summaryrefslogtreecommitdiff
path: root/sql/sql_derived.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2011-07-16 23:57:43 -0700
committerIgor Babaev <igor@askmonty.org>2011-07-16 23:57:43 -0700
commit1eea03ccc489371fa2b438a60accda552ad33e12 (patch)
tree2fc2c3e0ee8a246b65001039b7651a2f38091608 /sql/sql_derived.cc
parenta40354b6e30ff867301779aaf737691aaaf05920 (diff)
downloadmariadb-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.cc55
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;
}