182
if (open_tables(thd, &table_list, &table_count, 0))
182
if (open_tables(session, &table_list, &table_count, 0))
185
if (!lock_tables(thd, table_list, table_count, &need_reopen))
185
if (!lock_tables(session, table_list, table_count, &need_reopen))
187
187
if (!need_reopen)
189
close_tables_for_reopen(thd, &table_list);
189
close_tables_for_reopen(session, &table_list);
192
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
193
(thd->fill_derived_tables() &&
194
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
192
if (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
193
(session->fill_derived_tables() &&
194
mysql_handle_derived(session->lex, &mysql_derived_filling)))
197
197
DRIZZLE_UPDATE_START();
198
thd->set_proc_info("init");
198
session->set_proc_info("init");
199
199
table= table_list->table;
201
201
/* Calculate "table->covering_keys" based on the WHERE */
202
202
table->covering_keys= table->s->keys_in_use;
203
203
table->quick_keys.clear_all();
205
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
205
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
208
208
old_covering_keys= table->covering_keys; // Keys used in WHERE
209
209
/* Check the fields we are going to modify */
210
if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
210
if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
211
211
goto abort; /* purecov: inspected */
212
212
if (table->timestamp_field)
227
if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
227
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
229
free_underlaid_joins(thd, select_lex);
229
free_underlaid_joins(session, select_lex);
230
230
goto abort; /* purecov: inspected */
233
233
if (select_lex->inner_refs_list.elements &&
234
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
234
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
236
236
DRIZZLE_UPDATE_END();
264
264
select= make_select(table, 0, 0, conds, 0, &error);
265
265
if (error || !limit ||
266
(select && select->check_quick(thd, safe_update, limit)))
266
(select && select->check_quick(session, safe_update, limit)))
269
free_underlaid_joins(thd, select_lex);
269
free_underlaid_joins(session, select_lex);
271
271
goto abort; // Error in where
272
272
DRIZZLE_UPDATE_END();
273
my_ok(thd); // No matching records
273
my_ok(session); // No matching records
276
276
if (!select && limit != HA_POS_ERROR)
341
341
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
342
342
MYF(MY_FAE | MY_ZEROFILL));
343
343
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
344
(table->sort.found_records= filesort(thd, table, sortorder, length,
344
(table->sort.found_records= filesort(session, table, sortorder, length,
345
345
select, limit, 1,
387
387
if (used_index == MAX_KEY || (select && select->quick))
388
init_read_record(&info,thd,table,select,0,1);
388
init_read_record(&info,session,table,select,0,1);
390
init_read_record_idx(&info, thd, table, 1, used_index);
390
init_read_record_idx(&info, session, table, 1, used_index);
392
thd->set_proc_info("Searching rows for update");
392
session->set_proc_info("Searching rows for update");
393
393
ha_rows tmp_limit= limit;
395
while (!(error=info.read_record(&info)) && !thd->killed)
395
while (!(error=info.read_record(&info)) && !session->killed)
397
397
if (!(select && select->skip_record()))
451
451
if (select && select->quick && select->quick->reset())
453
453
table->file->try_semi_consistent_read(1);
454
init_read_record(&info,thd,table,select,0,1);
454
init_read_record(&info,session,table,select,0,1);
456
456
updated= found= 0;
457
457
/* Generate an error when trying to set a NOT NULL field to NULL. */
458
thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
458
session->count_cuted_fields= ignore ? CHECK_FIELD_WARN
459
459
: CHECK_FIELD_ERROR_FOR_NULL;
460
thd->cuted_fields=0L;
461
thd->set_proc_info("Updating");
460
session->cuted_fields=0L;
461
session->set_proc_info("Updating");
463
463
transactional_table= table->file->has_transactions();
464
thd->abort_on_warning= test(!ignore);
464
session->abort_on_warning= test(!ignore);
465
465
will_batch= !table->file->start_bulk_update();
488
488
continue; /* repeat the read of the same row if it still exists */
490
490
store_record(table,record[1]);
491
if (fill_record(thd, fields, values, 0))
491
if (fill_record(session, fields, values, 0))
492
492
break; /* purecov: inspected */
662
662
Sometimes we want to binlog even if we updated no rows, in case user used
663
663
it to be sure master and slave are in same state.
665
if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
665
if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
667
667
if (mysql_bin_log.is_open())
671
if (thd->binlog_query(Session::ROW_QUERY_TYPE,
672
thd->query, thd->query_length,
670
session->clear_error();
671
if (session->binlog_query(Session::ROW_QUERY_TYPE,
672
session->query, session->query_length,
673
673
transactional_table, false, killed_status) &&
674
674
transactional_table)
676
676
error=1; // Rollback update
679
if (thd->transaction.stmt.modified_non_trans_table)
680
thd->transaction.all.modified_non_trans_table= true;
679
if (session->transaction.stmt.modified_non_trans_table)
680
session->transaction.all.modified_non_trans_table= true;
682
assert(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
683
free_underlaid_joins(thd, select_lex);
682
assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
683
free_underlaid_joins(session, select_lex);
685
685
/* If LAST_INSERT_ID(X) was used, report X */
686
id= thd->arg_of_last_insert_id_function ?
687
thd->first_successful_insert_id_in_prev_stmt : 0;
686
id= session->arg_of_last_insert_id_function ?
687
session->first_successful_insert_id_in_prev_stmt : 0;
689
689
DRIZZLE_UPDATE_END();
692
692
char buff[STRING_BUFFER_USUAL_SIZE];
693
693
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
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);
694
(ulong) session->cuted_fields);
695
session->row_count_func=
696
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
697
my_ok(session, (ulong) session->row_count_func, id, buff);
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);
699
session->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
700
session->abort_on_warning= 0;
701
return((error >= 0 || session->is_error()) ? 1 : 0);
705
free_underlaid_joins(thd, select_lex);
705
free_underlaid_joins(session, select_lex);
706
706
if (table->key_read)
708
708
table->key_read=0;
709
709
table->file->extra(HA_EXTRA_NO_KEYREAD);
711
thd->abort_on_warning= 0;
711
session->abort_on_warning= 0;
714
714
DRIZZLE_UPDATE_END();
733
bool mysql_prepare_update(Session *thd, TableList *table_list,
733
bool mysql_prepare_update(Session *session, TableList *table_list,
734
734
Item **conds, uint32_t order_num, order_st *order)
736
736
List<Item> all_fields;
737
SELECT_LEX *select_lex= &thd->lex->select_lex;
737
SELECT_LEX *select_lex= &session->lex->select_lex;
740
740
Statement-based replication of UPDATE ... LIMIT is not safe as order of
744
744
is present. However it may confuse users to see very similiar statements
745
745
replicated differently.
747
if (thd->lex->current_select->select_limit)
747
if (session->lex->current_select->select_limit)
749
thd->lex->set_stmt_unsafe();
750
thd->set_current_stmt_binlog_row_based_if_mixed();
749
session->lex->set_stmt_unsafe();
750
session->set_current_stmt_binlog_row_based_if_mixed();
753
thd->lex->allow_sum_func= 0;
753
session->lex->allow_sum_func= 0;
755
if (setup_tables_and_check_access(thd, &select_lex->context,
755
if (setup_tables_and_check_access(session, &select_lex->context,
756
756
&select_lex->top_join_list,
758
758
&select_lex->leaf_tables,
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
setup_conds(session, table_list, select_lex->leaf_tables, conds) ||
761
select_lex->setup_ref_array(session, order_num) ||
762
setup_order(session, select_lex->ref_pointer_array,
763
763
table_list, all_fields, all_fields, order))
766
766
/* Check that we are not using table that we are updating in a sub select */
768
768
TableList *duplicate;
769
if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
769
if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
771
771
update_non_unique_table_error(table_list, "UPDATE", duplicate);
772
772
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
824
824
count in open_tables()
826
826
uint32_t 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);
827
const bool using_lock_tables= session->locked_tables != 0;
828
bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
829
829
bool need_reopen= false;
832
832
/* following need for prepared statements, to run next time multi-update */
833
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
833
session->lex->sql_command= SQLCOM_UPDATE_MULTI;
837
837
/* open tables and create derived ones, but do not lock and fill them */
838
838
if (((original_multiupdate || need_reopen) &&
839
open_tables(thd, &table_list, &table_count, 0)) ||
839
open_tables(session, &table_list, &table_count, 0)) ||
840
840
mysql_handle_derived(lex, &mysql_derived_prepare))
845
845
call in setup_tables()).
848
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
848
if (setup_tables_and_check_access(session, &lex->select_lex.context,
849
849
&lex->select_lex.top_join_list,
851
851
&lex->select_lex.leaf_tables, false))
854
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
854
if (setup_fields_with_no_wrap(session, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
857
if (update_view && check_fields(thd, *fields))
857
if (update_view && check_fields(session, *fields))
975
975
if (!(result= new multi_update(table_list,
976
thd->lex->select_lex.leaf_tables,
976
session->lex->select_lex.leaf_tables,
978
978
handle_duplicates, ignore)))
981
thd->abort_on_warning= true;
981
session->abort_on_warning= true;
983
983
List<Item> total_list;
984
res= mysql_select(thd, &select_lex->ref_pointer_array,
984
res= mysql_select(session, &select_lex->ref_pointer_array,
985
985
table_list, select_lex->with_wild,
987
987
conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
1081
1081
table_count= update.elements;
1082
1082
update_tables= (TableList*) update.first;
1084
tmp_tables = (Table**) thd->calloc(sizeof(Table *) * table_count);
1085
tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
1084
tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
1085
tmp_table_param = (TMP_TABLE_PARAM*) session->calloc(sizeof(TMP_TABLE_PARAM) *
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)
1087
fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1089
values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1091
if (session->is_fatal_error)
1093
1093
for (i=0 ; i < table_count ; i++)
1095
1095
fields_for_table[i]= new List_item;
1096
1096
values_for_table[i]= new List_item;
1098
if (thd->is_fatal_error)
1098
if (session->is_fatal_error)
1101
1101
/* Split fields into fields_for_table[] and values_by_table[] */
1152
1152
1 Safe to update
1155
static bool safe_update_on_fly(Session *thd, JOIN_TAB *join_tab,
1155
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
1156
1156
TableList *table_ref, TableList *all_tables)
1158
1158
Table *table= join_tab->table;
1159
if (unique_table(thd, table_ref, all_tables, 0))
1159
if (unique_table(session, table_ref, all_tables, 0))
1161
1161
switch (join_tab->type) {
1162
1162
case JT_SYSTEM:
1219
1219
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1220
1220
if (table == main_table) // First table in join
1222
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
1222
if (safe_update_on_fly(session, join->join_tab, table_ref, all_tables))
1224
1224
table_to_update= main_table; // Update table on the fly
1273
1273
tmp_param->field_count=temp_fields.elements;
1274
1274
tmp_param->group_parts=1;
1275
1275
tmp_param->group_length= table->file->ref_length;
1276
if (!(tmp_tables[cnt]=create_tmp_table(thd,
1276
if (!(tmp_tables[cnt]=create_tmp_table(session,
1279
1279
(order_st*) &group, 0, 0,
1304
1304
if (tmp_tables[cnt])
1306
tmp_tables[cnt]->free_tmp_table(thd);
1306
tmp_tables[cnt]->free_tmp_table(session);
1307
1307
tmp_table_param[cnt].cleanup();
1311
1311
if (copy_field)
1312
1312
delete [] copy_field;
1313
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1313
session->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1314
1314
assert(trans_safe || !updated ||
1315
thd->transaction.all.modified_non_trans_table);
1315
session->transaction.all.modified_non_trans_table);
1440
1440
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
1443
create_myisam_from_heap(thd, tmp_table,
1443
create_myisam_from_heap(session, tmp_table,
1444
1444
tmp_table_param[offset].start_recinfo,
1445
1445
&tmp_table_param[offset].recinfo,
1500
1500
got caught and if happens later the killed error is written
1501
1501
into repl event.
1503
thd->binlog_query(Session::ROW_QUERY_TYPE,
1504
thd->query, thd->query_length,
1503
session->binlog_query(Session::ROW_QUERY_TYPE,
1504
session->query, session->query_length,
1505
1505
transactional_tables, false);
1507
thd->transaction.all.modified_non_trans_table= true;
1507
session->transaction.all.modified_non_trans_table= true;
1509
assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
1509
assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
1696
1696
assert(trans_safe || !updated ||
1697
thd->transaction.stmt.modified_non_trans_table);
1698
if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
1697
session->transaction.stmt.modified_non_trans_table);
1698
if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1700
1700
if (mysql_bin_log.is_open())
1702
1702
if (local_error == 0)
1704
if (thd->binlog_query(Session::ROW_QUERY_TYPE,
1705
thd->query, thd->query_length,
1703
session->clear_error();
1704
if (session->binlog_query(Session::ROW_QUERY_TYPE,
1705
session->query, session->query_length,
1706
1706
transactional_tables, false, killed_status) &&
1709
1709
local_error= 1; // Rollback update
1712
if (thd->transaction.stmt.modified_non_trans_table)
1713
thd->transaction.all.modified_non_trans_table= true;
1712
if (session->transaction.stmt.modified_non_trans_table)
1713
session->transaction.all.modified_non_trans_table= true;
1715
1715
if (local_error != 0)
1716
1716
error_handled= true; // to force early leave from ::send_error()
1726
id= thd->arg_of_last_insert_id_function ?
1727
thd->first_successful_insert_id_in_prev_stmt : 0;
1726
id= session->arg_of_last_insert_id_function ?
1727
session->first_successful_insert_id_in_prev_stmt : 0;
1728
1728
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
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);
1729
(ulong) session->cuted_fields);
1730
session->row_count_func=
1731
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1732
::my_ok(session, (ulong) session->row_count_func, id, buff);