diff options
author | Igor Babaev <igor@askmonty.org> | 2011-07-16 23:57:43 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2011-07-16 23:57:43 -0700 |
commit | 1eea03ccc489371fa2b438a60accda552ad33e12 (patch) | |
tree | 2fc2c3e0ee8a246b65001039b7651a2f38091608 /sql/sql_derived.cc | |
parent | a40354b6e30ff867301779aaf737691aaaf05920 (diff) | |
download | mariadb-git-1eea03ccc489371fa2b438a60accda552ad33e12.tar.gz |
Fixed LP bug #794901.
Also:
1. simplified the code of the function mysql_derived_merge_for_insert.
2. moved merge of views/dt for multi-update/delete to the prepare stage.
3. the list of the references to the candidates for semi-join now is
allocated in the statement memory.
Diffstat (limited to 'sql/sql_derived.cc')
-rw-r--r-- | sql/sql_derived.cc | 55 |
1 files changed, 15 insertions, 40 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 0f860986bab..e3de7d9c2dd 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -346,10 +346,17 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) if (derived->merged) return FALSE; + if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI || + thd->lex->sql_command == SQLCOM_DELETE_MULTI) + thd->save_prep_leaf_list= TRUE; + arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test derived->merged= TRUE; - if (!derived->merged_for_insert) + if (!derived->merged_for_insert || + (derived->is_multitable() && + (thd->lex->sql_command == SQLCOM_UPDATE_MULTI || + thd->lex->sql_command == SQLCOM_DELETE_MULTI))) { /* Check whether there is enough free bits in table map to merge subquery. @@ -392,7 +399,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) } /* Merge derived table's subquery in the parent select. */ - if (parent_lex->merge_subquery(derived, dt_select, tablenr, map)) + if (parent_lex->merge_subquery(thd, derived, dt_select, tablenr, map)) { res= TRUE; goto exit_merge; @@ -468,8 +475,6 @@ exit_merge: bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) { - SELECT_LEX *dt_select= derived->get_single_select(); - if (derived->merged_for_insert) return FALSE; if (derived->is_materialized_derived()) @@ -482,43 +487,13 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) { if (!derived->updatable) return derived->create_field_translation(thd); - TABLE_LIST *tl=((TABLE_LIST*)dt_select->table_list.first); - TABLE *table= tl->table; - /* preserve old map & tablenr. */ - if (!derived->merged_for_insert && derived->table) - table->set_table_map(derived->table->map, derived->table->tablenr); - - derived->table= table; - derived->schema_table= - ((TABLE_LIST*)dt_select->table_list.first)->schema_table; - if (!derived->merged) + if (derived->merge_underlying_list) { - Query_arena *arena, backup; - arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test - derived->select_lex->leaf_tables.push_back(tl); - derived->nested_join= (NESTED_JOIN*) thd->calloc(sizeof(NESTED_JOIN)); - if (derived->nested_join) - { - derived->wrap_into_nested_join(tl->select_lex->top_join_list); - derived->get_unit()->exclude_level(); - } - if (arena) - thd->restore_active_arena(arena, &backup); - derived->merged= TRUE; - if (!derived->nested_join) - return TRUE; - } - } - else - { - if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI || - thd->lex->sql_command == SQLCOM_DELETE_MULTI) - thd->save_prep_leaf_list= TRUE; - if (!derived->merged_for_insert && mysql_derived_merge(thd, lex, derived)) - return TRUE; - } - derived->merged_for_insert= TRUE; - + derived->table= derived->merge_underlying_list->table; + derived->schema_table= derived->merge_underlying_list->schema_table; + derived->merged_for_insert= TRUE; + } + } return FALSE; } |