MDEV-8114: server crash on updates with joins still on 10.0.18
Check that leaf table list is really built before storing it.
This commit is contained in:
parent
9a3b975da6
commit
6264451f25
31
mysql-test/r/update_innodb.result
Normal file
31
mysql-test/r/update_innodb.result
Normal file
@ -0,0 +1,31 @@
|
||||
CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL,
|
||||
`c2` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE TABLE `t2` (
|
||||
`c0` varchar(10) NOT NULL,
|
||||
`c1` int(11) NOT NULL,
|
||||
`c2` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c0`,`c1`),
|
||||
KEY `c1` (`c1`),
|
||||
KEY `c2` (`c2`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE TABLE `t3` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`c1` datetime NOT NULL,
|
||||
`c2` bigint(20) NOT NULL,
|
||||
`c3` int(4) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `c2` (`c2`),
|
||||
KEY `c3` (`c3`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE TABLE `t4` (
|
||||
`c1` int(11) NOT NULL,
|
||||
`c2` bigint(20) DEFAULT NULL,
|
||||
`c3` int(11) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE ALGORITHM=UNDEFINED VIEW `v1` AS select `t4`.`c1` AS `c1`,`t4`.`c2` AS `c2`,`t4`.`c3` AS `c3` from `t4`;
|
||||
UPDATE t1 a JOIN t2 b ON a.c1 = b.c1 JOIN v1 vw ON b.c2 = vw.c1 JOIN t3 del ON vw.c2 = del.c2 SET a.c2 = ( SELECT max(t.c1) FROM t3 t, v1 i WHERE del.c2 = t.c2 AND vw.c3 = i.c3 AND t.c3 = 4 ) WHERE a.c2 IS NULL OR a.c2 < '2011-05-01';
|
||||
drop view v1;
|
||||
drop table t1,t2,t3,t4;
|
39
mysql-test/t/update_innodb.test
Normal file
39
mysql-test/t/update_innodb.test
Normal file
@ -0,0 +1,39 @@
|
||||
--source include/have_innodb.inc
|
||||
|
||||
CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL,
|
||||
`c2` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `t2` (
|
||||
`c0` varchar(10) NOT NULL,
|
||||
`c1` int(11) NOT NULL,
|
||||
`c2` int(11) NOT NULL,
|
||||
PRIMARY KEY (`c0`,`c1`),
|
||||
KEY `c1` (`c1`),
|
||||
KEY `c2` (`c2`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `t3` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`c1` datetime NOT NULL,
|
||||
`c2` bigint(20) NOT NULL,
|
||||
`c3` int(4) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `c2` (`c2`),
|
||||
KEY `c3` (`c3`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `t4` (
|
||||
`c1` int(11) NOT NULL,
|
||||
`c2` bigint(20) DEFAULT NULL,
|
||||
`c3` int(11) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE ALGORITHM=UNDEFINED VIEW `v1` AS select `t4`.`c1` AS `c1`,`t4`.`c2` AS `c2`,`t4`.`c3` AS `c3` from `t4`;
|
||||
|
||||
UPDATE t1 a JOIN t2 b ON a.c1 = b.c1 JOIN v1 vw ON b.c2 = vw.c1 JOIN t3 del ON vw.c2 = del.c2 SET a.c2 = ( SELECT max(t.c1) FROM t3 t, v1 i WHERE del.c2 = t.c2 AND vw.c3 = i.c3 AND t.c3 = 4 ) WHERE a.c2 IS NULL OR a.c2 < '2011-05-01';
|
||||
|
||||
drop view v1;
|
||||
drop table t1,t2,t3,t4;
|
@ -8291,9 +8291,10 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||
if (select_lex->first_cond_optimization)
|
||||
{
|
||||
leaves.empty();
|
||||
if (!select_lex->is_prep_leaf_list_saved)
|
||||
if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED)
|
||||
{
|
||||
make_leaves_list(leaves, tables, full_table_list, first_select_table);
|
||||
select_lex->prep_leaf_list_state= SELECT_LEX::READY;
|
||||
select_lex->leaf_tables_exec.empty();
|
||||
}
|
||||
else
|
||||
|
@ -1882,7 +1882,7 @@ void st_select_lex::init_query()
|
||||
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
|
||||
nest_level= 0;
|
||||
link_next= 0;
|
||||
is_prep_leaf_list_saved= FALSE;
|
||||
prep_leaf_list_state= UNINIT;
|
||||
bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
|
||||
m_non_agg_field_used= false;
|
||||
m_agg_func_used= false;
|
||||
@ -4129,12 +4129,22 @@ bool st_select_lex::save_prep_leaf_tables(THD *thd)
|
||||
{
|
||||
List_iterator_fast<TABLE_LIST> li(leaf_tables);
|
||||
TABLE_LIST *table;
|
||||
|
||||
/*
|
||||
Check that the SELECT_LEX was really prepared and so tables are setup.
|
||||
|
||||
It can be subquery in SET clause of UPDATE which was not prepared yet, so
|
||||
its tables are not yet setup and ready for storing.
|
||||
*/
|
||||
if (prep_leaf_list_state != READY)
|
||||
return FALSE;
|
||||
|
||||
while ((table= li++))
|
||||
{
|
||||
if (leaf_tables_prep.push_back(table))
|
||||
return TRUE;
|
||||
}
|
||||
is_prep_leaf_list_saved= TRUE;
|
||||
prep_leaf_list_state= SAVED;
|
||||
for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit())
|
||||
{
|
||||
for (SELECT_LEX *sl= u->first_select(); sl; sl= sl->next_select())
|
||||
|
@ -789,7 +789,8 @@ public:
|
||||
List<TABLE_LIST> leaf_tables;
|
||||
List<TABLE_LIST> leaf_tables_exec;
|
||||
List<TABLE_LIST> leaf_tables_prep;
|
||||
bool is_prep_leaf_list_saved;
|
||||
enum leaf_list_state {UNINIT, READY, SAVED};
|
||||
enum leaf_list_state prep_leaf_list_state;
|
||||
uint insert_tables;
|
||||
st_select_lex *merged_into; /* select which this select is merged into */
|
||||
/* (not 0 only for views/derived tables) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user