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
138
session thread handler
139
158
fields fields for update
140
159
values values of fields for update
141
160
conds WHERE clause expression
142
order_num number of elemen in order_st BY clause
143
order order_st BY clause list
161
order_num number of elemen in ORDER BY clause
162
order ORDER BY clause list
144
163
limit limit clause
145
164
handle_duplicates how to handle duplicates
168
2 - privilege check and openning table passed, but we need to convert to
169
multi-update because of view substitution
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,
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__)),
158
183
bool using_limit= limit != HA_POS_ERROR;
159
bool safe_update= test(session->options & OPTION_SAFE_UPDATES);
184
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
160
185
bool used_key_is_modified, transactional_table, will_batch;
161
186
bool can_compare_record;
162
187
int error, loc_error;
163
188
uint used_index= MAX_KEY, dup_key_found;
164
189
bool need_sort= true;
165
uint32_t table_count= 0;
166
191
ha_rows updated, found;
167
192
key_map old_covering_keys;
169
194
SQL_SELECT *select;
170
195
READ_RECORD info;
171
Select_Lex *select_lex= &session->lex->select_lex;
196
SELECT_LEX *select_lex= &thd->lex->select_lex;
172
197
bool need_reopen;
174
199
List<Item> all_fields;
175
Session::killed_state killed_status= Session::NOT_KILLED;
200
THD::killed_state killed_status= THD::NOT_KILLED;
179
if (open_tables(session, &table_list, &table_count, 0))
204
if (open_tables(thd, &table_list, &table_count, 0))
182
if (!lock_tables(session, table_list, table_count, &need_reopen))
207
if (!lock_tables(thd, table_list, table_count, &need_reopen))
184
209
if (!need_reopen)
186
close_tables_for_reopen(session, &table_list);
211
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)))
214
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
215
(thd->fill_derived_tables() &&
216
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
194
DRIZZLE_UPDATE_START();
195
session->set_proc_info("init");
219
MYSQL_UPDATE_START();
220
thd_proc_info(thd, "init");
196
221
table= table_list->table;
198
223
/* Calculate "table->covering_keys" based on the WHERE */
199
224
table->covering_keys= table->s->keys_in_use;
200
225
table->quick_keys.clear_all();
202
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
227
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
205
230
old_covering_keys= table->covering_keys; // Keys used in WHERE
206
231
/* Check the fields we are going to modify */
207
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))
208
233
goto abort; /* purecov: inspected */
209
234
if (table->timestamp_field)
224
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
249
if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
226
free_underlaid_joins(session, select_lex);
251
free_underlaid_joins(thd, select_lex);
227
252
goto abort; /* purecov: inspected */
230
255
if (select_lex->inner_refs_list.elements &&
231
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))
233
DRIZZLE_UPDATE_END();
239
264
Item::cond_result cond_value;
240
conds= remove_eq_conds(session, conds, &cond_value);
265
conds= remove_eq_conds(thd, conds, &cond_value);
241
266
if (cond_value == Item::COND_FALSE)
242
267
limit= 0; // Impossible WHERE
261
286
select= make_select(table, 0, 0, conds, 0, &error);
262
287
if (error || !limit ||
263
(select && select->check_quick(session, safe_update, limit)))
288
(select && select->check_quick(thd, safe_update, limit)))
266
free_underlaid_joins(session, select_lex);
291
free_underlaid_joins(thd, select_lex);
268
293
goto abort; // Error in where
269
DRIZZLE_UPDATE_END();
270
session->my_ok(); // No matching records
295
my_ok(thd); // No matching records
273
298
if (!select && limit != HA_POS_ERROR)
327
352
if (order && (need_sort || used_key_is_modified))
330
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
332
357
NOTE: filesort will call table->prepare_for_position()
335
360
SORT_FIELD *sortorder;
336
361
ha_rows examined_rows;
338
table->sort.io_cache = new IO_CACHE;
339
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));
341
365
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
342
(table->sort.found_records= filesort(session, table, sortorder, length,
366
(table->sort.found_records= filesort(thd, table, sortorder, length,
343
367
select, limit, 1,
385
409
if (used_index == MAX_KEY || (select && select->quick))
386
init_read_record(&info,session,table,select,0,1);
410
init_read_record(&info,thd,table,select,0,1);
388
init_read_record_idx(&info, session, table, 1, used_index);
412
init_read_record_idx(&info, thd, table, 1, used_index);
390
session->set_proc_info("Searching rows for update");
414
thd_proc_info(thd, "Searching rows for update");
391
415
ha_rows tmp_limit= limit;
393
while (!(error=info.read_record(&info)) && !session->killed)
417
while (!(error=info.read_record(&info)) && !thd->killed)
395
419
if (!(select && select->skip_record()))
447
471
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
449
473
if (select && select->quick && select->quick->reset())
451
475
table->file->try_semi_consistent_read(1);
452
init_read_record(&info,session,table,select,0,1);
476
init_read_record(&info,thd,table,select,0,1);
454
478
updated= found= 0;
456
* Per the SQL standard, inserting NULL into a NOT NULL
457
* field requires an error to be thrown.
461
* NULL check and handling occurs in field_conv.cc
463
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
464
session->cuted_fields= 0L;
465
session->set_proc_info("Updating");
479
/* Generate an error when trying to set a NOT NULL field to NULL. */
480
thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
481
: CHECK_FIELD_ERROR_FOR_NULL;
482
thd->cuted_fields=0L;
483
thd_proc_info(thd, "Updating");
467
485
transactional_table= table->file->has_transactions();
468
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)));
469
490
will_batch= !table->file->start_bulk_update();
666
687
Sometimes we want to binlog even if we updated no rows, in case user used
667
688
it to be sure master and slave are in same state.
669
if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
690
if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
671
if (session->transaction.stmt.modified_non_trans_table)
672
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;
674
assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
675
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);
677
710
/* If LAST_INSERT_ID(X) was used, report X */
678
id= session->arg_of_last_insert_id_function ?
679
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;
681
DRIZZLE_UPDATE_END();
684
717
char buff[STRING_BUFFER_USUAL_SIZE];
685
718
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
686
(ulong) session->cuted_fields);
687
session->row_count_func=
688
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
689
session->my_ok((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);
691
session->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
692
session->abort_on_warning= 0;
693
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);
697
free_underlaid_joins(session, select_lex);
730
free_underlaid_joins(thd, select_lex);
698
731
if (table->key_read)
700
733
table->key_read=0;
701
734
table->file->extra(HA_EXTRA_NO_KEYREAD);
703
session->abort_on_warning= 0;
736
thd->abort_on_warning= 0;
706
DRIZZLE_UPDATE_END();
714
747
mysql_prepare_update()
715
session - thread handler
716
749
table_list - global/local table list
717
750
conds - conditions
718
order_num - number of order_st BY list entries
719
order - order_st BY clause list
751
order_num - number of ORDER BY list entries
752
order - ORDER BY clause list
725
bool mysql_prepare_update(Session *session, TableList *table_list,
726
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)
728
761
List<Item> all_fields;
729
Select_Lex *select_lex= &session->lex->select_lex;
731
session->lex->allow_sum_func= 0;
733
if (setup_tables_and_check_access(session, &select_lex->context,
762
SELECT_LEX *select_lex= &thd->lex->select_lex;
765
Statement-based replication of UPDATE ... LIMIT is not safe as order of
766
rows is not defined, so in mixed mode we go to row-based.
768
Note that we may consider a statement as safe if ORDER BY primary_key
769
is present. However it may confuse users to see very similiar statements
770
replicated differently.
772
if (thd->lex->current_select->select_limit)
774
thd->lex->set_stmt_unsafe();
775
thd->set_current_stmt_binlog_row_based_if_mixed();
778
thd->lex->allow_sum_func= 0;
780
if (setup_tables_and_check_access(thd, &select_lex->context,
734
781
&select_lex->top_join_list,
736
783
&select_lex->leaf_tables,
738
setup_conds(session, table_list, select_lex->leaf_tables, conds) ||
739
select_lex->setup_ref_array(session, order_num) ||
740
setup_order(session, select_lex->ref_pointer_array,
785
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
786
select_lex->setup_ref_array(thd, order_num) ||
787
setup_order(thd, select_lex->ref_pointer_array,
741
788
table_list, all_fields, all_fields, order))
744
791
/* Check that we are not using table that we are updating in a sub select */
746
TableList *duplicate;
747
if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
793
TABLE_LIST *duplicate;
794
if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
749
796
update_non_unique_table_error(table_list, "UPDATE", duplicate);
750
797
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
759
806
/***************************************************************************
760
Update multiple tables from join
807
Update multiple tables from join
761
808
***************************************************************************/
801
848
counter else junk will be assigned here, but then replaced with real
802
849
count in open_tables()
804
uint32_t table_count= lex->table_count;
805
const bool using_lock_tables= session->locked_tables != 0;
806
bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
851
uint table_count= lex->table_count;
852
const bool using_lock_tables= thd->locked_tables != 0;
853
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
807
854
bool need_reopen= false;
810
857
/* following need for prepared statements, to run next time multi-update */
811
session->lex->sql_command= SQLCOM_UPDATE_MULTI;
858
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
815
862
/* open tables and create derived ones, but do not lock and fill them */
816
863
if (((original_multiupdate || need_reopen) &&
817
open_tables(session, &table_list, &table_count, 0)) ||
864
open_tables(thd, &table_list, &table_count, 0)) ||
818
865
mysql_handle_derived(lex, &mysql_derived_prepare))
821
868
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
822
869
second time, but this call will do nothing (there are check for second
823
870
call in setup_tables()).
826
if (setup_tables_and_check_access(session, &lex->select_lex.context,
873
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
827
874
&lex->select_lex.top_join_list,
829
876
&lex->select_lex.leaf_tables, false))
832
if (setup_fields_with_no_wrap(session, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
835
if (update_view && check_fields(session, *fields))
879
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
882
if (update_view && check_fields(thd, *fields))
840
887
tables_for_update= get_table_map(fields);
868
915
correct order of statements. Otherwise, we use a TL_READ lock to
869
916
improve performance.
871
tl->lock_type= TL_READ;
918
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
873
/* Update Table::lock_type accordingly. */
920
/* Update TABLE::lock_type accordingly. */
874
921
if (!tl->placeholder() && !using_lock_tables)
875
922
tl->table->reginfo.lock_type= tl->lock_type;
879
926
/* now lock and fill tables */
880
if (lock_tables(session, table_list, table_count, &need_reopen))
927
if (lock_tables(thd, table_list, table_count, &need_reopen))
882
929
if (!need_reopen)
886
933
We have to reopen tables since some of them were altered or dropped
938
985
Setup multi-update handling and call SELECT to do the join
941
bool mysql_multi_update(Session *session,
942
TableList *table_list,
988
bool mysql_multi_update(THD *thd,
989
TABLE_LIST *table_list,
943
990
List<Item> *fields,
944
991
List<Item> *values,
946
993
uint64_t options,
947
994
enum enum_duplicates handle_duplicates, bool ignore,
948
Select_Lex_Unit *unit, Select_Lex *select_lex)
995
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
950
997
multi_update *result;
953
1000
if (!(result= new multi_update(table_list,
954
session->lex->select_lex.leaf_tables,
1001
thd->lex->select_lex.leaf_tables,
956
1003
handle_duplicates, ignore)))
959
session->abort_on_warning= true;
1006
thd->abort_on_warning= test(thd->variables.sql_mode &
1007
(MODE_STRICT_TRANS_TABLES |
1008
MODE_STRICT_ALL_TABLES));
961
1010
List<Item> total_list;
962
res= mysql_select(session, &select_lex->ref_pointer_array,
1011
res= mysql_select(thd, &select_lex->ref_pointer_array,
963
1012
table_list, select_lex->with_wild,
965
conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
1014
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
966
1016
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
967
1017
OPTION_SETUP_TABLES_DONE,
968
1018
result, unit, select_lex);
969
res|= session->is_error();
1019
res|= thd->is_error();
970
1020
if (unlikely(res))
972
1022
/* If we had a another error reported earlier then this will be ignored */
996
1046
Connect fields with tables and create list of tables that are updated
999
int multi_update::prepare(List<Item> &,
1049
int multi_update::prepare(List<Item> ¬_used_values __attribute__((__unused__)),
1050
SELECT_LEX_UNIT *lex_unit __attribute__((__unused__)))
1002
TableList *table_ref;
1052
TABLE_LIST *table_ref;
1003
1053
SQL_LIST update;
1004
1054
table_map tables_to_update;
1005
1055
Item_field *item;
1006
1056
List_iterator_fast<Item> field_it(*fields);
1007
1057
List_iterator_fast<Item> value_it(*values);
1008
uint32_t i, max_fields;
1009
uint32_t leaf_table_count= 0;
1011
session->count_cuted_fields= CHECK_FIELD_WARN;
1012
session->cuted_fields=0L;
1013
session->set_proc_info("updating main table");
1059
uint leaf_table_count= 0;
1061
thd->count_cuted_fields= CHECK_FIELD_WARN;
1062
thd->cuted_fields=0L;
1063
thd_proc_info(thd, "updating main table");
1015
1065
tables_to_update= get_table_map(fields);
1038
1088
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1040
1090
/* TODO: add support of view of join support */
1041
Table *table=table_ref->table;
1091
TABLE *table=table_ref->table;
1042
1092
leaf_table_count++;
1043
1093
if (tables_to_update & table->map)
1045
TableList *tl= (TableList*) session->memdup((char*) table_ref,
1095
TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
1049
update.link_in_list((unsigned char*) tl, (unsigned char**) &tl->next_local);
1099
update.link_in_list((uchar*) tl, (uchar**) &tl->next_local);
1050
1100
tl->shared= table_count++;
1051
1101
table->no_keyread=1;
1052
1102
table->covering_keys.clear_all();
1058
1108
table_count= update.elements;
1059
update_tables= (TableList*) update.first;
1109
update_tables= (TABLE_LIST*) update.first;
1061
tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
1062
tmp_table_param = (Tmp_Table_Param*) session->calloc(sizeof(Tmp_Table_Param) *
1111
tmp_tables = (TABLE**) thd->calloc(sizeof(TABLE *) * table_count);
1112
tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
1064
fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1066
values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1068
if (session->is_fatal_error)
1114
fields_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1116
values_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1118
if (thd->is_fatal_error)
1070
1120
for (i=0 ; i < table_count ; i++)
1072
1122
fields_for_table[i]= new List_item;
1073
1123
values_for_table[i]= new List_item;
1075
if (session->is_fatal_error)
1125
if (thd->is_fatal_error)
1078
1128
/* Split fields into fields_for_table[] and values_by_table[] */
1129
1179
1 Safe to update
1132
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
1133
TableList *table_ref, TableList *all_tables)
1182
static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
1183
TABLE_LIST *table_ref, TABLE_LIST *all_tables)
1135
Table *table= join_tab->table;
1136
if (unique_table(session, table_ref, all_tables, 0))
1185
TABLE *table= join_tab->table;
1186
if (unique_table(thd, table_ref, all_tables, 0))
1138
1188
switch (join_tab->type) {
1139
1189
case JT_SYSTEM:
1185
1235
/* Create a temporary table for keys to all tables, except main table */
1186
1236
for (table_ref= update_tables; table_ref; table_ref= table_ref->next_local)
1188
Table *table=table_ref->table;
1189
uint32_t cnt= table_ref->shared;
1238
TABLE *table=table_ref->table;
1239
uint cnt= table_ref->shared;
1190
1240
List<Item> temp_fields;
1192
Tmp_Table_Param *tmp_param;
1242
TMP_TABLE_PARAM *tmp_param;
1194
1244
table->mark_columns_needed_for_update();
1196
1246
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1197
1247
if (table == main_table) // First table in join
1199
if (safe_update_on_fly(session, join->join_tab, table_ref, all_tables))
1249
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
1201
1251
table_to_update= main_table; // Update table on the fly
1273
1324
if (tmp_tables)
1275
for (uint32_t cnt = 0; cnt < table_count; cnt++)
1326
for (uint cnt = 0; cnt < table_count; cnt++)
1277
1328
if (tmp_tables[cnt])
1279
tmp_tables[cnt]->free_tmp_table(session);
1330
free_tmp_table(thd, tmp_tables[cnt]);
1280
1331
tmp_table_param[cnt].cleanup();
1284
1335
if (copy_field)
1285
1336
delete [] copy_field;
1286
session->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1337
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1287
1338
assert(trans_safe || !updated ||
1288
session->transaction.all.modified_non_trans_table);
1339
thd->transaction.all.modified_non_trans_table);
1292
bool multi_update::send_data(List<Item> &)
1343
bool multi_update::send_data(List<Item> ¬_used_values __attribute__((__unused__)))
1294
TableList *cur_table;
1345
TABLE_LIST *cur_table;
1296
1347
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1298
Table *table= cur_table->table;
1299
uint32_t offset= cur_table->shared;
1349
TABLE *table= cur_table->table;
1350
uint offset= cur_table->shared;
1301
1352
Check if we are using outer join and we didn't find the row
1302
1353
or if we have already updated this row in the previous call to this
1390
Table *tmp_table= tmp_tables[offset];
1441
TABLE *tmp_table= tmp_tables[offset];
1392
1443
For updatable VIEW store rowid of the updated table and
1393
1444
rowids of tables used in the CHECK OPTION condition.
1395
uint32_t field_num= 0;
1396
List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1447
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
1400
1451
tbl->file->position(tbl->record[0]);
1401
Field_varstring *ref_field=
1402
reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1403
ref_field->store((char *)tbl->file->ref, tbl->file->ref_length,
1452
memcpy((char*) tmp_table->field[field_num]->ptr,
1453
(char*) tbl->file->ref, tbl->file->ref_length);
1406
1455
} while ((tbl= tbl_it++));
1408
1457
/* Store regular updated fields in the row. */
1409
fill_record(session,
1410
1459
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
1411
1460
*values_for_table[offset], 1);
1452
1501
if (! trans_safe)
1454
assert(session->transaction.stmt.modified_non_trans_table);
1503
assert(thd->transaction.stmt.modified_non_trans_table);
1455
1504
if (do_update && table_count > 1)
1457
1506
/* Add warning here */
1459
1508
todo/fixme: do_update() is never called with the arg 1.
1460
1509
should it change the signature to become argless?
1465
if (session->transaction.stmt.modified_non_trans_table)
1514
if (thd->transaction.stmt.modified_non_trans_table)
1467
session->transaction.all.modified_non_trans_table= true;
1517
The query has to binlog because there's a modified non-transactional table
1518
either from the query's list or via a stored routine: bug#13270,23333
1520
if (mysql_bin_log.is_open())
1523
THD::killed status might not have been set ON at time of an error
1524
got caught and if happens later the killed error is written
1527
thd->binlog_query(THD::ROW_QUERY_TYPE,
1528
thd->query, thd->query_length,
1529
transactional_tables, false);
1531
thd->transaction.all.modified_non_trans_table= true;
1469
assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
1533
assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
1473
1537
int multi_update::do_updates()
1475
TableList *cur_table;
1539
TABLE_LIST *cur_table;
1476
1540
int local_error= 0;
1477
1541
ha_rows org_updated;
1478
Table *table, *tmp_table;
1479
List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
1542
TABLE *table, *tmp_table;
1543
List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
1481
1545
do_update= 0; // Don't retry this function
1484
1548
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1486
1550
bool can_compare_record;
1487
uint32_t offset= cur_table->shared;
1551
uint offset= cur_table->shared;
1489
1553
table = cur_table->table;
1490
1554
if (table == table_to_update)
1644
1705
if local_error is not set ON until after do_updates() then
1645
1706
later carried out killing should not affect binlogging.
1647
killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
1648
session->set_proc_info("end");
1708
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
1709
thd_proc_info(thd, "end");
1651
1712
Write the SQL statement to the binlog if we updated
1652
1713
rows and we succeeded or if we updated some non
1653
1714
transactional tables.
1655
1716
The query has to binlog because there's a modified non-transactional table
1656
1717
either from the query's list or via a stored routine: bug#13270,23333
1659
assert(trans_safe || !updated ||
1660
session->transaction.stmt.modified_non_trans_table);
1661
if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1720
assert(trans_safe || !updated ||
1721
thd->transaction.stmt.modified_non_trans_table);
1722
if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
1663
if (session->transaction.stmt.modified_non_trans_table)
1664
session->transaction.all.modified_non_trans_table= true;
1724
if (mysql_bin_log.is_open())
1726
if (local_error == 0)
1728
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
1729
thd->query, thd->query_length,
1730
transactional_tables, false, killed_status) &&
1733
local_error= 1; // Rollback update
1736
if (thd->transaction.stmt.modified_non_trans_table)
1737
thd->transaction.all.modified_non_trans_table= true;
1666
1739
if (local_error != 0)
1667
1740
error_handled= true; // to force early leave from ::send_error()
1671
1744
/* Safety: If we haven't got an error before (can happen in do_updates) */
1672
1745
my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
1677
id= session->arg_of_last_insert_id_function ?
1678
session->first_successful_insert_id_in_prev_stmt : 0;
1750
id= thd->arg_of_last_insert_id_function ?
1751
thd->first_successful_insert_id_in_prev_stmt : 0;
1679
1752
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
1680
(ulong) session->cuted_fields);
1681
session->row_count_func=
1682
(session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1683
session->my_ok((ulong) session->row_count_func, id, buff);
1753
(ulong) thd->cuted_fields);
1754
thd->row_count_func=
1755
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1756
::my_ok(thd, (ulong) thd->row_count_func, id, buff);