diff options
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0814c7a747e..e2b7ee93905 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -18,7 +18,6 @@ /* Insert of records */ #include "mysql_priv.h" -#include "sql_acl.h" #include "sp_head.h" #include "sql_trigger.h" #include "sql_select.h" @@ -244,13 +243,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->used_tables=0; values= its++; - if (duplic == DUP_UPDATE) - { - /* it should be allocated before Item::fix_fields() */ - if (table_list->set_insert_values(thd->mem_root)) - goto abort; - } - if (mysql_prepare_insert(thd, table_list, table, fields, values, update_fields, update_values, duplic)) goto abort; @@ -666,26 +658,33 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, */ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, - List<Item> &fields, List_item *values, - List<Item> &update_fields, List<Item> &update_values, - enum_duplicates duplic) + List<Item> &fields, List_item *values, + List<Item> &update_fields, List<Item> &update_values, + enum_duplicates duplic) { bool insert_into_view= (table_list->view != 0); /* TODO: use this condition for 'WITH CHECK OPTION' */ Item *unused_conds= 0; bool res; DBUG_ENTER("mysql_prepare_insert"); - DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d", (ulong)table_list, (ulong)table, (int)insert_into_view)); + + if (duplic == DUP_UPDATE) + { + /* it should be allocated before Item::fix_fields() */ + if (table_list->set_insert_values(thd->mem_root)) + goto abort; + } + if (mysql_prepare_insert_check_table(thd, table_list, fields, &unused_conds, FALSE)) DBUG_RETURN(TRUE); - if (check_insert_fields(thd, table_list, fields, *values, 1, - !insert_into_view) || - setup_fields(thd, 0, table_list, *values, 0, 0, 0) || + if ((values && check_insert_fields(thd, table_list, fields, *values, 1, + !insert_into_view)) || + (values && setup_fields(thd, 0, table_list, *values, 0, 0, 0)) || (duplic == DUP_UPDATE && ((thd->lex->select_lex.no_wrap_view_item= 1, (res= setup_fields(thd, 0, table_list, update_fields, 1, 0, 0)), @@ -697,7 +696,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, if (!table) table= table_list->table; - if (unique_table(table_list, table_list->next_global)) + if ((thd->lex->sql_command == SQLCOM_INSERT || + thd->lex->sql_command == SQLCOM_REPLACE) && + unique_table(table_list, table_list->next_global)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); DBUG_RETURN(TRUE); @@ -795,8 +796,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) that matches, is updated. If update causes a conflict again, an error is returned */ + DBUG_ASSERT(table->insert_values != NULL); store_record(table,insert_values); restore_record(table,record[1]); + DBUG_ASSERT(info->update_fields->elements == info->update_values->elements); if (fill_record(thd, *info->update_fields, *info->update_values, 0)) goto err; @@ -1753,17 +1756,21 @@ bool mysql_insert_select_prepare(THD *thd) select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, - List<Item> *fields_par, enum_duplicates duplic, + List<Item> *fields_par, + List<Item> *update_fields, List<Item> *update_values, + enum_duplicates duplic, bool ignore_check_option_errors) :table_list(table_list_par), table(table_par), fields(fields_par), last_insert_id(0), insert_into_view(table_list_par && table_list_par->view != 0) { bzero((char*) &info,sizeof(info)); - info.handle_duplicates=duplic; + info.handle_duplicates= duplic; + info.ignore= ignore_check_option_errors; + info.update_fields= update_fields; + info.update_values= update_values; if (table_list_par) info.view= (table_list_par->view ? table_list_par : 0); - info.ignore= ignore_check_option_errors; } |