106
106
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
108
108
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
109
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
110
109
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
111
110
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
112
111
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
113
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
114
112
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
115
113
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
826
824
unit->select_limit_cnt,
827
825
lex->duplicates, lex->ignore);
829
case SQLCOM_UPDATE_MULTI:
831
assert(first_table == all_tables && first_table != 0);
832
if ((res= update_precheck(session, all_tables)))
835
if ((res= mysql_multi_update_prepare(session)))
838
res= mysql_multi_update(session, all_tables,
839
&select_lex->item_list,
843
lex->duplicates, lex->ignore, unit, select_lex);
846
827
case SQLCOM_REPLACE:
847
828
case SQLCOM_INSERT:
961
case SQLCOM_DELETE_MULTI:
963
assert(first_table == all_tables && first_table != 0);
964
TableList *aux_tables=
965
(TableList *)session->lex->auxiliary_table_list.first;
966
multi_delete *del_result;
968
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
974
if ((res= multi_delete_precheck(session, all_tables)))
977
/* condition will be true on SP re-excuting */
978
if (select_lex->item_list.elements != 0)
979
select_lex->item_list.empty();
980
if (session->add_item_to_list(new Item_null()))
983
session->set_proc_info("init");
984
if ((res= session->open_and_lock_tables(all_tables)))
987
if ((res= mysql_multi_delete_prepare(session)))
990
if (!session->is_fatal_error &&
991
(del_result= new multi_delete(aux_tables, lex->table_count)))
993
res= mysql_select(session, &select_lex->ref_pointer_array,
994
select_lex->get_table_list(),
995
select_lex->with_wild,
996
select_lex->item_list,
998
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
999
select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
1000
del_result, unit, select_lex);
1001
res|= session->is_error();
1003
del_result->abort();
1010
942
case SQLCOM_DROP_TABLE:
1012
944
assert(first_table == all_tables && first_table != 0);
2580
Multi delete query pre-check.
2582
@param session Thread handler
2583
@param tables Global/local table list
2591
bool multi_delete_precheck(Session *session, TableList *)
2593
Select_Lex *select_lex= &session->lex->select_lex;
2594
TableList **save_query_tables_own_last= session->lex->query_tables_own_last;
2596
session->lex->query_tables_own_last= 0;
2597
session->lex->query_tables_own_last= save_query_tables_own_last;
2599
if ((session->options & OPTION_SAFE_UPDATES) && !select_lex->where)
2601
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
2602
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
2610
Given a table in the source list, find a correspondent table in the
2611
table references list.
2613
@param lex Pointer to LEX representing multi-delete.
2614
@param src Source table to match.
2615
@param ref Table references list.
2617
@remark The source table list (tables listed before the FROM clause
2618
or tables listed in the FROM clause before the USING clause) may
2619
contain table names or aliases that must match unambiguously one,
2620
and only one, table in the target table list (table references list,
2621
after FROM/USING clause).
2623
@return Matching table, NULL otherwise.
2626
static TableList *multi_delete_table_match(LEX *, TableList *tbl,
2629
TableList *match= NULL;
2631
for (TableList *elem= tables; elem; elem= elem->next_local)
2635
if (tbl->is_fqtn && elem->is_alias)
2636
continue; /* no match */
2637
if (tbl->is_fqtn && elem->is_fqtn)
2638
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
2639
strcmp(tbl->db, elem->db);
2640
else if (elem->is_alias)
2641
cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
2643
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
2644
strcmp(tbl->db, elem->db);
2651
my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
2659
my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
2666
Link tables in auxilary table list of multi-delete with corresponding
2667
elements in main table list, and set proper locks for them.
2669
@param lex pointer to LEX representing multi-delete
2677
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
2679
TableList *tables= (TableList*)lex->select_lex.table_list.first;
2680
TableList *target_tbl;
2682
lex->table_count= 0;
2684
for (target_tbl= (TableList *)lex->auxiliary_table_list.first;
2685
target_tbl; target_tbl= target_tbl->next_local)
2688
/* All tables in aux_tables must be found in FROM PART */
2689
TableList *walk= multi_delete_table_match(lex, target_tbl, tables);
2694
target_tbl->table_name= walk->table_name;
2695
target_tbl->table_name_length= walk->table_name_length;
2697
walk->updating= target_tbl->updating;
2698
walk->lock_type= target_tbl->lock_type;
2699
target_tbl->correspondent_table= walk; // Remember corresponding table
2706
2500
simple INSERT query pre-check.