diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2015-04-22 10:14:11 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2015-04-22 13:59:18 +0200 |
commit | 8cbaafd22b145512cc91f7b512290320849e77bd (patch) | |
tree | 883256655c931a6bb940b7d7d67d5d985673d17c | |
parent | e428c809d7e2176834ed9889483643e4ef2c2c2b (diff) | |
download | mariadb-git-8cbaafd22b145512cc91f7b512290320849e77bd.tar.gz |
MDEV-8018: main.multi_update fails with --ps-protocol
save_prep_leaf_tables() made recursive to work with underlying view
Arena restoiring fixed in case of EOM.
-rw-r--r-- | mysql-test/r/multi_update.result | 5 | ||||
-rw-r--r-- | mysql-test/t/multi_update.test | 6 | ||||
-rw-r--r-- | sql/sql_delete.cc | 2 | ||||
-rw-r--r-- | sql/sql_derived.cc | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 37 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
7 files changed, 47 insertions, 11 deletions
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 0c522ec1f4f..09df98c741e 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -1010,6 +1010,11 @@ CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1c`.`fe2` AS `fe2`,`t1c`.`f34` AS `f34`,`t1c`.`f33` AS `f33`,`t1c`.`f32` AS `f32`,`t1c`.`f37` AS `f37`,`t1c`.`fe10` AS `fe10`,if((`tov`.`ft6` in ('klarmobil','callmobile')),`tov`.`ft9`,`tov`.`ft6`) AS `ft6_1`,`tov`.`ft6_2` AS `ft6_2`,`ua`.`fe18` AS `fe18`,`ua`.`ft3` AS `ft3` from ((`t3` `t1c` left join `v2` `ua` on((`t1c`.`fe2` = `ua`.`fe2`))) left join `v1` `tov` on((`t1c`.`fe8` = `tov`.`ft4`))) where (`t1c`.`ft3` = `ua`.`ft3`) group by `t1c`.`fe2`,`t1c`.`f34`,`t1c`.`f33`,`t1c`.`f32` order by `t1c`.`f34`; UPDATE t1 t1 left join v3 t2 on t1.f4 = t2.fe2 SET t1.f20 = t2.ft6_1, t1.f32 = t2.f32, t1.f33 = t2.f33, t1.f37 = t2.f37 WHERE f5 >= '2015-02-01'; +#MDEV-8018: main.multi_update fails with --ps-protocol +prepare stmt1 from "UPDATE t1 t1 left join v3 t2 on t1.f4 = t2.fe2 SET t1.f20 = t2.ft6_1, t1.f32 = t2.f32, t1.f33 = t2.f33, t1.f37 = t2.f37 WHERE f5 >= '2015-02-01'"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; drop view v3,v2,v1; drop table t1,t2,t3; end of 5.5 tests diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 720d9503eb2..8184d8ded1a 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -1047,6 +1047,12 @@ VIEW `v3` AS select `t1c`.`fe2` AS `fe2`,`t1c`.`f34` AS `f34`,`t1c`.`f33` AS `f3 UPDATE t1 t1 left join v3 t2 on t1.f4 = t2.fe2 SET t1.f20 = t2.ft6_1, t1.f32 = t2.f32, t1.f33 = t2.f33, t1.f37 = t2.f37 WHERE f5 >= '2015-02-01'; +--echo #MDEV-8018: main.multi_update fails with --ps-protocol +prepare stmt1 from "UPDATE t1 t1 left join v3 t2 on t1.f4 = t2.fe2 SET t1.f20 = t2.ft6_1, t1.f32 = t2.f32, t1.f33 = t2.f33, t1.f37 = t2.f37 WHERE f5 >= '2015-02-01'"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + drop view v3,v2,v1; drop table t1,t2,t3; --echo end of 5.5 tests diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 055b4858598..5b233cde7c7 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -610,7 +610,7 @@ int mysql_multi_delete_prepare(THD *thd) */ lex->select_lex.exclude_from_table_unique_test= FALSE; - if (lex->select_lex.save_prep_leaf_tables(thd)) + if (lex->save_prep_leaf_tables()) DBUG_RETURN(TRUE); DBUG_RETURN(FALSE); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 56748fa110d..c6865a7116e 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -169,7 +169,9 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE : DT_PHASES_MATERIALIZE); DBUG_ENTER("mysql_handle_single_derived"); - DBUG_PRINT("enter", ("phases: 0x%x allowed: 0x%x", phases, allowed_phases)); + DBUG_PRINT("enter", ("phases: 0x%x allowed: 0x%x alias: '%s'", + phases, allowed_phases, + (derived->alias ? derived->alias : "<NULL>"))); if (!lex->derived_tables) DBUG_RETURN(FALSE); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 8aeb2e6c516..74591b5371e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -4102,27 +4102,48 @@ bool st_select_lex::save_leaf_tables(THD *thd) } -bool st_select_lex::save_prep_leaf_tables(THD *thd) +bool LEX::save_prep_leaf_tables() { if (!thd->save_prep_leaf_list) - return 0; + return FALSE; Query_arena *arena= thd->stmt_arena, backup; arena= thd->activate_stmt_arena_if_needed(&backup); + //It is used for DETETE/UPDATE so top level has only one SELECT + DBUG_ASSERT(select_lex.next_select() == NULL); + bool res= select_lex.save_prep_leaf_tables(thd); + + if (arena) + thd->restore_active_arena(arena, &backup); + + if (res) + return TRUE; + thd->save_prep_leaf_list= FALSE; + return FALSE; +} + + +bool st_select_lex::save_prep_leaf_tables(THD *thd) +{ List_iterator_fast<TABLE_LIST> li(leaf_tables); TABLE_LIST *table; while ((table= li++)) { if (leaf_tables_prep.push_back(table)) - return 1; + return TRUE; + } + is_prep_leaf_list_saved= TRUE; + 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()) + { + if (sl->save_prep_leaf_tables(thd)) + return TRUE; + } } - thd->lex->select_lex.is_prep_leaf_list_saved= TRUE; - thd->save_prep_leaf_list= FALSE; - if (arena) - thd->restore_active_arena(arena, &backup); - return 0; + return FALSE; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 4f424000180..69ee5cc9be0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2766,6 +2766,8 @@ struct LEX: public Query_tables_list } return FALSE; } + + bool save_prep_leaf_tables(); }; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 300769ef099..23e17b0a3bb 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1388,7 +1388,7 @@ int mysql_multi_update_prepare(THD *thd) */ lex->select_lex.exclude_from_table_unique_test= FALSE; - if (lex->select_lex.save_prep_leaf_tables(thd)) + if (lex->save_prep_leaf_tables()) DBUG_RETURN(TRUE); DBUG_RETURN (FALSE); |