18
18
Single table and multi table updates of tables.
19
19
Multi-table updates were introduced by Sinisa & Monty
21
#include <drizzled/server_includes.h>
22
#include <drizzled/sql_select.h>
23
#include <drizzled/error.h>
24
#include <drizzled/probes.h>
25
#include <drizzled/sql_base.h>
26
#include <drizzled/field/timestamp.h>
22
#include "mysql_priv.h"
23
#include "sql_select.h"
25
/* Return 0 if row hasn't changed */
27
bool compare_record(TABLE *table)
29
if (table->s->blob_fields + table->s->varchar_fields == 0)
30
return cmp_record(table,record[1]);
31
/* Compare null bits */
32
if (memcmp(table->null_flags,
33
table->null_flags+table->s->rec_buff_length,
34
table->s->null_bytes))
35
return true; // Diff in NULL value
36
/* Compare updated fields */
37
for (Field **ptr= table->field ; *ptr ; ptr++)
39
if (bitmap_is_set(table->write_set, (*ptr)->field_index) &&
40
(*ptr)->cmp_binary_offset(table->s->rec_buff_length))
29
48
check that all fields are real fields
33
session thread handler
34
53
items Items for check
154
int mysql_update(Session *session, TableList *table_list,
155
List<Item> &fields, List<Item> &values, COND *conds,
156
uint32_t order_num, order_st *order,
157
ha_rows limit, enum enum_duplicates,
173
int mysql_update(THD *thd,
174
TABLE_LIST *table_list,
178
uint order_num, ORDER *order,
180
enum enum_duplicates handle_duplicates __attribute__((__unused__)),
160
183
bool using_limit= limit != HA_POS_ERROR;
161
bool safe_update= test(session->options & OPTION_SAFE_UPDATES);
184
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
162
185
bool used_key_is_modified, transactional_table, will_batch;
163
186
bool can_compare_record;
164
187
int error, loc_error;
165
188
uint used_index= MAX_KEY, dup_key_found;
166
189
bool need_sort= true;
167
uint32_t table_count= 0;
168
191
ha_rows updated, found;
169
192
key_map old_covering_keys;
171
194
SQL_SELECT *select;
172
195
READ_RECORD info;
173
SELECT_LEX *select_lex= &session->lex->select_lex;
196
SELECT_LEX *select_lex= &thd->lex->select_lex;
174
197
bool need_reopen;
176
199
List<Item> all_fields;
177
Session::killed_state killed_status= Session::NOT_KILLED;
200
THD::killed_state killed_status= THD::NOT_KILLED;
181
if (open_tables(session, &table_list, &table_count, 0))
204
if (open_tables(thd, &table_list, &table_count, 0))
184
if (!lock_tables(session, table_list, table_count, &need_reopen))
207
if (!lock_tables(thd, table_list, table_count, &need_reopen))
186
209
if (!need_reopen)
188
close_tables_for_reopen(session, &table_list);
211
close_tables_for_reopen(thd, &table_list);
191
if (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
192
(session->fill_derived_tables() &&
193
mysql_handle_derived(session->lex, &mysql_derived_filling)))
214
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
215
(thd->fill_derived_tables() &&
216
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
196
DRIZZLE_UPDATE_START();
197
session->set_proc_info("init");
219
MYSQL_UPDATE_START();
220
thd_proc_info(thd, "init");
198
221
table= table_list->table;
200
223
/* Calculate "table->covering_keys" based on the WHERE */
201
224
table->covering_keys= table->s->keys_in_use;
202
225
table->quick_keys.clear_all();
204
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
227
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
207
230
old_covering_keys= table->covering_keys; // Keys used in WHERE
208
231
/* Check the fields we are going to modify */
209
if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
232
if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
210
233
goto abort; /* purecov: inspected */
211
234
if (table->timestamp_field)
226
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
249
if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
228
free_underlaid_joins(session, select_lex);
251
free_underlaid_joins(thd, select_lex);
229
252
goto abort; /* purecov: inspected */
232
255
if (select_lex->inner_refs_list.elements &&
233
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
256
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
235
DRIZZLE_UPDATE_END();
241
264
Item::cond_result cond_value;
242
conds= remove_eq_conds(session, conds, &cond_value);
265
conds= remove_eq_conds(thd, conds, &cond_value);
243
266
if (cond_value == Item::COND_FALSE)
244
267
limit= 0; // Impossible WHERE
263
286
select= make_select(table, 0, 0, conds, 0, &error);
264
287
if (error || !limit ||
265
(select && select->check_quick(session, safe_update, limit)))
288
(select && select->check_quick(thd, safe_update, limit)))
268
free_underlaid_joins(session, select_lex);
291
free_underlaid_joins(thd, select_lex);
270
293
goto abort; // Error in where
271
DRIZZLE_UPDATE_END();
272
my_ok(session); // No matching records
295
my_ok(thd); // No matching records
275
298
if (!select && limit != HA_POS_ERROR)
329
352
if (order && (need_sort || used_key_is_modified))
332
Doing an order_st BY; Let filesort find and sort the rows we are going
355
Doing an ORDER BY; Let filesort find and sort the rows we are going
334
357
NOTE: filesort will call table->prepare_for_position()
337
360
SORT_FIELD *sortorder;
338
361
ha_rows examined_rows;
340
table->sort.io_cache = new IO_CACHE;
341
memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
363
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
364
MYF(MY_FAE | MY_ZEROFILL));
343
365
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
344
(table->sort.found_records= filesort(session, table, sortorder, length,
366
(table->sort.found_records= filesort(thd, table, sortorder, length,
345
367
select, limit, 1,
387
409
if (used_index == MAX_KEY || (select && select->quick))
388
init_read_record(&info,session,table,select,0,1);
410
init_read_record(&info,thd,table,select,0,1);
390
init_read_record_idx(&info, session, table, 1, used_index);
412
init_read_record_idx(&info, thd, table, 1, used_index);
392
session->set_proc_info("Searching rows for update");
414
thd_proc_info(thd, "Searching rows for update");
393
415
ha_rows tmp_limit= limit;
395
while (!(error=info.read_record(&info)) && !session->killed)
417
while (!(error=info.read_record(&info)) && !thd->killed)
397
419
if (!(select && select->skip_record()))
449
471
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
451
473
if (select && select->quick && select->quick->reset())
453
475
table->file->try_semi_consistent_read(1);
454
init_read_record(&info,session,table,select,0,1);
476
init_read_record(&info,thd,table,select,0,1);
456
478
updated= found= 0;
457
479
/* Generate an error when trying to set a NOT NULL field to NULL. */
458
session->count_cuted_fields= ignore ? CHECK_FIELD_WARN
480
thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
459
481
: CHECK_FIELD_ERROR_FOR_NULL;
460
session->cuted_fields=0L;
461
session->set_proc_info("Updating");
482
thd->cuted_fields=0L;
483
thd_proc_info(thd, "Updating");
463
485
transactional_table= table->file->has_transactions();
464
session->abort_on_warning= test(!ignore);
486
thd->abort_on_warning= test(!ignore &&
487
(thd->variables.sql_mode &
488
(MODE_STRICT_TRANS_TABLES |
489
MODE_STRICT_ALL_TABLES)));
465
490
will_batch= !table->file->start_bulk_update();
488
513
continue; /* repeat the read of the same row if it still exists */
490
515
store_record(table,record[1]);
491
if (fill_record(session, fields, values, 0))
516
if (fill_record(thd, fields, values, 0))
492
517
break; /* purecov: inspected */
496
if (!can_compare_record || table->compare_record())
521
if (!can_compare_record || compare_record(table))
662
687
Sometimes we want to binlog even if we updated no rows, in case user used
663
688
it to be sure master and slave are in same state.
665
if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
690
if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
667
if (session->transaction.stmt.modified_non_trans_table)
668
session->transaction.all.modified_non_trans_table= true;
692
if (mysql_bin_log.is_open())
696
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
697
thd->query, thd->query_length,
698
transactional_table, false, killed_status) &&
701
error=1; // Rollback update
704
if (thd->transaction.stmt.modified_non_trans_table)
705
thd->transaction.all.modified_non_trans_table= true;
670
assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
671
free_underlaid_joins(session, select_lex);
707
assert(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
708
free_underlaid_joins(thd, select_lex);
673
710
/* If LAST_INSERT_ID(X) was used, report X */
674
id= session->arg_of_last_insert_id_function ?
675
session->first_successful_insert_id_in_prev_stmt : 0;
711
id= thd->arg_of_last_insert_id_function ?
712
thd->first_successful_insert_id_in_prev_stmt : 0;
677
DRIZZLE_UPDATE_END();
680
717
char buff[STRING_BUFFER_USUAL_SIZE];
681
718
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
682
(ulong) session->cuted_fields);
683
session->row_count_func=
684
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
685
my_ok(session, (ulong) session->row_count_func, id, buff);
719
(ulong) thd->cuted_fields);
721
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
722
my_ok(thd, (ulong) thd->row_count_func, id, buff);
687
session->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
688
session->abort_on_warning= 0;
689
return((error >= 0 || session->is_error()) ? 1 : 0);
724
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
725
thd->abort_on_warning= 0;
726
return((error >= 0 || thd->is_error()) ? 1 : 0);
693
free_underlaid_joins(session, select_lex);
730
free_underlaid_joins(thd, select_lex);
694
731
if (table->key_read)
696
733
table->key_read=0;
697
734
table->file->extra(HA_EXTRA_NO_KEYREAD);
699
session->abort_on_warning= 0;
736
thd->abort_on_warning= 0;
702
DRIZZLE_UPDATE_END();
710
747
mysql_prepare_update()
711
session - thread handler
712
749
table_list - global/local table list
713
750
conds - conditions
714
order_num - number of order_st BY list entries
715
order - order_st BY clause list
751
order_num - number of ORDER BY list entries
752
order - ORDER BY clause list
721
bool mysql_prepare_update(Session *session, TableList *table_list,
722
Item **conds, uint32_t order_num, order_st *order)
758
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
759
Item **conds, uint order_num, ORDER *order)
724
762
List<Item> all_fields;
725
SELECT_LEX *select_lex= &session->lex->select_lex;
727
session->lex->allow_sum_func= 0;
729
if (setup_tables_and_check_access(session, &select_lex->context,
763
SELECT_LEX *select_lex= &thd->lex->select_lex;
766
Statement-based replication of UPDATE ... LIMIT is not safe as order of
767
rows is not defined, so in mixed mode we go to row-based.
769
Note that we may consider a statement as safe if ORDER BY primary_key
770
is present. However it may confuse users to see very similiar statements
771
replicated differently.
773
if (thd->lex->current_select->select_limit)
775
thd->lex->set_stmt_unsafe();
776
thd->set_current_stmt_binlog_row_based_if_mixed();
779
thd->lex->allow_sum_func= 0;
781
if (setup_tables_and_check_access(thd, &select_lex->context,
730
782
&select_lex->top_join_list,
732
784
&select_lex->leaf_tables,
734
setup_conds(session, table_list, select_lex->leaf_tables, conds) ||
735
select_lex->setup_ref_array(session, order_num) ||
736
setup_order(session, select_lex->ref_pointer_array,
786
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
787
select_lex->setup_ref_array(thd, order_num) ||
788
setup_order(thd, select_lex->ref_pointer_array,
737
789
table_list, all_fields, all_fields, order))
740
792
/* Check that we are not using table that we are updating in a sub select */
742
TableList *duplicate;
743
if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
794
TABLE_LIST *duplicate;
795
if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
745
797
update_non_unique_table_error(table_list, "UPDATE", duplicate);
746
798
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
802
select_lex->fix_prepare_information(thd, conds, &fake_conds);
755
807
/***************************************************************************
756
Update multiple tables from join
808
Update multiple tables from join
757
809
***************************************************************************/
797
849
counter else junk will be assigned here, but then replaced with real
798
850
count in open_tables()
800
uint32_t table_count= lex->table_count;
801
const bool using_lock_tables= session->locked_tables != 0;
802
bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
852
uint table_count= lex->table_count;
853
const bool using_lock_tables= thd->locked_tables != 0;
854
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
803
855
bool need_reopen= false;
806
858
/* following need for prepared statements, to run next time multi-update */
807
session->lex->sql_command= SQLCOM_UPDATE_MULTI;
859
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
811
863
/* open tables and create derived ones, but do not lock and fill them */
812
864
if (((original_multiupdate || need_reopen) &&
813
open_tables(session, &table_list, &table_count, 0)) ||
865
open_tables(thd, &table_list, &table_count, 0)) ||
814
866
mysql_handle_derived(lex, &mysql_derived_prepare))
819
871
call in setup_tables()).
822
if (setup_tables_and_check_access(session, &lex->select_lex.context,
874
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
823
875
&lex->select_lex.top_join_list,
825
877
&lex->select_lex.leaf_tables, false))
828
if (setup_fields_with_no_wrap(session, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
880
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
831
if (update_view && check_fields(session, *fields))
883
if (update_view && check_fields(thd, *fields))
864
916
correct order of statements. Otherwise, we use a TL_READ lock to
865
917
improve performance.
867
tl->lock_type= TL_READ;
919
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
869
/* Update Table::lock_type accordingly. */
921
/* Update TABLE::lock_type accordingly. */
870
922
if (!tl->placeholder() && !using_lock_tables)
871
923
tl->table->reginfo.lock_type= tl->lock_type;
875
927
/* now lock and fill tables */
876
if (lock_tables(session, table_list, table_count, &need_reopen))
928
if (lock_tables(thd, table_list, table_count, &need_reopen))
878
930
if (!need_reopen)
934
986
Setup multi-update handling and call SELECT to do the join
937
bool mysql_multi_update(Session *session,
938
TableList *table_list,
989
bool mysql_multi_update(THD *thd,
990
TABLE_LIST *table_list,
939
991
List<Item> *fields,
940
992
List<Item> *values,
943
995
enum enum_duplicates handle_duplicates, bool ignore,
944
996
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
946
998
multi_update *result;
949
1001
if (!(result= new multi_update(table_list,
950
session->lex->select_lex.leaf_tables,
1002
thd->lex->select_lex.leaf_tables,
952
1004
handle_duplicates, ignore)))
955
session->abort_on_warning= true;
1007
thd->abort_on_warning= test(thd->variables.sql_mode &
1008
(MODE_STRICT_TRANS_TABLES |
1009
MODE_STRICT_ALL_TABLES));
957
1011
List<Item> total_list;
958
res= mysql_select(session, &select_lex->ref_pointer_array,
1012
res= mysql_select(thd, &select_lex->ref_pointer_array,
959
1013
table_list, select_lex->with_wild,
961
conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
1015
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
963
1017
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
964
1018
OPTION_SETUP_TABLES_DONE,
965
1019
result, unit, select_lex);
966
res|= session->is_error();
1020
res|= thd->is_error();
967
1021
if (unlikely(res))
969
1023
/* If we had a another error reported earlier then this will be ignored */
993
1047
Connect fields with tables and create list of tables that are updated
996
int multi_update::prepare(List<Item> &,
1050
int multi_update::prepare(List<Item> ¬_used_values __attribute__((__unused__)),
1051
SELECT_LEX_UNIT *lex_unit __attribute__((__unused__)))
999
TableList *table_ref;
1053
TABLE_LIST *table_ref;
1000
1054
SQL_LIST update;
1001
1055
table_map tables_to_update;
1002
1056
Item_field *item;
1003
1057
List_iterator_fast<Item> field_it(*fields);
1004
1058
List_iterator_fast<Item> value_it(*values);
1005
uint32_t i, max_fields;
1006
uint32_t leaf_table_count= 0;
1008
session->count_cuted_fields= CHECK_FIELD_WARN;
1009
session->cuted_fields=0L;
1010
session->set_proc_info("updating main table");
1060
uint leaf_table_count= 0;
1062
thd->count_cuted_fields= CHECK_FIELD_WARN;
1063
thd->cuted_fields=0L;
1064
thd_proc_info(thd, "updating main table");
1012
1066
tables_to_update= get_table_map(fields);
1035
1089
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1037
1091
/* TODO: add support of view of join support */
1038
Table *table=table_ref->table;
1092
TABLE *table=table_ref->table;
1039
1093
leaf_table_count++;
1040
1094
if (tables_to_update & table->map)
1042
TableList *tl= (TableList*) session->memdup((char*) table_ref,
1096
TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
1046
update.link_in_list((unsigned char*) tl, (unsigned char**) &tl->next_local);
1100
update.link_in_list((uchar*) tl, (uchar**) &tl->next_local);
1047
1101
tl->shared= table_count++;
1048
1102
table->no_keyread=1;
1049
1103
table->covering_keys.clear_all();
1055
1109
table_count= update.elements;
1056
update_tables= (TableList*) update.first;
1110
update_tables= (TABLE_LIST*) update.first;
1058
tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
1059
tmp_table_param = (TMP_TABLE_PARAM*) session->calloc(sizeof(TMP_TABLE_PARAM) *
1112
tmp_tables = (TABLE**) thd->calloc(sizeof(TABLE *) * table_count);
1113
tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
1061
fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1063
values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1065
if (session->is_fatal_error)
1115
fields_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1117
values_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1119
if (thd->is_fatal_error)
1067
1121
for (i=0 ; i < table_count ; i++)
1069
1123
fields_for_table[i]= new List_item;
1070
1124
values_for_table[i]= new List_item;
1072
if (session->is_fatal_error)
1126
if (thd->is_fatal_error)
1075
1129
/* Split fields into fields_for_table[] and values_by_table[] */
1126
1180
1 Safe to update
1129
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
1130
TableList *table_ref, TableList *all_tables)
1183
static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
1184
TABLE_LIST *table_ref, TABLE_LIST *all_tables)
1132
Table *table= join_tab->table;
1133
if (unique_table(session, table_ref, all_tables, 0))
1186
TABLE *table= join_tab->table;
1187
if (unique_table(thd, table_ref, all_tables, 0))
1135
1189
switch (join_tab->type) {
1136
1190
case JT_SYSTEM:
1270
1325
if (tmp_tables)
1272
for (uint32_t cnt = 0; cnt < table_count; cnt++)
1327
for (uint cnt = 0; cnt < table_count; cnt++)
1274
1329
if (tmp_tables[cnt])
1276
tmp_tables[cnt]->free_tmp_table(session);
1331
free_tmp_table(thd, tmp_tables[cnt]);
1277
1332
tmp_table_param[cnt].cleanup();
1281
1336
if (copy_field)
1282
1337
delete [] copy_field;
1283
session->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1338
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1284
1339
assert(trans_safe || !updated ||
1285
session->transaction.all.modified_non_trans_table);
1340
thd->transaction.all.modified_non_trans_table);
1289
bool multi_update::send_data(List<Item> &)
1344
bool multi_update::send_data(List<Item> ¬_used_values __attribute__((__unused__)))
1291
TableList *cur_table;
1346
TABLE_LIST *cur_table;
1293
1348
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1295
Table *table= cur_table->table;
1296
uint32_t offset= cur_table->shared;
1350
TABLE *table= cur_table->table;
1351
uint offset= cur_table->shared;
1298
1353
Check if we are using outer join and we didn't find the row
1299
1354
or if we have already updated this row in the previous call to this
1387
Table *tmp_table= tmp_tables[offset];
1442
TABLE *tmp_table= tmp_tables[offset];
1389
1444
For updatable VIEW store rowid of the updated table and
1390
1445
rowids of tables used in the CHECK OPTION condition.
1392
uint32_t field_num= 0;
1393
List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1448
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
1397
1452
tbl->file->position(tbl->record[0]);
1398
Field_varstring *ref_field=
1399
reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1400
ref_field->store((char *)tbl->file->ref, tbl->file->ref_length,
1453
memcpy((char*) tmp_table->field[field_num]->ptr,
1454
(char*) tbl->file->ref, tbl->file->ref_length);
1403
1456
} while ((tbl= tbl_it++));
1405
1458
/* Store regular updated fields in the row. */
1406
fill_record(session,
1407
1460
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
1408
1461
*values_for_table[offset], 1);
1449
1502
if (! trans_safe)
1451
assert(session->transaction.stmt.modified_non_trans_table);
1504
assert(thd->transaction.stmt.modified_non_trans_table);
1452
1505
if (do_update && table_count > 1)
1454
1507
/* Add warning here */
1456
1509
todo/fixme: do_update() is never called with the arg 1.
1457
1510
should it change the signature to become argless?
1462
if (session->transaction.stmt.modified_non_trans_table)
1515
if (thd->transaction.stmt.modified_non_trans_table)
1464
session->transaction.all.modified_non_trans_table= true;
1518
The query has to binlog because there's a modified non-transactional table
1519
either from the query's list or via a stored routine: bug#13270,23333
1521
if (mysql_bin_log.is_open())
1524
THD::killed status might not have been set ON at time of an error
1525
got caught and if happens later the killed error is written
1528
thd->binlog_query(THD::ROW_QUERY_TYPE,
1529
thd->query, thd->query_length,
1530
transactional_tables, false);
1532
thd->transaction.all.modified_non_trans_table= true;
1466
assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
1534
assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
1470
1538
int multi_update::do_updates()
1472
TableList *cur_table;
1540
TABLE_LIST *cur_table;
1473
1541
int local_error= 0;
1474
1542
ha_rows org_updated;
1475
Table *table, *tmp_table;
1476
List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
1543
TABLE *table, *tmp_table;
1544
List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
1478
1546
do_update= 0; // Don't retry this function
1481
1549
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1483
1551
bool can_compare_record;
1484
uint32_t offset= cur_table->shared;
1552
uint offset= cur_table->shared;
1486
1554
table = cur_table->table;
1487
1555
if (table == table_to_update)
1641
1706
if local_error is not set ON until after do_updates() then
1642
1707
later carried out killing should not affect binlogging.
1644
killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
1645
session->set_proc_info("end");
1709
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
1710
thd_proc_info(thd, "end");
1648
1713
Write the SQL statement to the binlog if we updated
1649
1714
rows and we succeeded or if we updated some non
1650
1715
transactional tables.
1652
1717
The query has to binlog because there's a modified non-transactional table
1653
1718
either from the query's list or via a stored routine: bug#13270,23333
1656
assert(trans_safe || !updated ||
1657
session->transaction.stmt.modified_non_trans_table);
1658
if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1721
assert(trans_safe || !updated ||
1722
thd->transaction.stmt.modified_non_trans_table);
1723
if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
1660
if (session->transaction.stmt.modified_non_trans_table)
1661
session->transaction.all.modified_non_trans_table= true;
1725
if (mysql_bin_log.is_open())
1727
if (local_error == 0)
1729
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
1730
thd->query, thd->query_length,
1731
transactional_tables, false, killed_status) &&
1734
local_error= 1; // Rollback update
1737
if (thd->transaction.stmt.modified_non_trans_table)
1738
thd->transaction.all.modified_non_trans_table= true;
1663
1740
if (local_error != 0)
1664
1741
error_handled= true; // to force early leave from ::send_error()
1674
id= session->arg_of_last_insert_id_function ?
1675
session->first_successful_insert_id_in_prev_stmt : 0;
1751
id= thd->arg_of_last_insert_id_function ?
1752
thd->first_successful_insert_id_in_prev_stmt : 0;
1676
1753
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
1677
(ulong) session->cuted_fields);
1678
session->row_count_func=
1679
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1680
::my_ok(session, (ulong) session->row_count_func, id, buff);
1754
(ulong) thd->cuted_fields);
1755
thd->row_count_func=
1756
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1757
::my_ok(thd, (ulong) thd->row_count_func, id, buff);