summaryrefslogtreecommitdiff
path: root/sql/sql_update.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r--sql/sql_update.cc95
1 files changed, 65 insertions, 30 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 3e9bb0b753b..918a4c769b4 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -70,8 +70,6 @@ int mysql_update(THD *thd,
READ_RECORD info;
TABLE_LIST *update_table_list= ((TABLE_LIST*)
thd->lex->select_lex.table_list.first);
- TABLE_LIST tables;
- List<Item> all_fields;
DBUG_ENTER("mysql_update");
LINT_INIT(used_index);
@@ -86,30 +84,13 @@ int mysql_update(THD *thd,
/* Calculate "table->used_keys" based on the WHERE */
table->used_keys=table->keys_in_use;
table->quick_keys.clear_all();
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- want_privilege=table->grant.want_privilege;
- table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
+ want_privilege= table->grant.want_privilege;
#endif
-
- bzero((char*) &tables,sizeof(tables)); // For ORDER BY
- tables.table= table;
- tables.alias= table_list->alias;
-
- if (setup_tables(update_table_list) ||
- setup_conds(thd,update_table_list,&conds) ||
- thd->lex->select_lex.setup_ref_array(thd, order_num) ||
- setup_order(thd, thd->lex->select_lex.ref_pointer_array,
- &tables, all_fields, all_fields, order) ||
- setup_ftfuncs(&thd->lex->select_lex))
- DBUG_RETURN(-1); /* purecov: inspected */
-
- /* Check that we are not using table that we are updating in a sub select */
- if (find_real_table_in_list(table_list->next,
- table_list->db, table_list->real_name))
- {
- my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
- DBUG_RETURN(-1);
- }
+ if ((error= mysql_prepare_update(thd, table_list, update_table_list,
+ &conds, order_num, order)))
+ DBUG_RETURN(error);
old_used_keys= table->used_keys; // Keys used in WHERE
/*
@@ -420,6 +401,59 @@ err:
DBUG_RETURN(-1);
}
+/*
+ Prepare items in UPDATE statement
+
+ SYNOPSIS
+ mysql_prepare_update()
+ thd - thread handler
+ table_list - global table list
+ update_table_list - local table list of UPDATE SELECT_LEX
+ conds - conditions
+ order_num - number of ORDER BY list entries
+ order - ORDER BY clause list
+
+ RETURN VALUE
+ 0 - OK
+ 1 - error (message is sent to user)
+ -1 - error (message is not sent to user)
+*/
+int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
+ TABLE_LIST *update_table_list,
+ Item **conds, uint order_num, ORDER *order)
+{
+ TABLE *table= table_list->table;
+ TABLE_LIST tables;
+ List<Item> all_fields;
+ DBUG_ENTER("mysql_prepare_update");
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
+#endif
+
+ bzero((char*) &tables,sizeof(tables)); // For ORDER BY
+ tables.table= table;
+ tables.alias= table_list->alias;
+
+ if (setup_tables(update_table_list) ||
+ setup_conds(thd, update_table_list, conds) ||
+ thd->lex->select_lex.setup_ref_array(thd, order_num) ||
+ setup_order(thd, thd->lex->select_lex.ref_pointer_array,
+ update_table_list, all_fields, all_fields, order) ||
+ setup_ftfuncs(&thd->lex->select_lex))
+ DBUG_RETURN(-1);
+
+ /* Check that we are not using table that we are updating in a sub select */
+ if (find_real_table_in_list(table_list->next,
+ table_list->db, table_list->real_name))
+ {
+ my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
+ DBUG_RETURN(-1);
+ }
+
+ DBUG_RETURN(0);
+}
+
/***************************************************************************
Update multiple tables from join
@@ -441,6 +475,7 @@ int mysql_multi_update(THD *thd,
int res;
multi_update *result;
TABLE_LIST *tl;
+ TABLE_LIST *update_list= (TABLE_LIST*) thd->lex->select_lex.table_list.first;
table_map item_tables= 0, derived_tables= 0;
DBUG_ENTER("mysql_multi_update");
@@ -453,7 +488,7 @@ int mysql_multi_update(THD *thd,
Ensure that we have update privilege for all tables and columns in the
SET part
*/
- for (tl= table_list ; tl ; tl=tl->next)
+ for (tl= update_list; tl; tl= tl->next)
{
TABLE *table= tl->table;
/*
@@ -470,14 +505,14 @@ int mysql_multi_update(THD *thd,
{
// Assign table map values to check updatability of derived tables
uint tablenr=0;
- for (TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
+ for (TABLE_LIST *table_list= update_list;
table_list;
table_list= table_list->next, tablenr++)
{
table_list->table->map= (table_map) 1 << tablenr;
}
}
- if (setup_fields(thd, 0, table_list, *fields, 1, 0, 0))
+ if (setup_fields(thd, 0, update_list, *fields, 1, 0, 0))
DBUG_RETURN(-1);
if (thd->lex->derived_tables)
{
@@ -493,7 +528,7 @@ int mysql_multi_update(THD *thd,
/*
Count tables and setup timestamp handling
*/
- for (tl= select_lex->get_table_list() ; tl ; tl= tl->next)
+ for (tl= update_list; tl; tl= tl->next)
{
TABLE *table= tl->table;
@@ -510,7 +545,7 @@ int mysql_multi_update(THD *thd,
if (thd->lex->derived_tables && (item_tables & derived_tables))
{
// find derived table which cause error
- for (tl= select_lex->get_table_list() ; tl ; tl= tl->next)
+ for (tl= update_list; tl; tl= tl->next)
{
if (tl->derived && (item_tables & tl->table->map))
{
@@ -521,7 +556,7 @@ int mysql_multi_update(THD *thd,
}
}
- if (!(result=new multi_update(thd, table_list, fields, values,
+ if (!(result=new multi_update(thd, update_list, fields, values,
handle_duplicates)))
DBUG_RETURN(-1);