summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extra/mariabackup/backup_copy.cc2
-rw-r--r--extra/mariabackup/changed_page_bitmap.cc2
-rw-r--r--include/heap.h2
-rw-r--r--mysql-test/main/selectivity.result57
-rw-r--r--mysql-test/main/selectivity.test29
-rw-r--r--mysql-test/main/selectivity_innodb.result57
-rw-r--r--mysql-test/suite/innodb/r/ibuf_not_empty.result1
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty.test30
-rw-r--r--mysql-test/suite/innodb_fts/r/innodb_fts_misc.result21
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb_fts_misc.test24
-rw-r--r--mysql-test/suite/perfschema/r/misc.result16
-rw-r--r--mysql-test/suite/perfschema/t/misc.test48
-rw-r--r--sql/sql_select.cc3
-rw-r--r--sql/sql_table.cc8
-rw-r--r--storage/heap/_check.c27
-rw-r--r--storage/innobase/dict/dict0boot.cc23
-rw-r--r--storage/innobase/dict/dict0crea.cc4
-rw-r--r--storage/innobase/dict/dict0dict.cc34
-rw-r--r--storage/innobase/dict/dict0load.cc7
-rw-r--r--storage/innobase/handler/handler0alter.cc5
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc82
-rw-r--r--storage/innobase/include/dict0dict.h17
-rw-r--r--storage/innobase/row/row0mysql.cc8
-rw-r--r--support-files/CMakeLists.txt3
24 files changed, 400 insertions, 110 deletions
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index a31668a9642..161486fbe39 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -478,7 +478,7 @@ struct datafile_cur_t {
{
memset(rel_path, 0, sizeof rel_path);
if (filename) {
- strncpy(abs_path, filename, sizeof abs_path);
+ strncpy(abs_path, filename, sizeof abs_path - 1);
abs_path[(sizeof abs_path) - 1] = 0;
} else {
abs_path[0] = '\0';
diff --git a/extra/mariabackup/changed_page_bitmap.cc b/extra/mariabackup/changed_page_bitmap.cc
index fcfb33c500a..5266bed800d 100644
--- a/extra/mariabackup/changed_page_bitmap.cc
+++ b/extra/mariabackup/changed_page_bitmap.cc
@@ -390,7 +390,7 @@ log_online_setup_bitmap_file_range(
bitmap_files->files[array_pos].seq_num = file_seq_num;
strncpy(bitmap_files->files[array_pos].name,
- bitmap_dir_file_info.name, FN_REFLEN);
+ bitmap_dir_file_info.name, FN_REFLEN - 1);
bitmap_files->files[array_pos].name[FN_REFLEN - 1]
= '\0';
bitmap_files->files[array_pos].start_lsn
diff --git a/include/heap.h b/include/heap.h
index d0c907a48b4..ca6efa48f1b 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -246,7 +246,7 @@ int hp_panic(enum ha_panic_function flag);
int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key,
key_part_map keypart_map, enum ha_rkey_function find_flag);
extern uchar * heap_find(HP_INFO *info,int inx,const uchar *key);
-extern int heap_check_heap(HP_INFO *info, my_bool print_status);
+extern int heap_check_heap(const HP_INFO *info, my_bool print_status);
extern uchar *heap_position(HP_INFO *info);
/* The following is for programs that uses the old HEAP interface where
diff --git a/mysql-test/main/selectivity.result b/mysql-test/main/selectivity.result
index abab4936af0..25f58b3f023 100644
--- a/mysql-test/main/selectivity.result
+++ b/mysql-test/main/selectivity.result
@@ -1758,5 +1758,62 @@ a
1991
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1;
+#
+# MDEV-20424: New default value for optimizer_use_condition-selectivity
+# leads to bad plan
+#
+create table t1(a int, b int, c int, d int, key(a,b));
+insert into t1 select 50,seq-1,seq-1,seq from seq_1_to_10;
+insert into t1 select seq-1,seq-1,seq-1,seq from seq_1_to_100 limit 90;
+create table t2(a int, b int, c int, primary key(a));
+insert into t2 select seq-1,seq-1,seq-1 from seq_1_to_100;
+create table t3(a int, b int, c int, primary key(a));
+insert into t3 select seq-1,seq-1,seq-1 from seq_1_to_100 limit 30;
+set optimizer_use_condition_selectivity=1;
+explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range a a 10 NULL 9 100.00 Using index condition; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100
+select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+b a a b
+0 0 1 1
+1 1 2 2
+2 2 3 3
+3 3 4 4
+4 4 5 5
+5 5 6 6
+6 6 7 7
+7 7 8 8
+8 8 9 9
+9 9 10 10
+set optimizer_use_condition_selectivity=2;
+explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range a a 10 NULL 9 9.00 Using index condition; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100
+select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+b a a b
+0 0 1 1
+1 1 2 2
+2 2 3 3
+3 3 4 4
+4 4 5 5
+5 5 6 6
+6 6 7 7
+7 7 8 8
+8 8 9 9
+9 9 10 10
+set optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+drop table t1,t2,t3;
# End of 10.1 tests
set @@global.histogram_size=@save_histogram_size;
diff --git a/mysql-test/main/selectivity.test b/mysql-test/main/selectivity.test
index d3fafc2ae52..b145cd08d67 100644
--- a/mysql-test/main/selectivity.test
+++ b/mysql-test/main/selectivity.test
@@ -1211,6 +1211,35 @@ set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivit
DROP TABLE t1;
+--echo #
+--echo # MDEV-20424: New default value for optimizer_use_condition-selectivity
+--echo # leads to bad plan
+--echo #
+
+create table t1(a int, b int, c int, d int, key(a,b));
+insert into t1 select 50,seq-1,seq-1,seq from seq_1_to_10;
+insert into t1 select seq-1,seq-1,seq-1,seq from seq_1_to_100 limit 90;
+
+create table t2(a int, b int, c int, primary key(a));
+insert into t2 select seq-1,seq-1,seq-1 from seq_1_to_100;
+
+create table t3(a int, b int, c int, primary key(a));
+insert into t3 select seq-1,seq-1,seq-1 from seq_1_to_100 limit 30;
+
+let $query= select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+
+set optimizer_use_condition_selectivity=1;
+eval explain extended $query;
+eval $query;
+
+set optimizer_use_condition_selectivity=2;
+eval explain extended $query;
+eval $query;
+set optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+
+drop table t1,t2,t3;
+
--echo # End of 10.1 tests
#
diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result
index 5c740d71925..c091ce07ff8 100644
--- a/mysql-test/main/selectivity_innodb.result
+++ b/mysql-test/main/selectivity_innodb.result
@@ -1768,6 +1768,63 @@ a
1991
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1;
+#
+# MDEV-20424: New default value for optimizer_use_condition-selectivity
+# leads to bad plan
+#
+create table t1(a int, b int, c int, d int, key(a,b));
+insert into t1 select 50,seq-1,seq-1,seq from seq_1_to_10;
+insert into t1 select seq-1,seq-1,seq-1,seq from seq_1_to_100 limit 90;
+create table t2(a int, b int, c int, primary key(a));
+insert into t2 select seq-1,seq-1,seq-1 from seq_1_to_100;
+create table t3(a int, b int, c int, primary key(a));
+insert into t3 select seq-1,seq-1,seq-1 from seq_1_to_100 limit 30;
+set optimizer_use_condition_selectivity=1;
+explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range a a 10 NULL 11 100.00 Using index condition; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100
+select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+b a a b
+0 0 1 1
+1 1 2 2
+2 2 3 3
+3 3 4 4
+4 4 5 5
+5 5 6 6
+6 6 7 7
+7 7 8 8
+8 8 9 9
+9 9 10 10
+set optimizer_use_condition_selectivity=2;
+explain extended select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range a a 10 NULL 11 11.00 Using index condition; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.d 1 100.00
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t2`.`a` = `test`.`t1`.`c` and `test`.`t3`.`a` = `test`.`t1`.`d` and `test`.`t1`.`a` = 50 and `test`.`t1`.`b` <= 100
+select t1.b,t2.a,t3.a,t3.b from t1,t2,t3
+where t1.c = t2.a AND t1.d = t3.a and t1.a = 50 and t1.b <= 100;
+b a a b
+0 0 1 1
+1 1 2 2
+2 2 3 3
+3 3 4 4
+4 4 5 5
+5 5 6 6
+6 6 7 7
+7 7 8 8
+8 8 9 9
+9 9 10 10
+set optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+drop table t1,t2,t3;
# End of 10.1 tests
set @@global.histogram_size=@save_histogram_size;
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
diff --git a/mysql-test/suite/innodb/r/ibuf_not_empty.result b/mysql-test/suite/innodb/r/ibuf_not_empty.result
index 2c898b8916d..7c61e74850b 100644
--- a/mysql-test/suite/innodb/r/ibuf_not_empty.result
+++ b/mysql-test/suite/innodb/r/ibuf_not_empty.result
@@ -22,4 +22,5 @@ check table t1;
Table Op Msg_type Msg_text
test.t1 check Warning InnoDB: Index 'b' contains #### entries, should be 4096.
test.t1 check error Corrupt
+SET GLOBAL innodb_fast_shutdown=0;
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test
index 470d375c661..33118ad6bf5 100644
--- a/mysql-test/suite/innodb/t/ibuf_not_empty.test
+++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test
@@ -42,15 +42,43 @@ INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
+let MYSQLD_DATADIR=`select @@datadir`;
+let PAGE_SIZE=`select @@innodb_page_size`;
+
+--source include/shutdown_mysqld.inc
+
+# Corrupt the change buffer bitmap, to claim that pages are clean
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
+my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd";
+open(FILE, "+<$file") || die "Unable to open $file";
+binmode FILE;
+my $ps= $ENV{PAGE_SIZE};
+my $page;
+sysseek(FILE, $ps, 0) || die "Unable to seek $file\n";
+die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
+# Clean the change buffer bitmap.
+substr($page,38,$ps - 38 - 8) = chr(0) x ($ps - 38 - 8);
+my $polynomial = 0x82f63b78; # CRC-32C
+my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
+ mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
+substr($page,0,4)=$ck;
+substr($page,$ps-8,4)=$ck;
+sysseek(FILE, $ps, 0) || die "Unable to rewind $file\n";
+syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
+close(FILE) || die "Unable to close $file";
+EOF
--let $restart_parameters= --innodb-force-recovery=6 --innodb-change-buffer-dump
---source include/restart_mysqld.inc
+--source include/start_mysqld.inc
--replace_regex /contains \d+ entries/contains #### entries/
check table t1;
--let $restart_parameters=
--source include/restart_mysqld.inc
+SET GLOBAL innodb_fast_shutdown=0;
+--source include/restart_mysqld.inc
# Cleanup
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result
index 0ebdf46c9fe..69a75bb53fb 100644
--- a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result
+++ b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result
@@ -1,4 +1,3 @@
-drop table if exists t1;
CREATE TABLE t1 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
a VARCHAR(200),
@@ -409,7 +408,6 @@ AGAINST ('"following database"@10' IN BOOLEAN MODE);
id
105
DROP TABLE t1;
-drop table if exists t50;
set names utf8;
"----------Test1---------"
create table t50 (s1 varchar(60) character set utf8 collate utf8_bin) engine = innodb;
@@ -648,9 +646,6 @@ s1
ŁŁŁŁ
LLLL
ŁŁŁŁ ŁŁŁŁ
-DROP TABLE if EXISTS t2;
-Warnings:
-Note 1051 Unknown table 'test.t2'
CREATE TABLE t2 (s1 VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_POLISH_CI) ENGINE = InnoDB;
CREATE FULLTEXT INDEX i ON t2 ( s1);
INSERT INTO t2 VALUES
@@ -705,7 +700,12 @@ ALTER TABLE t2 DROP a;
SET @@autocommit=0;
CREATE FULLTEXT INDEX i ON t1 (char_column);
INSERT INTO t1 values (1,'aaa');
-"restart server..."
+CREATE TABLE mdev20987_1(f1 INT NOT NULL, PRIMARY KEY(f1))ENGINE=InnoDB;
+CREATE TABLE mdev20987_2(f1 INT NOT NULL, f2 CHAR(100),
+FULLTEXT(f2),
+FOREIGN KEY(f1) REFERENCES mdev20987_1(f1))ENGINE=InnoDB;
+INSERT INTO mdev20987_1 VALUES(1);
+INSERT INTO mdev20987_2 VALUES(1, 'mariadb');
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
@@ -713,12 +713,8 @@ t2 CREATE TABLE `t2` (
PRIMARY KEY (`FTS_DOC_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb');
-SET @@autocommit=1;
-DROP TABLE t1, t2;
+DROP TABLE t1, t2, mdev20987_2, mdev20987_1;
"----------Test28---------"
-drop table if exists `fts_test`;
-Warnings:
-Note 1051 Unknown table 'test.fts_test'
create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb;
set session autocommit=0;
insert into `fts_test` values ('');
@@ -908,9 +904,6 @@ id title body
2 How To Use MySQL Well After you went through a ...
3 Optimizing MySQL In this tutorial we will show ...
DROP TABLE articles;
-drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 'test.t1'
create table t1 (FTS_DOC_ID bigint unsigned auto_increment not null primary key,
title varchar(200),body text,fulltext(title,body)) engine=innodb;
insert into t1 set body='test';
diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test
index 9de76a3bbce..6628ddce51b 100644
--- a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test
+++ b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test
@@ -7,10 +7,6 @@
let collation=UTF8_UNICODE_CI;
--source include/have_collation.inc
---disable_warnings
-drop table if exists t1;
---enable_warnings
-
# Create FTS table
CREATE TABLE t1 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
@@ -403,10 +399,6 @@ DROP TABLE t1;
#------------------------------------------------------------------------------
# More FTS test from peter's testing
#------------------------------------------------------------------------------
---disable_warnings
-drop table if exists t50;
---enable_warnings
-
set names utf8;
@@ -608,7 +600,6 @@ CREATE FULLTEXT INDEX i ON t1 (s1);
INSERT INTO t1 VALUES
('a'),('b'),('c'),('d'),('ŁŁŁŁ'),('LLLL'),(NULL),('ŁŁŁŁ ŁŁŁŁ'),('LLLLLLLL');
SELECT * FROM t1 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI);
-DROP TABLE if EXISTS t2;
CREATE TABLE t2 (s1 VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_POLISH_CI) ENGINE = InnoDB;
CREATE FULLTEXT INDEX i ON t2 ( s1);
INSERT INTO t2 VALUES
@@ -675,16 +666,19 @@ ALTER TABLE t2 DROP a;
SET @@autocommit=0;
CREATE FULLTEXT INDEX i ON t1 (char_column);
INSERT INTO t1 values (1,'aaa');
-echo "restart server...";
-# Restart the server
+
+CREATE TABLE mdev20987_1(f1 INT NOT NULL, PRIMARY KEY(f1))ENGINE=InnoDB;
+CREATE TABLE mdev20987_2(f1 INT NOT NULL, f2 CHAR(100),
+ FULLTEXT(f2),
+ FOREIGN KEY(f1) REFERENCES mdev20987_1(f1))ENGINE=InnoDB;
+INSERT INTO mdev20987_1 VALUES(1);
+INSERT INTO mdev20987_2 VALUES(1, 'mariadb');
--source include/restart_mysqld.inc
SHOW CREATE TABLE t2;
DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb');
-SET @@autocommit=1;
-DROP TABLE t1, t2;
+DROP TABLE t1, t2, mdev20987_2, mdev20987_1;
--echo "----------Test28---------"
-drop table if exists `fts_test`;
create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb;
set session autocommit=0;
insert into `fts_test` values ('');
@@ -873,8 +867,6 @@ DROP TABLE articles;
# Test for Bug 13940669 - 64901: INNODB: ASSERTION FAILURE IN
# THREAD 34387022112 IN FILE REM0CMP.CC LINE 5
-drop table if exists t1;
-
create table t1 (FTS_DOC_ID bigint unsigned auto_increment not null primary key,
title varchar(200),body text,fulltext(title,body)) engine=innodb;
diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result
index 4c8fdca8e68..2e4d21d625a 100644
--- a/mysql-test/suite/perfschema/r/misc.result
+++ b/mysql-test/suite/perfschema/r/misc.result
@@ -134,3 +134,19 @@ truncate performance_schema.events_statements_history 0
select * from t1 3
insert into t1 select RAND()*10000 from t1 6
drop table t1;
+#
+# MDEV-17896 Assertion `pfs->get_refcount() > 0' failed
+# in release_table_share
+#
+SELECT COUNT(*)<@@performance_schema_max_table_instances FROM
+performance_schema.objects_summary_global_by_type WHERE OBJECT_TYPE='TABLE';
+COUNT(*)<@@performance_schema_max_table_instances
+1
+CREATE TABLE t0(a INT);
+SELECT * FROM t0;
+a
+DROP TEMPORARY TABLE IF EXISTS t0;
+Warnings:
+Note 1051 Unknown table 'test.t0'
+FLUSH TABLE t0;
+DROP TABLE t0;
diff --git a/mysql-test/suite/perfschema/t/misc.test b/mysql-test/suite/perfschema/t/misc.test
index c9f7dc6bfc0..80ce64f0302 100644
--- a/mysql-test/suite/perfschema/t/misc.test
+++ b/mysql-test/suite/perfschema/t/misc.test
@@ -222,3 +222,51 @@ insert into t1 select RAND()*10000 from t1;
select sql_text, rows_examined from performance_schema.events_statements_history;
drop table t1;
+--echo #
+--echo # MDEV-17896 Assertion `pfs->get_refcount() > 0' failed
+--echo # in release_table_share
+--echo #
+
+# There must be at least one available slot in PFS table_share_array for
+# this test to be meaningful. If there are no free slots we must
+# restart mysqld, it is the only way to reset PFS table_share_array
+let $query= SELECT COUNT(*)<@@performance_schema_max_table_instances FROM
+ performance_schema.objects_summary_global_by_type WHERE OBJECT_TYPE='TABLE';
+
+let $free_slots_available= `$query`;
+
+if (!$free_slots_available)
+{
+ source include/restart_mysqld.inc;
+}
+eval $query;
+
+CREATE TABLE t0(a INT);
+
+# TABLE_SHARE must be cached in the table definition cache.
+SELECT * FROM t0;
+
+# Dropping t0 using DROP TEMPORARY frees up a slot in table_share_array,
+# but the persistent table is not correctly dropped, i.e. TABLE_SHARE::m_psi
+# still points to that slot in table_share_array.
+DROP TEMPORARY TABLE IF EXISTS t0;
+
+# Try re-using each and every slot in PFS table_share_array. If bug is
+# there, we re-use t0 slot.
+# The newly created table that re-uses the t0 slot ends up
+# resetting the PFS_table_share refcount.
+let $i= `SELECT @@performance_schema_max_table_instances`;
+disable_query_log;
+while ($i)
+{
+ # Memory engine is here to reduce disk IO
+ eval CREATE TABLE t$i(a INT) ENGINE=MEMORY;
+ eval DROP TABLE t$i;
+ dec $i;
+}
+enable_query_log;
+
+# FLUSH TABLE crashes the server when PFS_table_share is found with
+# an unexpected refcount.
+FLUSH TABLE t0;
+DROP TABLE t0;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index a68eaf00424..fcd4b4336c1 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9243,7 +9243,10 @@ prev_record_reads(const POSITION *positions, uint idx, table_map found_ref)
#max_nested_outer_joins=64-1) will not make it any more precise.
*/
if (pos->records_read)
+ {
found= COST_MULT(found, pos->records_read);
+ found*= pos->cond_selectivity;
+ }
}
}
return found;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index bb22e9a9f34..170c02c0f7f 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2435,6 +2435,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
err, ER_THD(thd, err),
tbl_name.c_ptr_safe());
+
+ /*
+ Our job is done here. This statement was added to avoid executing
+ unnecessary code farther below which in some strange corner cases
+ caused the server to crash (see MDEV-17896).
+ */
+ goto log_query;
}
else
{
@@ -2550,6 +2557,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
mysql_audit_drop_table(thd, table);
}
+log_query:
if (!dont_log_query && !drop_temporary)
{
non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted);
diff --git a/storage/heap/_check.c b/storage/heap/_check.c
index 883e67046e7..1a640fa13da 100644
--- a/storage/heap/_check.c
+++ b/storage/heap/_check.c
@@ -18,10 +18,8 @@
#include "heapdef.h"
-static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
- ulong blength, my_bool print_status);
-static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
- my_bool print_status);
+static int check_one_key(HP_KEYDEF *, uint, ulong, ulong, my_bool);
+static int check_one_rb_key(const HP_INFO *, uint, ulong, my_bool);
/*
@@ -40,13 +38,13 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
1 error
*/
-int heap_check_heap(HP_INFO *info, my_bool print_status)
+int heap_check_heap(const HP_INFO *info, my_bool print_status)
{
int error;
uint key;
ulong records=0, deleted=0, pos, next_block;
HP_SHARE *share=info->s;
- HP_INFO save_info= *info; /* Needed because scan_init */
+ uchar *current_ptr= info->current_ptr;
DBUG_ENTER("heap_check_heap");
for (error=key= 0 ; key < share->keys ; key++)
@@ -65,7 +63,7 @@ int heap_check_heap(HP_INFO *info, my_bool print_status)
{
if (pos < next_block)
{
- info->current_ptr+= share->block.recbuffer;
+ current_ptr+= share->block.recbuffer;
}
else
{
@@ -77,9 +75,9 @@ int heap_check_heap(HP_INFO *info, my_bool print_status)
break; /* End of file */
}
}
- hp_find_record(info,pos);
+ current_ptr= hp_find_block(&share->block, pos);
- if (!info->current_ptr[share->visible])
+ if (!current_ptr[share->visible])
deleted++;
else
records++;
@@ -92,7 +90,6 @@ int heap_check_heap(HP_INFO *info, my_bool print_status)
deleted, (ulong) share->deleted));
error= 1;
}
- *info= save_info;
DBUG_RETURN(error);
}
@@ -165,7 +162,7 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
return error;
}
-static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
+static int check_one_rb_key(const HP_INFO *info, uint keynr, ulong records,
my_bool print_status)
{
HP_KEYDEF *keydef= info->s->keydef + keynr;
@@ -174,9 +171,11 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
uchar *key, *recpos;
uint key_length;
uint not_used[2];
+ TREE_ELEMENT **last_pos;
+ TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1];
- if ((key= tree_search_edge(&keydef->rb_tree, info->parents,
- &info->last_pos, offsetof(TREE_ELEMENT, left))))
+ if ((key= tree_search_edge(&keydef->rb_tree, parents,
+ &last_pos, offsetof(TREE_ELEMENT, left))))
{
do
{
@@ -191,7 +190,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
}
else
found++;
- key= tree_search_next(&keydef->rb_tree, &info->last_pos,
+ key= tree_search_next(&keydef->rb_tree, &last_pos,
offsetof(TREE_ELEMENT, left),
offsetof(TREE_ELEMENT, right));
} while (key);
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index 2104aff83cd..f62bed52990 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -127,8 +127,7 @@ dict_hdr_get_new_id(
}
if (space_id) {
- *space_id = mtr_read_ulint(dict_hdr + DICT_HDR_MAX_SPACE_ID,
- MLOG_4BYTES, &mtr);
+ *space_id = mach_read_from_4(dict_hdr + DICT_HDR_MAX_SPACE_ID);
if (fil_assign_new_space_id(space_id)) {
mlog_write_ulint(dict_hdr + DICT_HDR_MAX_SPACE_ID,
*space_id, MLOG_4BYTES, &mtr);
@@ -361,9 +360,9 @@ dict_boot(void)
dict_mem_index_add_field(index, "NAME", 0);
index->id = DICT_TABLES_ID;
- index = dict_index_add_to_cache(
+ dberr_t error = dict_index_add_to_cache(
index, mach_read_from_4(dict_hdr + DICT_HDR_TABLES));
- ut_a(index);
+ ut_a(error == DB_SUCCESS);
ut_ad(!table->is_instant());
table->indexes.start->n_core_null_bytes = UT_BITS_IN_BYTES(
unsigned(table->indexes.start->n_nullable));
@@ -373,9 +372,9 @@ dict_boot(void)
dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_TABLE_IDS_ID;
- index = dict_index_add_to_cache(
+ error = dict_index_add_to_cache(
index, mach_read_from_4(dict_hdr + DICT_HDR_TABLE_IDS));
- ut_a(index);
+ ut_a(error == DB_SUCCESS);
/*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS", fil_system.sys_space,
@@ -403,9 +402,9 @@ dict_boot(void)
dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_COLUMNS_ID;
- index = dict_index_add_to_cache(
+ error = dict_index_add_to_cache(
index, mach_read_from_4(dict_hdr + DICT_HDR_COLUMNS));
- ut_a(index);
+ ut_a(error == DB_SUCCESS);
ut_ad(!table->is_instant());
table->indexes.start->n_core_null_bytes = UT_BITS_IN_BYTES(
unsigned(table->indexes.start->n_nullable));
@@ -446,9 +445,9 @@ dict_boot(void)
dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_INDEXES_ID;
- index = dict_index_add_to_cache(
+ error = dict_index_add_to_cache(
index, mach_read_from_4(dict_hdr + DICT_HDR_INDEXES));
- ut_a(index);
+ ut_a(error == DB_SUCCESS);
ut_ad(!table->is_instant());
table->indexes.start->n_core_null_bytes = UT_BITS_IN_BYTES(
unsigned(table->indexes.start->n_nullable));
@@ -475,9 +474,9 @@ dict_boot(void)
dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_FIELDS_ID;
- index = dict_index_add_to_cache(
+ error = dict_index_add_to_cache(
index, mach_read_from_4(dict_hdr + DICT_HDR_FIELDS));
- ut_a(index);
+ ut_a(error == DB_SUCCESS);
ut_ad(!table->is_instant());
table->indexes.start->n_core_null_bytes = UT_BITS_IN_BYTES(
unsigned(table->indexes.start->n_nullable));
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index b5f7a389f4d..d424446ba87 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -1350,9 +1350,9 @@ dict_create_index_step(
if (node->state == INDEX_ADD_TO_CACHE) {
ut_ad(node->index->table == node->table);
- node->index = dict_index_add_to_cache(
+ err = dict_index_add_to_cache(
node->index, FIL_NULL, trx_is_strict(trx),
- &err, node->add_v);
+ node->add_v);
ut_ad((node->index == NULL) == (err != DB_SUCCESS));
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index c84356f40c8..17d2c6c68eb 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1765,8 +1765,7 @@ dict_table_rename_in_cache(
/* The old table name in my_charset_filename is stored
in old_name_cs_filename */
- strncpy(old_name_cs_filename, old_name,
- MAX_FULL_NAME_LEN);
+ strcpy(old_name_cs_filename, old_name);
old_name_cs_filename[MAX_FULL_NAME_LEN] = '\0';
if (strstr(old_name, TEMP_TABLE_PATH_PREFIX) == NULL) {
@@ -1788,8 +1787,7 @@ dict_table_rename_in_cache(
} else {
/* Old name already in
my_charset_filename */
- strncpy(old_name_cs_filename, old_name,
- MAX_FULL_NAME_LEN);
+ strcpy(old_name_cs_filename, old_name);
old_name_cs_filename[MAX_FULL_NAME_LEN]
= '\0';
}
@@ -2291,23 +2289,19 @@ void dict_index_remove_from_v_col_list(dict_index_t* index)
/** Adds an index to the dictionary cache, with possible indexing newly
added column.
-@param[in] index index; NOTE! The index memory
+@param[in,out] index index; NOTE! The index memory
object is freed in this function!
@param[in] page_no root page number of the index
-@param[in] strict TRUE=refuse to create the index
+@param[in] strict true=refuse to create the index
if records could be too big to fit in
an B-tree page
-@param[out] err DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION
-@param[in] add_v new virtual column that being added along with
- an add index call
-@return the added index
-@retval NULL on error */
-dict_index_t*
+@param[in] add_v virtual columns being added along with ADD INDEX
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
+dberr_t
dict_index_add_to_cache(
- dict_index_t* index,
+ dict_index_t*& index,
ulint page_no,
bool strict,
- dberr_t* err,
const dict_add_v_col_t* add_v)
{
dict_index_t* new_index;
@@ -2328,8 +2322,8 @@ dict_index_add_to_cache(
if (!dict_index_find_cols(index, add_v)) {
dict_mem_index_free(index);
- if (err) *err = DB_CORRUPTION;
- return NULL;
+ index = NULL;
+ return DB_CORRUPTION;
}
/* Build the cache internal representation of the index,
@@ -2361,8 +2355,8 @@ dict_index_add_to_cache(
if (strict) {
dict_mem_index_free(new_index);
dict_mem_index_free(index);
- if (err) *err = DB_TOO_BIG_RECORD;
- return NULL;
+ index = NULL;
+ return DB_TOO_BIG_RECORD;
} else if (current_thd != NULL) {
/* Avoid the warning to be printed
during recovery. */
@@ -2440,8 +2434,8 @@ dict_index_add_to_cache(
new_index->n_core_fields = new_index->n_fields;
dict_mem_index_free(index);
- if (err) *err = DB_SUCCESS;
- return new_index;
+ index = new_index;
+ return DB_SUCCESS;
}
/**********************************************************************//**
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 71cdee691b8..c8ba71e0c06 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -2574,8 +2574,9 @@ corrupted:
and simply did not load this index definition, the
.frm file would disagree with the index definitions
inside InnoDB. */
- if (!dict_index_add_to_cache(
- index, index->page, false, &error)) {
+ if ((error = dict_index_add_to_cache(index,
+ index->page))
+ != DB_SUCCESS) {
goto func_exit;
}
}
@@ -3089,7 +3090,7 @@ func_exit:
fts_free(table);
} else if (fts_optimize_wq) {
fts_optimize_add_table(table);
- } else {
+ } else if (table->can_be_evicted) {
/* fts_optimize_thread is not started yet.
So make the table as non-evictable from cache. */
dict_table_move_from_lru_to_non_lru(table);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 7b7afa6d1df..567285b0a68 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -5299,9 +5299,8 @@ new_clustered_failed:
for (uint a = 0; a < ctx->num_to_add_index; a++) {
ctx->add_index[a]->table = ctx->new_table;
- ctx->add_index[a] = dict_index_add_to_cache(
- ctx->add_index[a], FIL_NULL, false,
- &error, add_v);
+ error = dict_index_add_to_cache(
+ ctx->add_index[a], FIL_NULL, false, add_v);
ut_a(error == DB_SUCCESS);
}
DBUG_ASSERT(ha_alter_info->key_count
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 41ad08be63f..92d0aadca18 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -4313,6 +4313,71 @@ func_exit:
return(TRUE);
}
+/**
+Delete any buffered entries for a page.
+This prevents an infinite loop on slow shutdown
+in the case where the change buffer bitmap claims that no buffered
+changes exist, while entries exist in the change buffer tree.
+@param page_id page number for which there should be no unbuffered changes */
+ATTRIBUTE_COLD static void ibuf_delete_recs(const page_id_t page_id)
+{
+ ulint dops[IBUF_OP_COUNT];
+ mtr_t mtr;
+ btr_pcur_t pcur;
+ mem_heap_t* heap = mem_heap_create(512);
+ const dtuple_t* tuple = ibuf_search_tuple_build(
+ page_id.space(), page_id.page_no(), heap);
+ memset(dops, 0, sizeof(dops));
+
+loop:
+ ibuf_mtr_start(&mtr);
+ btr_pcur_open(ibuf->index, tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF,
+ &pcur, &mtr);
+
+ if (!btr_pcur_is_on_user_rec(&pcur)) {
+ ut_ad(btr_pcur_is_after_last_in_tree(&pcur));
+ goto func_exit;
+ }
+
+ for (;;) {
+ ut_ad(btr_pcur_is_on_user_rec(&pcur));
+
+ const rec_t* ibuf_rec = btr_pcur_get_rec(&pcur);
+
+ if (ibuf_rec_get_space(&mtr, ibuf_rec)
+ != page_id.space()
+ || ibuf_rec_get_page_no(&mtr, ibuf_rec)
+ != page_id.page_no()) {
+ break;
+ }
+
+ dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++;
+
+ /* Delete the record from ibuf */
+ if (ibuf_delete_rec(page_id.space(), page_id.page_no(),
+ &pcur, tuple, &mtr)) {
+ /* Deletion was pessimistic and mtr was committed:
+ we start from the beginning again */
+ ut_ad(mtr.has_committed());
+ goto loop;
+ }
+
+ if (btr_pcur_is_after_last_on_page(&pcur)) {
+ ibuf_mtr_commit(&mtr);
+ btr_pcur_close(&pcur);
+ goto loop;
+ }
+ }
+
+func_exit:
+ ibuf_mtr_commit(&mtr);
+ btr_pcur_close(&pcur);
+
+ ibuf_add_ops(ibuf->n_discarded_ops, dops);
+
+ mem_heap_free(heap);
+}
+
/** When an index page is read from a disk to the buffer pool, this function
applies any buffered operations to the page and deletes the entries from the
insert buffer. If the page is not read, but created in the buffer pool, this
@@ -4332,9 +4397,7 @@ ibuf_merge_or_delete_for_page(
const page_size_t* page_size,
ibool update_ibuf_bitmap)
{
- mem_heap_t* heap;
btr_pcur_t pcur;
- dtuple_t* search_tuple;
#ifdef UNIV_IBUF_DEBUG
ulint volume = 0;
#endif /* UNIV_IBUF_DEBUG */
@@ -4407,9 +4470,16 @@ ibuf_merge_or_delete_for_page(
ibuf_mtr_commit(&mtr);
if (!bitmap_bits) {
- /* No inserts buffered for this page */
-
+ /* No changes are buffered for this page. */
space->release();
+ if (UNIV_UNLIKELY(srv_shutdown_state)
+ && !srv_fast_shutdown) {
+ /* Prevent an infinite loop on slow
+ shutdown, in case the bitmap bits are
+ wrongly clear even though buffered
+ changes exist. */
+ ibuf_delete_recs(page_id);
+ }
return;
}
}
@@ -4422,9 +4492,9 @@ ibuf_merge_or_delete_for_page(
space = NULL;
}
- heap = mem_heap_create(512);
+ mem_heap_t* heap = mem_heap_create(512);
- search_tuple = ibuf_search_tuple_build(
+ const dtuple_t* search_tuple = ibuf_search_tuple_build(
page_id.space(), page_id.page_no(), heap);
if (block != NULL) {
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 8d12cccec32..a015c176a78 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1067,26 +1067,21 @@ void dict_index_remove_from_v_col_list(dict_index_t* index);
/** Adds an index to the dictionary cache, with possible indexing newly
added column.
-@param[in] index index; NOTE! The index memory
+@param[in,out] index index; NOTE! The index memory
object is freed in this function!
@param[in] page_no root page number of the index
@param[in] strict true=refuse to create the index
if records could be too big to fit in
an B-tree page
-@param[out] err DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION
-@param[in] add_v new virtual column that being added along with
- an add index call
-@return the added index
-@retval NULL on error */
-dict_index_t*
+@param[in] add_v virtual columns being added along with ADD INDEX
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
+dberr_t
dict_index_add_to_cache(
- dict_index_t* index,
+ dict_index_t*& index,
ulint page_no,
bool strict = false,
- dberr_t* err = NULL,
const dict_add_v_col_t* add_v = NULL)
- MY_ATTRIBUTE((nonnull(1)));
-
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system.
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index af1dcfdb0c1..7bf2655c196 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2580,10 +2580,10 @@ row_create_index_for_mysql(
} else {
dict_build_index_def(table, index, trx);
- /* add index to dictionary cache and also free index object. */
- index = dict_index_add_to_cache(
- index, FIL_NULL, trx_is_strict(trx), &err);
- if (index) {
+ err = dict_index_add_to_cache(
+ index, FIL_NULL, trx_is_strict(trx));
+ ut_ad((index == NULL) == (err != DB_SUCCESS));
+ if (UNIV_LIKELY(err == DB_SUCCESS)) {
ut_ad(!index->is_instant());
index->n_core_null_bytes = UT_BITS_IN_BYTES(
unsigned(index->n_nullable));
diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index 749964284c4..9be3ed65095 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -68,11 +68,12 @@ IF(UNIX)
IF(CHECKMODULE AND SEMODULE_PACKAGE)
FOREACH(pol mariadb)
SET(src ${CMAKE_CURRENT_SOURCE_DIR}/policy/selinux/${pol}.te)
- SET(tmp ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${pol}-pp.dir/${pol}.mod)
+ SET(tmp ${CMAKE_CURRENT_BINARY_DIR}/${pol}.mod)
SET(out ${CMAKE_CURRENT_BINARY_DIR}/${pol}.pp)
ADD_CUSTOM_COMMAND(OUTPUT ${out}
COMMAND ${CHECKMODULE} -M -m ${src} -o ${tmp}
COMMAND ${SEMODULE_PACKAGE} -m ${tmp} -o ${out}
+ COMMAND ${CMAKE_COMMAND} -E remove ${tmp}
DEPENDS ${src})
ADD_CUSTOM_TARGET(${pol}-pp ALL DEPENDS ${out})
INSTALL(FILES ${out} DESTINATION ${inst_location}/policy/selinux COMPONENT SupportFiles)