Hello Sergei, Please review a patch for mdev-10702.diff
Thanks!
diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index dec0d12..fc18322 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -2542,3 +2542,32 @@ EXECUTE stmt3; EXECUTE stmt3; DEALLOCATE PREPARE stmt3; DROP TEMPORARY TABLES tm, t1; +# +# Start of 10.1 tests +# +# +# MDEV-10702 Crash in SET STATEMENT FOR EXECUTE +# +CREATE TABLE t1 (a INT); +PREPARE stmt FROM 'INSERT INTO t1 VALUES (@@max_sort_length)'; +SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt; +SELECT * FROM t1; +a +2048 +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=NEW.a + 1; +SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt; +SELECT * FROM t1; +a +2048 +1025 +DROP TRIGGER tr1; +SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt; +SELECT * FROM t1; +a +2048 +1025 +1024 +DROP TABLE t1; +# +# End of 10.1 tests +# diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index 21355ca..90226d3 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -2259,3 +2259,27 @@ EXECUTE stmt3; EXECUTE stmt3; DEALLOCATE PREPARE stmt3; DROP TEMPORARY TABLES tm, t1; + +--echo # +--echo # Start of 10.1 tests +--echo # + +--echo # +--echo # MDEV-10702 Crash in SET STATEMENT FOR EXECUTE +--echo # +CREATE TABLE t1 (a INT); +PREPARE stmt FROM 'INSERT INTO t1 VALUES (@@max_sort_length)'; +SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt; +SELECT * FROM t1; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=NEW.a + 1; +SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt; +SELECT * FROM t1; +DROP TRIGGER tr1; +SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt; +SELECT * FROM t1; +DROP TABLE t1; + + +--echo # +--echo # End of 10.1 tests +--echo # diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 0db1daa..c0d5460 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3030,7 +3030,30 @@ void mysql_sql_stmt_execute(THD *thd) DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt)); + /* + thd->free_list can already have some Items, + e.g. for a query like this: + SET STATEMENT max_sort_length=2048 FOR EXECUTE stmt; + thd->free_list contains a pointer to Item_int corresponding to 2048. + + If Prepared_statement::execute() notices that the table metadata for "t1" + has changed since PREPARE, it returns an error asking the calling + Prepared_statement::execute_loop() to re-prepare the statement. + Before returning the error, Prepared_statement::execute() + calls Prepared_statement::cleanup_stmt(), + which calls thd->cleanup_after_query(), + which calls Query_arena::free_items(). + + We hide Items created while parsing the "SET STATEMENT" part of the query, + so they don't get freed before re-prepare. + See MDEV-10702 Crash in SET STATEMENT FOR EXECUTE + */ + Item *free_list_backup= thd->free_list; + thd->free_list= NULL; (void) stmt->execute_loop(&expanded_query, FALSE, NULL, NULL); + thd->free_list= free_list_backup; + thd->free_items(); // Now it's OK to free the "SET STATEMENT" Items. + stmt->lex->restore_set_statement_var(); DBUG_VOID_RETURN; }
_______________________________________________ Mailing list: https://launchpad.net/~maria-developers Post to : maria-developers@lists.launchpad.net Unsubscribe : https://launchpad.net/~maria-developers More help : https://help.launchpad.net/ListHelp