Commit 561e22ed authored by Yuchen Pei's avatar Yuchen Pei

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

parent 10b88590
...@@ -147,7 +147,210 @@ CALL p1(2); ...@@ -147,7 +147,210 @@ CALL p1(2);
# Clean up # Clean up
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
# End of 10.11 tests #
# 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;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
INSERT INTO t1 VALUES (1,10),(2,10),(3,10);
INSERT INTO t2 VALUES (1),(2);
EXECUTE stmt;
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
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;
# End of 11.1 tests
# #
# MDEV-34517: Memory leak on re-compilation of a failing statement inside a stored routine # MDEV-34517: Memory leak on re-compilation of a failing statement inside a stored routine
# #
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
# The cmake option -DWITH_PROTECT_STATEMENT_MEMROOT is used only # The cmake option -DWITH_PROTECT_STATEMENT_MEMROOT is used only
# for debug build # for debug build
--source include/have_debug.inc --source include/have_debug.inc
--source include/have_partition.inc
--echo # --echo #
--echo # MDEV-32369: Memory leak when executing PS for query with IN subquery --echo # MDEV-32369: Memory leak when executing PS for query with IN subquery
...@@ -166,7 +167,168 @@ CALL p1(2); ...@@ -166,7 +167,168 @@ CALL p1(2);
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
--echo # End of 10.11 tests --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)';
EXECUTE stmt;
INSERT INTO t1 VALUES (1,10),(2,10),(3,10);
INSERT INTO t2 VALUES (1),(2);
EXECUTE stmt;
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 # End of 11.1 tests
--echo # --echo #
--echo # MDEV-34517: Memory leak on re-compilation of a failing statement inside a stored routine --echo # MDEV-34517: Memory leak on re-compilation of a failing statement inside a stored routine
......
...@@ -500,6 +500,12 @@ bool Sql_cmd_delete::delete_from_single_table(THD *thd) ...@@ -500,6 +500,12 @@ bool Sql_cmd_delete::delete_from_single_table(THD *thd)
if (thd->binlog_for_noop_dml(transactional_table)) if (thd->binlog_for_noop_dml(transactional_table))
DBUG_RETURN(1); 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, 0); my_ok(thd, 0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -469,6 +469,12 @@ bool Sql_cmd_update::update_single_table(THD *thd) ...@@ -469,6 +469,12 @@ bool Sql_cmd_update::update_single_table(THD *thd)
if (thd->binlog_for_noop_dml(transactional_table)) if (thd->binlog_for_noop_dml(transactional_table))
DBUG_RETURN(1); 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 my_ok(thd); // No matching records
DBUG_RETURN(0); 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