summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2015-11-03 09:31:20 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2015-11-05 17:50:59 +0100
commit5041de97e15e4af05003a8c6c14bfff106da570b (patch)
tree4937735c3ae99e1df7732ffa9f12c94d18f2910e /sql
parentd9119710c44d0cd785447080c43bf3c2ba2e4cac (diff)
downloadmariadb-git-5041de97e15e4af05003a8c6c14bfff106da570b.tar.gz
MDEV-8701 Crash on derived query
Make unique table check after setup_fields of update because unique table can materialize table and we do not need field resolving after materialization.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_prepare.cc3
-rw-r--r--sql/sql_update.cc32
-rw-r--r--sql/sql_update.h1
3 files changed, 26 insertions, 10 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 1790b972724..8a3c55cbfda 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1420,7 +1420,8 @@ static int mysql_test_update(Prepared_statement *stmt,
(SELECT_ACL & ~table_list->table->grant.privilege);
table_list->register_want_access(SELECT_ACL);
#endif
- if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0))
+ if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0) ||
+ check_unique_table(thd, table_list))
goto error;
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN(0);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index d3d222620a8..0f7b28cd9d9 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -364,6 +364,9 @@ int mysql_update(THD *thd,
DBUG_RETURN(1); /* purecov: inspected */
}
+ if (check_unique_table(thd, table_list))
+ DBUG_RETURN(TRUE);
+
/* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */
if (select_lex->optimize_unflattened_subqueries(false))
DBUG_RETURN(TRUE);
@@ -1095,19 +1098,30 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
- /* Check that we are not using table that we are updating in a sub select */
- {
- TABLE_LIST *duplicate;
- if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
- {
- update_non_unique_table_error(table_list, "UPDATE", duplicate);
- DBUG_RETURN(TRUE);
- }
- }
select_lex->fix_prepare_information(thd, conds, &fake_conds);
DBUG_RETURN(FALSE);
}
+/**
+ Check that we are not using table that we are updating in a sub select
+
+ @param thd Thread handle
+ @param table_list List of table with first to check
+
+ @retval TRUE Error
+ @retval FALSE OK
+*/
+bool check_unique_table(THD *thd, TABLE_LIST *table_list)
+{
+ TABLE_LIST *duplicate;
+ DBUG_ENTER("check_unique_table");
+ if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
+ {
+ update_non_unique_table_error(table_list, "UPDATE", duplicate);
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
+}
/***************************************************************************
Update multiple tables from join
diff --git a/sql/sql_update.h b/sql/sql_update.h
index 64029c5d634..4c6f89d8468 100644
--- a/sql/sql_update.h
+++ b/sql/sql_update.h
@@ -27,6 +27,7 @@ typedef class st_select_lex_unit SELECT_LEX_UNIT;
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
Item **conds, uint order_num, ORDER *order);
+bool check_unique_table(THD *thd, TABLE_LIST *table_list);
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds,
uint order_num, ORDER *order, ha_rows limit,