152
int mysql_update(Session *session, TableList *table_list,
153
List<Item> &fields, List<Item> &values, COND *conds,
154
uint32_t order_num, order_st *order,
155
ha_rows limit, enum enum_duplicates,
151
int mysql_update(THD *thd,
152
TableList *table_list,
156
uint order_num, order_st *order,
158
enum enum_duplicates handle_duplicates __attribute__((unused)),
158
161
bool using_limit= limit != HA_POS_ERROR;
159
bool safe_update= test(session->options & OPTION_SAFE_UPDATES);
162
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
160
163
bool used_key_is_modified, transactional_table, will_batch;
161
164
bool can_compare_record;
162
165
int error, loc_error;
163
166
uint used_index= MAX_KEY, dup_key_found;
164
167
bool need_sort= true;
165
uint32_t table_count= 0;
166
169
ha_rows updated, found;
167
170
key_map old_covering_keys;
169
172
SQL_SELECT *select;
170
173
READ_RECORD info;
171
SELECT_LEX *select_lex= &session->lex->select_lex;
174
SELECT_LEX *select_lex= &thd->lex->select_lex;
172
175
bool need_reopen;
174
177
List<Item> all_fields;
175
Session::killed_state killed_status= Session::NOT_KILLED;
178
THD::killed_state killed_status= THD::NOT_KILLED;
179
if (open_tables(session, &table_list, &table_count, 0))
182
if (open_tables(thd, &table_list, &table_count, 0))
182
if (!lock_tables(session, table_list, table_count, &need_reopen))
185
if (!lock_tables(thd, table_list, table_count, &need_reopen))
184
187
if (!need_reopen)
186
close_tables_for_reopen(session, &table_list);
189
close_tables_for_reopen(thd, &table_list);
189
if (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
190
(session->fill_derived_tables() &&
191
mysql_handle_derived(session->lex, &mysql_derived_filling)))
192
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
193
(thd->fill_derived_tables() &&
194
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
194
197
DRIZZLE_UPDATE_START();
195
session->set_proc_info("init");
198
thd_proc_info(thd, "init");
196
199
table= table_list->table;
198
201
/* Calculate "table->covering_keys" based on the WHERE */
199
202
table->covering_keys= table->s->keys_in_use;
200
203
table->quick_keys.clear_all();
202
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
205
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
205
208
old_covering_keys= table->covering_keys; // Keys used in WHERE
206
209
/* Check the fields we are going to modify */
207
if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
210
if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
208
211
goto abort; /* purecov: inspected */
209
212
if (table->timestamp_field)
224
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
227
if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
226
free_underlaid_joins(session, select_lex);
229
free_underlaid_joins(thd, select_lex);
227
230
goto abort; /* purecov: inspected */
230
233
if (select_lex->inner_refs_list.elements &&
231
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
234
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
233
236
DRIZZLE_UPDATE_END();
261
264
select= make_select(table, 0, 0, conds, 0, &error);
262
265
if (error || !limit ||
263
(select && select->check_quick(session, safe_update, limit)))
266
(select && select->check_quick(thd, safe_update, limit)))
266
free_underlaid_joins(session, select_lex);
269
free_underlaid_joins(thd, select_lex);
268
271
goto abort; // Error in where
269
272
DRIZZLE_UPDATE_END();
270
my_ok(session); // No matching records
273
my_ok(thd); // No matching records
273
276
if (!select && limit != HA_POS_ERROR)
332
335
NOTE: filesort will call table->prepare_for_position()
335
338
SORT_FIELD *sortorder;
336
339
ha_rows examined_rows;
338
341
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
339
342
MYF(MY_FAE | MY_ZEROFILL));
340
343
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
341
(table->sort.found_records= filesort(session, table, sortorder, length,
344
(table->sort.found_records= filesort(thd, table, sortorder, length,
342
345
select, limit, 1,
384
387
if (used_index == MAX_KEY || (select && select->quick))
385
init_read_record(&info,session,table,select,0,1);
388
init_read_record(&info,thd,table,select,0,1);
387
init_read_record_idx(&info, session, table, 1, used_index);
390
init_read_record_idx(&info, thd, table, 1, used_index);
389
session->set_proc_info("Searching rows for update");
392
thd_proc_info(thd, "Searching rows for update");
390
393
ha_rows tmp_limit= limit;
392
while (!(error=info.read_record(&info)) && !session->killed)
395
while (!(error=info.read_record(&info)) && !thd->killed)
394
397
if (!(select && select->skip_record()))
448
451
if (select && select->quick && select->quick->reset())
450
453
table->file->try_semi_consistent_read(1);
451
init_read_record(&info,session,table,select,0,1);
454
init_read_record(&info,thd,table,select,0,1);
453
456
updated= found= 0;
454
457
/* Generate an error when trying to set a NOT NULL field to NULL. */
455
session->count_cuted_fields= ignore ? CHECK_FIELD_WARN
458
thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
456
459
: CHECK_FIELD_ERROR_FOR_NULL;
457
session->cuted_fields=0L;
458
session->set_proc_info("Updating");
460
thd->cuted_fields=0L;
461
thd_proc_info(thd, "Updating");
460
463
transactional_table= table->file->has_transactions();
461
session->abort_on_warning= test(!ignore);
464
thd->abort_on_warning= test(!ignore);
462
465
will_batch= !table->file->start_bulk_update();
659
662
Sometimes we want to binlog even if we updated no rows, in case user used
660
663
it to be sure master and slave are in same state.
662
if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
665
if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
664
667
if (mysql_bin_log.is_open())
667
session->clear_error();
668
if (session->binlog_query(Session::ROW_QUERY_TYPE,
669
session->query, session->query_length,
671
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
672
thd->query, thd->query_length,
670
673
transactional_table, false, killed_status) &&
671
674
transactional_table)
673
676
error=1; // Rollback update
676
if (session->transaction.stmt.modified_non_trans_table)
677
session->transaction.all.modified_non_trans_table= true;
679
if (thd->transaction.stmt.modified_non_trans_table)
680
thd->transaction.all.modified_non_trans_table= true;
679
assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
680
free_underlaid_joins(session, select_lex);
682
assert(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
683
free_underlaid_joins(thd, select_lex);
682
685
/* If LAST_INSERT_ID(X) was used, report X */
683
id= session->arg_of_last_insert_id_function ?
684
session->first_successful_insert_id_in_prev_stmt : 0;
686
id= thd->arg_of_last_insert_id_function ?
687
thd->first_successful_insert_id_in_prev_stmt : 0;
686
689
DRIZZLE_UPDATE_END();
689
692
char buff[STRING_BUFFER_USUAL_SIZE];
690
693
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
691
(ulong) session->cuted_fields);
692
session->row_count_func=
693
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
694
my_ok(session, (ulong) session->row_count_func, id, buff);
694
(ulong) thd->cuted_fields);
696
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
697
my_ok(thd, (ulong) thd->row_count_func, id, buff);
696
session->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
697
session->abort_on_warning= 0;
698
return((error >= 0 || session->is_error()) ? 1 : 0);
699
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
700
thd->abort_on_warning= 0;
701
return((error >= 0 || thd->is_error()) ? 1 : 0);
702
free_underlaid_joins(session, select_lex);
705
free_underlaid_joins(thd, select_lex);
703
706
if (table->key_read)
705
708
table->key_read=0;
706
709
table->file->extra(HA_EXTRA_NO_KEYREAD);
708
session->abort_on_warning= 0;
711
thd->abort_on_warning= 0;
711
714
DRIZZLE_UPDATE_END();
730
bool mysql_prepare_update(Session *session, TableList *table_list,
731
Item **conds, uint32_t order_num, order_st *order)
733
bool mysql_prepare_update(THD *thd, TableList *table_list,
734
Item **conds, uint order_num, order_st *order)
733
736
List<Item> all_fields;
734
SELECT_LEX *select_lex= &session->lex->select_lex;
737
SELECT_LEX *select_lex= &thd->lex->select_lex;
737
740
Statement-based replication of UPDATE ... LIMIT is not safe as order of
741
744
is present. However it may confuse users to see very similiar statements
742
745
replicated differently.
744
if (session->lex->current_select->select_limit)
747
if (thd->lex->current_select->select_limit)
746
session->lex->set_stmt_unsafe();
747
session->set_current_stmt_binlog_row_based_if_mixed();
749
thd->lex->set_stmt_unsafe();
750
thd->set_current_stmt_binlog_row_based_if_mixed();
750
session->lex->allow_sum_func= 0;
753
thd->lex->allow_sum_func= 0;
752
if (setup_tables_and_check_access(session, &select_lex->context,
755
if (setup_tables_and_check_access(thd, &select_lex->context,
753
756
&select_lex->top_join_list,
755
758
&select_lex->leaf_tables,
757
setup_conds(session, table_list, select_lex->leaf_tables, conds) ||
758
select_lex->setup_ref_array(session, order_num) ||
759
setup_order(session, select_lex->ref_pointer_array,
760
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
761
select_lex->setup_ref_array(thd, order_num) ||
762
setup_order(thd, select_lex->ref_pointer_array,
760
763
table_list, all_fields, all_fields, order))
763
766
/* Check that we are not using table that we are updating in a sub select */
765
768
TableList *duplicate;
766
if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
769
if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
768
771
update_non_unique_table_error(table_list, "UPDATE", duplicate);
769
772
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
820
823
counter else junk will be assigned here, but then replaced with real
821
824
count in open_tables()
823
uint32_t table_count= lex->table_count;
824
const bool using_lock_tables= session->locked_tables != 0;
825
bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
826
uint table_count= lex->table_count;
827
const bool using_lock_tables= thd->locked_tables != 0;
828
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
826
829
bool need_reopen= false;
829
832
/* following need for prepared statements, to run next time multi-update */
830
session->lex->sql_command= SQLCOM_UPDATE_MULTI;
833
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
834
837
/* open tables and create derived ones, but do not lock and fill them */
835
838
if (((original_multiupdate || need_reopen) &&
836
open_tables(session, &table_list, &table_count, 0)) ||
839
open_tables(thd, &table_list, &table_count, 0)) ||
837
840
mysql_handle_derived(lex, &mysql_derived_prepare))
842
845
call in setup_tables()).
845
if (setup_tables_and_check_access(session, &lex->select_lex.context,
848
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
846
849
&lex->select_lex.top_join_list,
848
851
&lex->select_lex.leaf_tables, false))
851
if (setup_fields_with_no_wrap(session, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
854
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
854
if (update_view && check_fields(session, *fields))
857
if (update_view && check_fields(thd, *fields))
972
975
if (!(result= new multi_update(table_list,
973
session->lex->select_lex.leaf_tables,
976
thd->lex->select_lex.leaf_tables,
975
978
handle_duplicates, ignore)))
978
session->abort_on_warning= true;
981
thd->abort_on_warning= true;
980
983
List<Item> total_list;
981
res= mysql_select(session, &select_lex->ref_pointer_array,
984
res= mysql_select(thd, &select_lex->ref_pointer_array,
982
985
table_list, select_lex->with_wild,
984
987
conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
1025
1028
Item_field *item;
1026
1029
List_iterator_fast<Item> field_it(*fields);
1027
1030
List_iterator_fast<Item> value_it(*values);
1028
uint32_t i, max_fields;
1029
uint32_t leaf_table_count= 0;
1032
uint leaf_table_count= 0;
1031
session->count_cuted_fields= CHECK_FIELD_WARN;
1032
session->cuted_fields=0L;
1033
session->set_proc_info("updating main table");
1034
thd->count_cuted_fields= CHECK_FIELD_WARN;
1035
thd->cuted_fields=0L;
1036
thd_proc_info(thd, "updating main table");
1035
1038
tables_to_update= get_table_map(fields);
1078
1081
table_count= update.elements;
1079
1082
update_tables= (TableList*) update.first;
1081
tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
1082
tmp_table_param = (TMP_TABLE_PARAM*) session->calloc(sizeof(TMP_TABLE_PARAM) *
1084
tmp_tables = (Table**) thd->calloc(sizeof(Table *) * table_count);
1085
tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
1084
fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1086
values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1088
if (session->is_fatal_error)
1087
fields_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1089
values_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1091
if (thd->is_fatal_error)
1090
1093
for (i=0 ; i < table_count ; i++)
1092
1095
fields_for_table[i]= new List_item;
1093
1096
values_for_table[i]= new List_item;
1095
if (session->is_fatal_error)
1098
if (thd->is_fatal_error)
1098
1101
/* Split fields into fields_for_table[] and values_by_table[] */
1149
1152
1 Safe to update
1152
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
1155
static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
1153
1156
TableList *table_ref, TableList *all_tables)
1155
1158
Table *table= join_tab->table;
1156
if (unique_table(session, table_ref, all_tables, 0))
1159
if (unique_table(thd, table_ref, all_tables, 0))
1158
1161
switch (join_tab->type) {
1159
1162
case JT_SYSTEM:
1297
1300
if (tmp_tables)
1299
for (uint32_t cnt = 0; cnt < table_count; cnt++)
1302
for (uint cnt = 0; cnt < table_count; cnt++)
1301
1304
if (tmp_tables[cnt])
1303
tmp_tables[cnt]->free_tmp_table(session);
1306
tmp_tables[cnt]->free_tmp_table(thd);
1304
1307
tmp_table_param[cnt].cleanup();
1308
1311
if (copy_field)
1309
1312
delete [] copy_field;
1310
session->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1313
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1311
1314
assert(trans_safe || !updated ||
1312
session->transaction.all.modified_non_trans_table);
1315
thd->transaction.all.modified_non_trans_table);
1316
bool multi_update::send_data(List<Item> &)
1319
bool multi_update::send_data(List<Item> ¬_used_values __attribute__((unused)))
1318
1321
TableList *cur_table;
1320
1323
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1322
1325
Table *table= cur_table->table;
1323
uint32_t offset= cur_table->shared;
1326
uint offset= cur_table->shared;
1325
1328
Check if we are using outer join and we didn't find the row
1326
1329
or if we have already updated this row in the previous call to this
1493
1496
if (mysql_bin_log.is_open())
1496
Session::killed status might not have been set ON at time of an error
1499
THD::killed status might not have been set ON at time of an error
1497
1500
got caught and if happens later the killed error is written
1498
1501
into repl event.
1500
session->binlog_query(Session::ROW_QUERY_TYPE,
1501
session->query, session->query_length,
1503
thd->binlog_query(THD::ROW_QUERY_TYPE,
1504
thd->query, thd->query_length,
1502
1505
transactional_tables, false);
1504
session->transaction.all.modified_non_trans_table= true;
1507
thd->transaction.all.modified_non_trans_table= true;
1506
assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
1509
assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
1693
1696
assert(trans_safe || !updated ||
1694
session->transaction.stmt.modified_non_trans_table);
1695
if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1697
thd->transaction.stmt.modified_non_trans_table);
1698
if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
1697
1700
if (mysql_bin_log.is_open())
1699
1702
if (local_error == 0)
1700
session->clear_error();
1701
if (session->binlog_query(Session::ROW_QUERY_TYPE,
1702
session->query, session->query_length,
1704
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
1705
thd->query, thd->query_length,
1703
1706
transactional_tables, false, killed_status) &&
1706
1709
local_error= 1; // Rollback update
1709
if (session->transaction.stmt.modified_non_trans_table)
1710
session->transaction.all.modified_non_trans_table= true;
1712
if (thd->transaction.stmt.modified_non_trans_table)
1713
thd->transaction.all.modified_non_trans_table= true;
1712
1715
if (local_error != 0)
1713
1716
error_handled= true; // to force early leave from ::send_error()
1723
id= session->arg_of_last_insert_id_function ?
1724
session->first_successful_insert_id_in_prev_stmt : 0;
1726
id= thd->arg_of_last_insert_id_function ?
1727
thd->first_successful_insert_id_in_prev_stmt : 0;
1725
1728
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
1726
(ulong) session->cuted_fields);
1727
session->row_count_func=
1728
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1729
::my_ok(session, (ulong) session->row_count_func, id, buff);
1729
(ulong) thd->cuted_fields);
1730
thd->row_count_func=
1731
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1732
::my_ok(thd, (ulong) thd->row_count_func, id, buff);