summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <sanja@askmonty.org>2014-05-01 17:19:17 +0300
committerunknown <sanja@askmonty.org>2014-05-01 17:19:17 +0300
commit285160dee270abbbfef9b7c1fb72ec4040c42262 (patch)
treec55beb66ac77398cb722da3e07fcfa7bf919f395 /sql
parenta24ea50d1a04d7bfe9608fe1ea8ac1ab8ed97294 (diff)
downloadmariadb-git-285160dee270abbbfef9b7c1fb72ec4040c42262.tar.gz
MDEV-5981: name resolution issues with views and multi-update in ps-protocol
It is triple bug with one test suite: 1. Incorrect outer table detection 2. Incorrect leaf table processing for multi-update (should be full like for usual updates and inserts) 3. ON condition fix_fields() fould be called for all tables of the query.
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc4
-rw-r--r--sql/sql_base.cc119
-rw-r--r--sql/sql_select.cc4
3 files changed, 80 insertions, 47 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 58b2d164509..a45a7500f1c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4336,6 +4336,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 c68ec7f1191..fe7b8a664b2 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8449,6 +8449,77 @@ 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)
+{
+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
+ uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
+#endif
+ 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.
@@ -8474,7 +8545,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
SELECT_LEX *select_lex= thd->lex->current_select;
Query_arena *arena= thd->stmt_arena, backup;
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
@@ -8537,51 +8607,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 45fa64e5a64..740a612fb8b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -591,7 +591,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);
/*