MDEV-15492: Subquery crash similar to MDEV-10050
Detection of first execution of PS fixed. More debug info.
This commit is contained in:
parent
2dd4e50d5f
commit
f3994b7432
23
mysql-test/r/ps_qc_innodb.result
Normal file
23
mysql-test/r/ps_qc_innodb.result
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# MDEV-15492: Subquery crash similar to MDEV-10050
|
||||||
|
#
|
||||||
|
SET @qcs.save= @@global.query_cache_size, @qct.save= @@global.query_cache_type;
|
||||||
|
SET GLOBAL query_cache_size= 512*1024*1024, query_cache_type= ON;
|
||||||
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
|
||||||
|
CREATE VIEW v AS select a from t1 join t2;
|
||||||
|
PREPARE stmt1 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
PREPARE stmt2 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
EXECUTE stmt2;
|
||||||
|
a
|
||||||
|
EXECUTE stmt1;
|
||||||
|
a
|
||||||
|
INSERT INTO t2 VALUES (0);
|
||||||
|
EXECUTE stmt1;
|
||||||
|
a
|
||||||
|
START TRANSACTION;
|
||||||
|
EXECUTE stmt1;
|
||||||
|
a
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET GLOBAL query_cache_size= @qcs.save, query_cache_type= @qct.save;
|
35
mysql-test/t/ps_qc_innodb.test
Normal file
35
mysql-test/t/ps_qc_innodb.test
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
--source include/have_query_cache.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15492: Subquery crash similar to MDEV-10050
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET @qcs.save= @@global.query_cache_size, @qct.save= @@global.query_cache_type;
|
||||||
|
SET GLOBAL query_cache_size= 512*1024*1024, query_cache_type= ON;
|
||||||
|
|
||||||
|
--connect (con1,localhost,root,,test)
|
||||||
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
|
||||||
|
CREATE VIEW v AS select a from t1 join t2;
|
||||||
|
|
||||||
|
PREPARE stmt1 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
|
||||||
|
--connect (con2,localhost,root,,test)
|
||||||
|
PREPARE stmt2 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)";
|
||||||
|
EXECUTE stmt2;
|
||||||
|
|
||||||
|
--connection con1
|
||||||
|
EXECUTE stmt1;
|
||||||
|
INSERT INTO t2 VALUES (0);
|
||||||
|
EXECUTE stmt1;
|
||||||
|
START TRANSACTION;
|
||||||
|
EXECUTE stmt1;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
--disconnect con1
|
||||||
|
--disconnect con2
|
||||||
|
--connection default
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET GLOBAL query_cache_size= @qcs.save, query_cache_type= @qct.save;
|
@ -2252,15 +2252,19 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
|
|||||||
|
|
||||||
void THD::rollback_item_tree_changes()
|
void THD::rollback_item_tree_changes()
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("THD::rollback_item_tree_changes");
|
||||||
I_List_iterator<Item_change_record> it(change_list);
|
I_List_iterator<Item_change_record> it(change_list);
|
||||||
Item_change_record *change;
|
Item_change_record *change;
|
||||||
|
|
||||||
while ((change= it++))
|
while ((change= it++))
|
||||||
{
|
{
|
||||||
|
DBUG_PRINT("info", ("Rollback: %p (%p) <- %p",
|
||||||
|
*change->place, change->place, change->old_value));
|
||||||
*change->place= change->old_value;
|
*change->place= change->old_value;
|
||||||
}
|
}
|
||||||
/* We can forget about changes memory: it's allocated in runtime memroot */
|
/* We can forget about changes memory: it's allocated in runtime memroot */
|
||||||
change_list.empty();
|
change_list.empty();
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3819,6 +3819,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||||||
Statement stmt_backup;
|
Statement stmt_backup;
|
||||||
Query_arena *old_stmt_arena;
|
Query_arena *old_stmt_arena;
|
||||||
bool error= TRUE;
|
bool error= TRUE;
|
||||||
|
bool qc_executed= FALSE;
|
||||||
|
|
||||||
char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
|
char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
|
||||||
LEX_STRING saved_cur_db_name=
|
LEX_STRING saved_cur_db_name=
|
||||||
@ -3937,6 +3938,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||||||
thd->lex->sql_command= SQLCOM_SELECT;
|
thd->lex->sql_command= SQLCOM_SELECT;
|
||||||
status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
|
status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]);
|
||||||
thd->update_stats();
|
thd->update_stats();
|
||||||
|
qc_executed= TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3960,7 +3962,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||||||
thd->set_statement(&stmt_backup);
|
thd->set_statement(&stmt_backup);
|
||||||
thd->stmt_arena= old_stmt_arena;
|
thd->stmt_arena= old_stmt_arena;
|
||||||
|
|
||||||
if (state == Query_arena::STMT_PREPARED)
|
if (state == Query_arena::STMT_PREPARED && !qc_executed)
|
||||||
state= Query_arena::STMT_EXECUTED;
|
state= Query_arena::STMT_EXECUTED;
|
||||||
|
|
||||||
if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
|
if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user