105
105
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
107
107
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
108
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
109
108
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
110
109
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
111
110
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
112
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
113
111
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
114
112
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
825
823
unit->select_limit_cnt,
826
824
lex->duplicates, lex->ignore);
828
case SQLCOM_UPDATE_MULTI:
830
assert(first_table == all_tables && first_table != 0);
831
if ((res= update_precheck(session, all_tables)))
834
if ((res= mysql_multi_update_prepare(session)))
837
res= mysql_multi_update(session, all_tables,
838
&select_lex->item_list,
842
lex->duplicates, lex->ignore, unit, select_lex);
845
826
case SQLCOM_REPLACE:
846
827
case SQLCOM_INSERT:
960
case SQLCOM_DELETE_MULTI:
962
assert(first_table == all_tables && first_table != 0);
963
TableList *aux_tables=
964
(TableList *)session->lex->auxiliary_table_list.first;
965
multi_delete *del_result;
967
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
973
if ((res= multi_delete_precheck(session, all_tables)))
976
/* condition will be true on SP re-excuting */
977
if (select_lex->item_list.elements != 0)
978
select_lex->item_list.empty();
979
if (session->add_item_to_list(new Item_null()))
982
session->set_proc_info("init");
983
if ((res= session->open_and_lock_tables(all_tables)))
986
if ((res= mysql_multi_delete_prepare(session)))
989
if (!session->is_fatal_error &&
990
(del_result= new multi_delete(aux_tables, lex->table_count)))
992
res= mysql_select(session, &select_lex->ref_pointer_array,
993
select_lex->get_table_list(),
994
select_lex->with_wild,
995
select_lex->item_list,
997
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
998
select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
999
del_result, unit, select_lex);
1000
res|= session->is_error();
1002
del_result->abort();
1009
941
case SQLCOM_DROP_TABLE:
1011
943
assert(first_table == all_tables && first_table != 0);
2579
Multi delete query pre-check.
2581
@param session Thread handler
2582
@param tables Global/local table list
2590
bool multi_delete_precheck(Session *session, TableList *)
2592
Select_Lex *select_lex= &session->lex->select_lex;
2593
TableList **save_query_tables_own_last= session->lex->query_tables_own_last;
2595
session->lex->query_tables_own_last= 0;
2596
session->lex->query_tables_own_last= save_query_tables_own_last;
2598
if ((session->options & OPTION_SAFE_UPDATES) && !select_lex->where)
2600
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
2601
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
2609
Given a table in the source list, find a correspondent table in the
2610
table references list.
2612
@param lex Pointer to LEX representing multi-delete.
2613
@param src Source table to match.
2614
@param ref Table references list.
2616
@remark The source table list (tables listed before the FROM clause
2617
or tables listed in the FROM clause before the USING clause) may
2618
contain table names or aliases that must match unambiguously one,
2619
and only one, table in the target table list (table references list,
2620
after FROM/USING clause).
2622
@return Matching table, NULL otherwise.
2625
static TableList *multi_delete_table_match(LEX *, TableList *tbl,
2628
TableList *match= NULL;
2630
for (TableList *elem= tables; elem; elem= elem->next_local)
2634
if (tbl->is_fqtn && elem->is_alias)
2635
continue; /* no match */
2636
if (tbl->is_fqtn && elem->is_fqtn)
2637
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
2638
strcmp(tbl->db, elem->db);
2639
else if (elem->is_alias)
2640
cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
2642
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
2643
strcmp(tbl->db, elem->db);
2650
my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
2658
my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
2665
Link tables in auxilary table list of multi-delete with corresponding
2666
elements in main table list, and set proper locks for them.
2668
@param lex pointer to LEX representing multi-delete
2676
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
2678
TableList *tables= (TableList*)lex->select_lex.table_list.first;
2679
TableList *target_tbl;
2681
lex->table_count= 0;
2683
for (target_tbl= (TableList *)lex->auxiliary_table_list.first;
2684
target_tbl; target_tbl= target_tbl->next_local)
2687
/* All tables in aux_tables must be found in FROM PART */
2688
TableList *walk= multi_delete_table_match(lex, target_tbl, tables);
2693
target_tbl->table_name= walk->table_name;
2694
target_tbl->table_name_length= walk->table_name_length;
2696
walk->updating= target_tbl->updating;
2697
walk->lock_type= target_tbl->lock_type;
2698
target_tbl->correspondent_table= walk; // Remember corresponding table
2705
2499
simple INSERT query pre-check.