Commit e886c2ba authored by Yuchen Pei's avatar Yuchen Pei

MDEV-34757 Check leaf_tables_saved in partition pruning in UPDATE and DELETE

parent 00cb3440
......@@ -119,6 +119,204 @@ CALL p1(2);
DROP TABLE t1;
DROP PROCEDURE p1;
#
# MDEV-34757: assertion of (mem_root->flags & 4) == 0 fails in 2nd ps execution with partition pruning
#
CREATE TABLE t1 (id INT, value INT);
CREATE TABLE t2 (id INT);
PREPARE stmt FROM 'EXPLAIN UPDATE t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)';
EXECUTE stmt;
INSERT INTO t1 VALUES (1,10),(2,10),(3,10);
INSERT INTO t2 VALUES (1),(2);
EXECUTE stmt;
SELECT * FROM t1;
id value
1 10
2 10
3 10
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (null,1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'UPDATE t1 t1 SET a = (SELECT 1 FROM t2 WHERE a = t1.a) where a = ?';
execute stmt using @var1;
select * from t1;
a
1
2
3
4
execute stmt using @var2;
select * from t1;
a
1
2
1
3
deallocate prepare stmt;
drop table t1, t2;
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (null,1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'EXPLAIN UPDATE t1 t1 SET a = (SELECT 1 FROM t2 WHERE a = t1.a) where a = ?';
execute stmt using @var1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No matching rows after partition pruning
select * from t1;
a
1
2
3
4
execute stmt using @var2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Using buffer
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
select * from t1;
a
1
2
3
4
deallocate prepare stmt;
drop table t1, t2;
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id) WHERE ?=?';
execute stmt using @var1, @var2;
execute stmt using @var1, @var1;
deallocate prepare stmt;
DROP TABLE t1,t2;
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'EXPLAIN UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id) WHERE ?=?';
execute stmt using @var1, @var2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
execute stmt using @var1, @var1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
deallocate prepare stmt;
DROP TABLE t1,t2;
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 (c1) VALUES (1), (2), (3);
CREATE PROCEDURE p1(p1 INT)
EXPLAIN DELETE FROM t1 LIMIT p1;
CALL p1(0);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
CALL p1(1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
CALL p1(2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
# Clean up
DROP TABLE t1;
DROP PROCEDURE p1;
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'DELETE FROM t1 where a = ?';
execute stmt using @var1;
select * from t1;
a
1
2
3
4
execute stmt using @var2;
select * from t1;
a
1
2
3
deallocate prepare stmt;
drop table t1, t2;
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'EXPLAIN DELETE FROM t1 where a = ?';
execute stmt using @var1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No matching rows after partition pruning
select * from t1;
a
1
2
3
4
execute stmt using @var2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
select * from t1;
a
1
2
3
4
deallocate prepare stmt;
drop table t1, t2;
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'DELETE FROM t1 WHERE ?=?';
execute stmt using @var1, @var2;
execute stmt using @var1, @var1;
deallocate prepare stmt;
DROP TABLE t1,t2;
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'EXPLAIN DELETE FROM t1 WHERE ?=?';
execute stmt using @var1, @var2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
execute stmt using @var1, @var1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL 3 Deleting all rows
deallocate prepare stmt;
DROP TABLE t1,t2;
#
# MDEV-33858: Assertion `(mem_root->flags & 4) == 0' fails on 2nd execution of PS with -DWITH_PROTECT_STATEMENT_MEMROOT=ON
#
CREATE TABLE t (a INT);
......
......@@ -5,6 +5,7 @@
# The cmake option -DWITH_PROTECT_STATEMENT_MEMROOT is used only
# for debug build
--source include/have_debug.inc
--source include/have_partition.inc
--echo #
--echo # MDEV-32369: Memory leak when executing PS for query with IN subquery
......@@ -142,6 +143,173 @@ CALL p1(2);
DROP TABLE t1;
DROP PROCEDURE p1;
--echo #
--echo # MDEV-34757: assertion of (mem_root->flags & 4) == 0 fails in 2nd ps execution with partition pruning
--echo #
# same as the first MDEV-34444 testcase but with explain
CREATE TABLE t1 (id INT, value INT);
CREATE TABLE t2 (id INT);
PREPARE stmt FROM 'EXPLAIN UPDATE t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)';
# we are testing 2nd ps assertion failure, not explain output, which
# may vary from version to version
--disable_result_log
EXECUTE stmt;
--enable_result_log
INSERT INTO t1 VALUES (1,10),(2,10),(3,10);
INSERT INTO t2 VALUES (1),(2);
--disable_result_log
EXECUTE stmt;
--enable_result_log
SELECT * FROM t1;
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
# 2nd ps mem leak; partition pruning
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (null,1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'UPDATE t1 t1 SET a = (SELECT 1 FROM t2 WHERE a = t1.a) where a = ?';
execute stmt using @var1;
select * from t1;
execute stmt using @var2;
select * from t1;
deallocate prepare stmt;
drop table t1, t2;
# same but with explain
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (null,1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'EXPLAIN UPDATE t1 t1 SET a = (SELECT 1 FROM t2 WHERE a = t1.a) where a = ?';
execute stmt using @var1;
select * from t1;
execute stmt using @var2;
select * from t1;
deallocate prepare stmt;
drop table t1, t2;
# top level impossible where
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id) WHERE ?=?';
execute stmt using @var1, @var2;
execute stmt using @var1, @var1;
deallocate prepare stmt;
DROP TABLE t1,t2;
# top level impossible where, with explain
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'EXPLAIN UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id) WHERE ?=?';
execute stmt using @var1, @var2;
execute stmt using @var1, @var1;
deallocate prepare stmt;
DROP TABLE t1,t2;
# Now we do delete instead of update
# same as the second MDEV-34447 testcase but with explain
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 (c1) VALUES (1), (2), (3);
CREATE PROCEDURE p1(p1 INT)
EXPLAIN DELETE FROM t1 LIMIT p1;
CALL p1(0);
CALL p1(1);
CALL p1(2);
--echo # Clean up
DROP TABLE t1;
DROP PROCEDURE p1;
# partition pruning
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'DELETE FROM t1 where a = ?';
execute stmt using @var1;
select * from t1;
execute stmt using @var2;
select * from t1;
deallocate prepare stmt;
drop table t1, t2;
# same but with explain
set @var1=5;
set @var2=4;
create table t1 (a int) partition by list(a) (
partition p0 values in (1,2),
partition p1 values in (3,4)
);
create table t2 (a int);
insert into t1 values (1),(2),(3),(4);
insert into t2 values (4);
PREPARE stmt FROM 'EXPLAIN DELETE FROM t1 where a = ?';
execute stmt using @var1;
select * from t1;
execute stmt using @var2;
select * from t1;
deallocate prepare stmt;
drop table t1, t2;
# top level impossible where
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'DELETE FROM t1 WHERE ?=?';
execute stmt using @var1, @var2;
execute stmt using @var1, @var1;
deallocate prepare stmt;
DROP TABLE t1,t2;
# top level impossible where, with explain
set @var1=1;
set @var2=2;
CREATE TABLE t1 ( id INT(10), value INT(10) );
CREATE TABLE t2 ( id INT(10) );
insert into t1 values (1,10),(2,10),(3,10);
insert into t2 values (1),(2);
PREPARE stmt FROM 'EXPLAIN DELETE FROM t1 WHERE ?=?';
execute stmt using @var1, @var2;
execute stmt using @var1, @var1;
deallocate prepare stmt;
DROP TABLE t1,t2;
--echo #
--echo # MDEV-33858: Assertion `(mem_root->flags & 4) == 0' fails on 2nd execution of PS with -DWITH_PROTECT_STATEMENT_MEMROOT=ON
--echo #
......
......@@ -500,6 +500,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (thd->lex->describe || thd->lex->analyze_stmt)
goto produce_explain_and_leave;
if (!thd->lex->current_select->leaf_tables_saved)
{
thd->lex->current_select->save_leaf_tables(thd);
thd->lex->current_select->leaf_tables_saved= true;
}
my_ok(thd, 0);
DBUG_RETURN(0);
}
......
......@@ -569,6 +569,12 @@ int mysql_update(THD *thd,
if (thd->is_error())
DBUG_RETURN(1);
if (!thd->lex->current_select->leaf_tables_saved)
{
thd->lex->current_select->save_leaf_tables(thd);
thd->lex->current_select->leaf_tables_saved= true;
}
my_ok(thd); // No matching records
DBUG_RETURN(0);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment