summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <sanja@askmonty.org>2014-05-07 09:28:12 +0300
committerunknown <sanja@askmonty.org>2014-05-07 09:28:12 +0300
commit3f80740aa8fb24a0f9798e7239f0adb9f910e0a6 (patch)
tree85fc1ae8cb23e103f2a3af5c44d3a2c1546f1c9c /sql
parent554fd30ba3f118d1ec2b89c0437bfd7f3cab9995 (diff)
parent285160dee270abbbfef9b7c1fb72ec4040c42262 (diff)
downloadmariadb-git-3f80740aa8fb24a0f9798e7239f0adb9f910e0a6.tar.gz
merge 5.5->5.3
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc4
-rw-r--r--sql/sql_base.cc117
-rw-r--r--sql/sql_select.cc4
3 files changed, 78 insertions, 47 deletions
diff --git a/sql/item.cc b/sql/item.cc
index b3d4b4a7616..7a650ca75c7 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4697,6 +4697,10 @@ bool is_outer_table(TABLE_LIST *table, SELECT_LEX *select)
DBUG_ASSERT(table->select_lex != select);
TABLE_LIST *tl;
+ if (table->belong_to_view &&
+ table->belong_to_view->select_lex == select)
+ return FALSE;
+
for (tl= select->master_unit()->derived;
tl && tl->is_merged_derived();
select= tl->select_lex, tl= select->master_unit()->derived)
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 3eefd8e8835..577d667b450 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8747,6 +8747,75 @@ void wrap_ident(THD *thd, Item **conds)
thd->restore_active_arena(arena, &backup);
}
+/**
+ Prepare ON expression
+
+ @param thd Thread handle
+ @param table Pointer to table list
+ @param is_update Update flag
+
+ @retval TRUE error.
+ @retval FALSE OK.
+*/
+
+bool setup_on_expr(THD *thd, TABLE_LIST *table, bool is_update)
+{
+ uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
+ if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
+ return TRUE; // Fatal error flag is set!
+ for(; table; table= table->next_local)
+ {
+ TABLE_LIST *embedded; /* The table at the current level of nesting. */
+ TABLE_LIST *embedding= table; /* The parent nested table reference. */
+ do
+ {
+ embedded= embedding;
+ DBUG_PRINT("XXX", ("check: %s", table->alias));
+ if (embedded->on_expr)
+ {
+ thd->where="on clause";
+ embedded->on_expr->mark_as_condition_AND_part(embedded);
+ if ((!embedded->on_expr->fixed &&
+ embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
+ embedded->on_expr->check_cols(1))
+ return TRUE;
+ }
+ /*
+ If it's a semi-join nest, fix its "left expression", as it is used by
+ the SJ-Materialization
+ */
+ if (embedded->sj_subq_pred)
+ {
+ Item **left_expr= &embedded->sj_subq_pred->left_expr;
+ if (!(*left_expr)->fixed && (*left_expr)->fix_fields(thd, left_expr))
+ return TRUE;
+ }
+
+ embedding= embedded->embedding;
+ }
+ while (embedding &&
+ embedding->nested_join->join_list.head() == embedded);
+
+ if (table->is_merged_derived())
+ {
+ SELECT_LEX *select_lex= table->get_single_select();
+ setup_on_expr(thd, select_lex->get_table_list(), is_update);
+ }
+
+ /* process CHECK OPTION */
+ if (is_update)
+ {
+ TABLE_LIST *view= table->top_table();
+ if (view->effective_with_check)
+ {
+ if (view->prepare_check_option(thd))
+ return TRUE;
+ thd->change_item_tree(&table->check_option, view->check_option);
+ }
+ }
+ }
+ return FALSE;
+}
/*
Fix all conditions and outer join expressions.
@@ -8771,7 +8840,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
{
SELECT_LEX *select_lex= thd->lex->current_select;
TABLE_LIST *table= NULL; // For HP compilers
- List_iterator<TABLE_LIST> ti(leaves);
/*
it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX
which belong to LEX, i.e. most up SELECT) will be updated by
@@ -8830,51 +8898,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
Apply fix_fields() to all ON clauses at all levels of nesting,
including the ones inside view definitions.
*/
- while ((table= ti++))
- {
- TABLE_LIST *embedded; /* The table at the current level of nesting. */
- TABLE_LIST *embedding= table; /* The parent nested table reference. */
- do
- {
- embedded= embedding;
- if (embedded->on_expr)
- {
- /* Make a join an a expression */
- thd->where="on clause";
- embedded->on_expr->mark_as_condition_AND_part(embedded);
- if ((!embedded->on_expr->fixed &&
- embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
- embedded->on_expr->check_cols(1))
- goto err_no_arena;
- }
- /*
- If it's a semi-join nest, fix its "left expression", as it is used by
- the SJ-Materialization
- */
- if (embedded->sj_subq_pred)
- {
- Item **left_expr= &embedded->sj_subq_pred->left_expr;
- if (!(*left_expr)->fixed && (*left_expr)->fix_fields(thd, left_expr))
- goto err_no_arena;
- }
-
- embedding= embedded->embedding;
- }
- while (embedding &&
- embedding->nested_join->join_list.head() == embedded);
-
- /* process CHECK OPTION */
- if (it_is_update)
- {
- TABLE_LIST *view= table->top_table();
- if (view->effective_with_check)
- {
- if (view->prepare_check_option(thd))
- goto err_no_arena;
- thd->change_item_tree(&table->check_option, view->check_option);
- }
- }
- }
+ if (setup_on_expr(thd, tables, it_is_update))
+ goto err_no_arena;
if (!thd->stmt_arena->is_conventional())
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e275a7ffee7..1f591624457 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -646,7 +646,9 @@ JOIN::prepare(Item ***rref_pointer_array,
if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
setup_tables_and_check_access(thd, &select_lex->context, join_list,
tables_list, select_lex->leaf_tables,
- FALSE, SELECT_ACL, SELECT_ACL, FALSE))
+ FALSE, SELECT_ACL, SELECT_ACL,
+ (thd->lex->sql_command ==
+ SQLCOM_UPDATE_MULTI)))
DBUG_RETURN(-1);
/*