111
session thread handler
112
136
fields fields for update
113
137
values values of fields for update
114
138
conds WHERE clause expression
115
order_num number of elemen in ORDER BY clause
139
order_num number of elemen in order_st BY clause
116
140
order order_st BY clause list
117
141
limit limit clause
118
142
handle_duplicates how to handle duplicates
146
2 - privilege check and openning table passed, but we need to convert to
147
multi-update because of view substitution
125
int mysql_update(Session *session, TableList *table_list,
126
List<Item> &fields, List<Item> &values, COND *conds,
127
uint32_t order_num, order_st *order,
128
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)),
131
161
bool using_limit= limit != HA_POS_ERROR;
132
bool used_key_is_modified;
133
bool transactional_table;
162
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
163
bool used_key_is_modified, transactional_table, will_batch;
134
164
bool can_compare_record;
165
int error, loc_error;
136
166
uint used_index= MAX_KEY, dup_key_found;
137
167
bool need_sort= true;
138
169
ha_rows updated, found;
139
170
key_map old_covering_keys;
141
optimizer::SqlSelect *select= NULL;
142
173
READ_RECORD info;
143
Select_Lex *select_lex= &session->lex->select_lex;
174
SELECT_LEX *select_lex= &thd->lex->select_lex;
145
177
List<Item> all_fields;
146
Session::killed_state killed_status= Session::NOT_KILLED;
148
DRIZZLE_UPDATE_START(session->query.c_str());
149
if (session->openTablesLock(table_list))
178
THD::killed_state killed_status= THD::NOT_KILLED;
151
DRIZZLE_UPDATE_DONE(1, 0, 0);
182
if (open_tables(thd, &table_list, &table_count, 0))
185
if (!lock_tables(thd, table_list, table_count, &need_reopen))
189
close_tables_for_reopen(thd, &table_list);
155
session->set_proc_info("init");
192
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
193
(thd->fill_derived_tables() &&
194
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
197
DRIZZLE_UPDATE_START();
198
thd_proc_info(thd, "init");
156
199
table= table_list->table;
158
201
/* Calculate "table->covering_keys" based on the WHERE */
159
202
table->covering_keys= table->s->keys_in_use;
160
table->quick_keys.reset();
203
table->quick_keys.clear_all();
162
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
205
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
165
208
old_covering_keys= table->covering_keys; // Keys used in WHERE
166
209
/* Check the fields we are going to modify */
167
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))
211
goto abort; /* purecov: inspected */
169
212
if (table->timestamp_field)
171
214
// Don't set timestamp column if this is modified
172
if (table->timestamp_field->isWriteSet())
215
if (bitmap_is_set(table->write_set,
216
table->timestamp_field->field_index))
173
217
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
176
220
if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
177
221
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
178
table->setWriteSet(table->timestamp_field->field_index);
222
bitmap_set_bit(table->write_set,
223
table->timestamp_field->field_index);
182
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
227
if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
184
free_underlaid_joins(session, select_lex);
229
free_underlaid_joins(thd, select_lex);
230
goto abort; /* purecov: inspected */
188
233
if (select_lex->inner_refs_list.elements &&
189
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))
191
DRIZZLE_UPDATE_DONE(1, 0, 0);
236
DRIZZLE_UPDATE_END();
197
242
Item::cond_result cond_value;
198
conds= remove_eq_conds(session, conds, &cond_value);
243
conds= remove_eq_conds(thd, conds, &cond_value);
199
244
if (cond_value == Item::COND_FALSE)
200
245
limit= 0; // Impossible WHERE
579
722
mysql_prepare_update()
580
session - thread handler
581
724
table_list - global/local table list
582
725
conds - conditions
583
order_num - number of ORDER BY list entries
584
order - ORDER BY clause list
726
order_num - number of order_st BY list entries
727
order - order_st BY clause list
590
bool mysql_prepare_update(Session *session, TableList *table_list,
591
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)
593
736
List<Item> all_fields;
594
Select_Lex *select_lex= &session->lex->select_lex;
596
session->lex->allow_sum_func= 0;
598
if (setup_tables_and_check_access(session, &select_lex->context,
737
SELECT_LEX *select_lex= &thd->lex->select_lex;
740
Statement-based replication of UPDATE ... LIMIT is not safe as order of
741
rows is not defined, so in mixed mode we go to row-based.
743
Note that we may consider a statement as safe if order_st BY primary_key
744
is present. However it may confuse users to see very similiar statements
745
replicated differently.
747
if (thd->lex->current_select->select_limit)
749
thd->lex->set_stmt_unsafe();
750
thd->set_current_stmt_binlog_row_based_if_mixed();
753
thd->lex->allow_sum_func= 0;
755
if (setup_tables_and_check_access(thd, &select_lex->context,
599
756
&select_lex->top_join_list,
601
758
&select_lex->leaf_tables,
603
session->setup_conds(table_list, conds) ||
604
select_lex->setup_ref_array(session, order_num) ||
605
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,
606
763
table_list, all_fields, all_fields, order))
609
766
/* Check that we are not using table that we are updating in a sub select */
611
768
TableList *duplicate;
612
if ((duplicate= unique_table(table_list, table_list->next_global)))
769
if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
771
update_non_unique_table_error(table_list, "UPDATE", duplicate);
614
772
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
781
/***************************************************************************
782
Update multiple tables from join
783
***************************************************************************/
786
Get table map for list of Item_field
789
static table_map get_table_map(List<Item> *items)
791
List_iterator_fast<Item> item_it(*items);
795
while ((item= (Item_field *) item_it++))
796
map|= item->used_tables();
802
make update specific preparation and checks after opening tables
805
mysql_multi_update_prepare()
813
int mysql_multi_update_prepare(THD *thd)
816
TableList *table_list= lex->query_tables;
817
TableList *tl, *leaves;
818
List<Item> *fields= &lex->select_lex.item_list;
819
table_map tables_for_update;
822
if this multi-update was converted from usual update, here is table
823
counter else junk will be assigned here, but then replaced with real
824
count in open_tables()
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);
829
bool need_reopen= false;
832
/* following need for prepared statements, to run next time multi-update */
833
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
837
/* open tables and create derived ones, but do not lock and fill them */
838
if (((original_multiupdate || need_reopen) &&
839
open_tables(thd, &table_list, &table_count, 0)) ||
840
mysql_handle_derived(lex, &mysql_derived_prepare))
843
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
844
second time, but this call will do nothing (there are check for second
845
call in setup_tables()).
848
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
849
&lex->select_lex.top_join_list,
851
&lex->select_lex.leaf_tables, false))
854
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
857
if (update_view && check_fields(thd, *fields))
862
tables_for_update= get_table_map(fields);
865
Setup timestamp handling and locking mode
867
leaves= lex->select_lex.leaf_tables;
868
for (tl= leaves; tl; tl= tl->next_leaf)
870
Table *table= tl->table;
871
/* Only set timestamp column if this is not modified */
872
if (table->timestamp_field &&
873
bitmap_is_set(table->write_set,
874
table->timestamp_field->field_index))
875
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
877
/* if table will be updated then check that it is unique */
878
if (table->map & tables_for_update)
880
table->mark_columns_needed_for_update();
882
If table will be updated we should not downgrade lock for it and
889
If we are using the binary log, we need TL_READ_NO_INSERT to get
890
correct order of statements. Otherwise, we use a TL_READ lock to
893
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
895
/* Update Table::lock_type accordingly. */
896
if (!tl->placeholder() && !using_lock_tables)
897
tl->table->reginfo.lock_type= tl->lock_type;
901
/* now lock and fill tables */
902
if (lock_tables(thd, table_list, table_count, &need_reopen))
908
We have to reopen tables since some of them were altered or dropped
909
during lock_tables() or something was done with their triggers.
910
Let us do some cleanups to be able do setup_table() and setup_fields()
913
List_iterator_fast<Item> it(*fields);
918
/* We have to cleanup translation tables of views. */
919
for (TableList *tbl= table_list; tbl; tbl= tbl->next_global)
920
tbl->cleanup_items();
922
close_tables_for_reopen(thd, &table_list);
927
Check that we are not using table that we are updating, but we should
928
skip all tables of UPDATE SELECT itself
930
lex->select_lex.exclude_from_table_unique_test= true;
931
/* We only need SELECT privilege for columns in the values list */
932
for (tl= leaves; tl; tl= tl->next_leaf)
934
if (tl->lock_type != TL_READ &&
935
tl->lock_type != TL_READ_NO_INSERT)
937
TableList *duplicate;
938
if ((duplicate= unique_table(thd, tl, table_list, 0)))
940
update_non_unique_table_error(table_list, "UPDATE", duplicate);
946
Set exclude_from_table_unique_test value back to false. It is needed for
947
further check in multi_update::prepare whether to use record cache.
949
lex->select_lex.exclude_from_table_unique_test= false;
951
if (thd->fill_derived_tables() &&
952
mysql_handle_derived(lex, &mysql_derived_filling))
960
Setup multi-update handling and call SELECT to do the join
963
bool mysql_multi_update(THD *thd,
964
TableList *table_list,
969
enum enum_duplicates handle_duplicates, bool ignore,
970
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
972
multi_update *result;
975
if (!(result= new multi_update(table_list,
976
thd->lex->select_lex.leaf_tables,
978
handle_duplicates, ignore)))
981
thd->abort_on_warning= true;
983
List<Item> total_list;
984
res= mysql_select(thd, &select_lex->ref_pointer_array,
985
table_list, select_lex->with_wild,
987
conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
989
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
990
OPTION_SETUP_TABLES_DONE,
991
result, unit, select_lex);
992
res|= thd->is_error();
995
/* If we had a another error reported earlier then this will be ignored */
996
result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
1000
thd->abort_on_warning= 0;
1005
multi_update::multi_update(TableList *table_list,
1006
TableList *leaves_list,
1007
List<Item> *field_list, List<Item> *value_list,
1008
enum enum_duplicates handle_duplicates_arg,
1010
:all_tables(table_list), leaves(leaves_list), update_tables(0),
1011
tmp_tables(0), updated(0), found(0), fields(field_list),
1012
values(value_list), table_count(0), copy_field(0),
1013
handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
1014
transactional_tables(0), ignore(ignore_arg), error_handled(0)
1019
Connect fields with tables and create list of tables that are updated
1022
int multi_update::prepare(List<Item> ¬_used_values __attribute__((unused)),
1023
SELECT_LEX_UNIT *lex_unit __attribute__((unused)))
1025
TableList *table_ref;
1027
table_map tables_to_update;
1029
List_iterator_fast<Item> field_it(*fields);
1030
List_iterator_fast<Item> value_it(*values);
1032
uint leaf_table_count= 0;
1034
thd->count_cuted_fields= CHECK_FIELD_WARN;
1035
thd->cuted_fields=0L;
1036
thd_proc_info(thd, "updating main table");
1038
tables_to_update= get_table_map(fields);
1040
if (!tables_to_update)
1042
my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
1047
We have to check values after setup_tables to get covering_keys right in
1051
if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0))
1055
Save tables beeing updated in update_tables
1056
update_table->shared is position for table
1057
Don't use key read on tables that are updated
1061
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1063
/* TODO: add support of view of join support */
1064
Table *table=table_ref->table;
1066
if (tables_to_update & table->map)
1068
TableList *tl= (TableList*) thd->memdup((char*) table_ref,
1072
update.link_in_list((uchar*) tl, (uchar**) &tl->next_local);
1073
tl->shared= table_count++;
1074
table->no_keyread=1;
1075
table->covering_keys.clear_all();
1076
table->pos_in_table_list= tl;
1081
table_count= update.elements;
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) *
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)
1093
for (i=0 ; i < table_count ; i++)
1095
fields_for_table[i]= new List_item;
1096
values_for_table[i]= new List_item;
1098
if (thd->is_fatal_error)
1101
/* Split fields into fields_for_table[] and values_by_table[] */
1103
while ((item= (Item_field *) field_it++))
1105
Item *value= value_it++;
1106
uint offset= item->field->table->pos_in_table_list->shared;
1107
fields_for_table[offset]->push_back(item);
1108
values_for_table[offset]->push_back(value);
1110
if (thd->is_fatal_error)
1113
/* Allocate copy fields */
1115
for (i=0 ; i < table_count ; i++)
1116
set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
1117
copy_field= new Copy_field[max_fields];
1118
return(thd->is_fatal_error != 0);
1123
Check if table is safe to update on fly
1126
safe_update_on_fly()
1128
join_tab How table is used in join
1129
all_tables List of tables
1132
We can update the first table in join on the fly if we know that
1133
a row in this table will never be read twice. This is true under
1134
the following conditions:
1136
- We are doing a table scan and the data is in a separate file (MyISAM) or
1137
if we don't update a clustered key.
1139
- We are doing a range scan and we don't update the scan key or
1140
the primary key for a clustered table handler.
1142
- Table is not joined to itself.
1144
This function gets information about fields to be updated from
1145
the Table::write_set bitmap.
1148
This code is a bit dependent of how make_join_readinfo() works.
1151
0 Not safe to update
1155
static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
1156
TableList *table_ref, TableList *all_tables)
1158
Table *table= join_tab->table;
1159
if (unique_table(thd, table_ref, all_tables, 0))
1161
switch (join_tab->type) {
1165
return true; // At most one matching row
1167
case JT_REF_OR_NULL:
1168
return !is_key_used(table, join_tab->ref.key, table->write_set);
1170
/* If range search on index */
1171
if (join_tab->quick)
1172
return !join_tab->quick->is_keys_used(table->write_set);
1173
/* If scanning in clustered key */
1174
if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1175
table->s->primary_key < MAX_KEY)
1176
return !is_key_used(table, table->s->primary_key, table->write_set);
1179
break; // Avoid compler warning
622
} /* namespace drizzled */
1187
Initialize table for multi table
1190
- Update first table in join on the fly, if possible
1191
- Create temporary tables to store changed values for all other tables
1192
that are updated (and main_table if the above doesn't hold).
1196
multi_update::initialize_tables(JOIN *join)
1198
TableList *table_ref;
1200
if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
1202
main_table=join->join_tab->table;
1205
/* Any update has at least one pair (field, value) */
1206
assert(fields->elements);
1208
/* Create a temporary table for keys to all tables, except main table */
1209
for (table_ref= update_tables; table_ref; table_ref= table_ref->next_local)
1211
Table *table=table_ref->table;
1212
uint cnt= table_ref->shared;
1213
List<Item> temp_fields;
1215
TMP_TABLE_PARAM *tmp_param;
1217
table->mark_columns_needed_for_update();
1219
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1220
if (table == main_table) // First table in join
1222
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
1224
table_to_update= main_table; // Update table on the fly
1228
table->prepare_for_position();
1230
tmp_param= tmp_table_param+cnt;
1233
Create a temporary table to store all fields that are changed for this
1234
table. The first field in the temporary table is a pointer to the
1235
original row so that we can find and update it. For the updatable
1236
VIEW a few following fields are rowids of tables used in the CHECK
1240
List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1244
Field_string *field= new Field_string(tbl->file->ref_length, 0,
1245
tbl->alias, &my_charset_bin);
1247
Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
1248
tbl->alias, tbl->s, &my_charset_bin);
1254
The field will be converted to varstring when creating tmp table if
1255
table to be updated was created by mysql 4.1. Deny this.
1257
Item_field *ifield= new Item_field((Field *) field);
1260
ifield->maybe_null= 0;
1261
if (temp_fields.push_back(ifield))
1263
} while ((tbl= tbl_it++));
1265
temp_fields.concat(fields_for_table[cnt]);
1267
/* Make an unique key over the first field to avoid duplicated updates */
1268
memset(&group, 0, sizeof(group));
1270
group.item= (Item**) temp_fields.head_ref();
1272
tmp_param->quick_group=1;
1273
tmp_param->field_count=temp_fields.elements;
1274
tmp_param->group_parts=1;
1275
tmp_param->group_length= table->file->ref_length;
1276
if (!(tmp_tables[cnt]=create_tmp_table(thd,
1279
(order_st*) &group, 0, 0,
1280
TMP_TABLE_ALL_COLUMNS,
1284
tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
1290
multi_update::~multi_update()
1293
for (table= update_tables ; table; table= table->next_local)
1295
table->table->no_keyread= table->table->no_cache= 0;
1297
table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1302
for (uint cnt = 0; cnt < table_count; cnt++)
1304
if (tmp_tables[cnt])
1306
tmp_tables[cnt]->free_tmp_table(thd);
1307
tmp_table_param[cnt].cleanup();
1312
delete [] copy_field;
1313
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1314
assert(trans_safe || !updated ||
1315
thd->transaction.all.modified_non_trans_table);
1319
bool multi_update::send_data(List<Item> ¬_used_values __attribute__((unused)))
1321
TableList *cur_table;
1323
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1325
Table *table= cur_table->table;
1326
uint offset= cur_table->shared;
1328
Check if we are using outer join and we didn't find the row
1329
or if we have already updated this row in the previous call to this
1332
The same row may be presented here several times in a join of type
1333
UPDATE t1 FROM t1,t2 SET t1.a=t2.a
1335
In this case we will do the update for the first found row combination.
1336
The join algorithm guarantees that we will not find the a row in
1339
if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
1343
We can use compare_record() to optimize away updates if
1344
the table handler is returning all columns OR if
1345
if all updated columns are read
1347
if (table == table_to_update)
1349
bool can_compare_record;
1350
can_compare_record= (!(table->file->ha_table_flags() &
1351
HA_PARTIAL_COLUMN_READ) ||
1352
bitmap_is_subset(table->write_set,
1354
table->status|= STATUS_UPDATED;
1355
store_record(table,record[1]);
1356
if (fill_record(thd, *fields_for_table[offset],
1357
*values_for_table[offset], 0))
1361
if (!can_compare_record || table->compare_record())
1367
Inform the main table that we are going to update the table even
1368
while we may be scanning it. This will flush the read cache
1371
main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
1373
if ((error=table->file->ha_update_row(table->record[1],
1374
table->record[0])) &&
1375
error != HA_ERR_RECORD_IS_THE_SAME)
1379
table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
1382
If (ignore && error == is ignorable) we don't have to
1383
do anything; otherwise...
1387
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
1388
flags|= ME_FATALERROR; /* Other handler errors are fatal */
1390
prepare_record_for_error_message(error, table);
1391
table->file->print_error(error,MYF(flags));
1397
if (error == HA_ERR_RECORD_IS_THE_SAME)
1402
/* non-transactional or transactional table got modified */
1403
/* either multi_update class' flag is raised in its branch */
1404
if (table->file->has_transactions())
1405
transactional_tables= 1;
1409
thd->transaction.stmt.modified_non_trans_table= true;
1417
Table *tmp_table= tmp_tables[offset];
1419
For updatable VIEW store rowid of the updated table and
1420
rowids of tables used in the CHECK OPTION condition.
1423
List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1427
tbl->file->position(tbl->record[0]);
1428
memcpy(tmp_table->field[field_num]->ptr,
1429
tbl->file->ref, tbl->file->ref_length);
1431
} while ((tbl= tbl_it++));
1433
/* Store regular updated fields in the row. */
1435
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
1436
*values_for_table[offset], 1);
1438
/* Write row, ignoring duplicated updates to a row */
1439
error= tmp_table->file->ha_write_row(tmp_table->record[0]);
1440
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
1443
create_myisam_from_heap(thd, tmp_table,
1444
tmp_table_param[offset].start_recinfo,
1445
&tmp_table_param[offset].recinfo,
1449
return(1); // Not a table_is_full error
1459
void multi_update::send_error(uint errcode,const char *err)
1461
/* First send error what ever it is ... */
1462
my_error(errcode, MYF(0), err);
1466
void multi_update::abort()
1468
/* the error was handled or nothing deleted and no side effects return */
1469
if (error_handled ||
1470
(!thd->transaction.stmt.modified_non_trans_table && !updated))
1473
If all tables that has been updated are trans safe then just do rollback.
1474
If not attempt to do remaining updates.
1479
assert(thd->transaction.stmt.modified_non_trans_table);
1480
if (do_update && table_count > 1)
1482
/* Add warning here */
1484
todo/fixme: do_update() is never called with the arg 1.
1485
should it change the signature to become argless?
1490
if (thd->transaction.stmt.modified_non_trans_table)
1493
The query has to binlog because there's a modified non-transactional table
1494
either from the query's list or via a stored routine: bug#13270,23333
1496
if (mysql_bin_log.is_open())
1499
THD::killed status might not have been set ON at time of an error
1500
got caught and if happens later the killed error is written
1503
thd->binlog_query(THD::ROW_QUERY_TYPE,
1504
thd->query, thd->query_length,
1505
transactional_tables, false);
1507
thd->transaction.all.modified_non_trans_table= true;
1509
assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
1513
int multi_update::do_updates()
1515
TableList *cur_table;
1517
ha_rows org_updated;
1518
Table *table, *tmp_table;
1519
List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
1521
do_update= 0; // Don't retry this function
1524
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1526
bool can_compare_record;
1527
uint offset= cur_table->shared;
1529
table = cur_table->table;
1530
if (table == table_to_update)
1531
continue; // Already updated
1532
org_updated= updated;
1533
tmp_table= tmp_tables[cur_table->shared];
1534
tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache
1535
(void) table->file->ha_rnd_init(0);
1536
table->file->extra(HA_EXTRA_NO_CACHE);
1538
check_opt_it.rewind();
1539
while(Table *tbl= check_opt_it++)
1541
if (tbl->file->ha_rnd_init(1))
1543
tbl->file->extra(HA_EXTRA_CACHE);
1547
Setup copy functions to copy fields from temporary table
1549
List_iterator_fast<Item> field_it(*fields_for_table[offset]);
1550
Field **field= tmp_table->field +
1551
1 + unupdated_check_opt_tables.elements; // Skip row pointers
1552
Copy_field *copy_field_ptr= copy_field, *copy_field_end;
1553
for ( ; *field ; field++)
1555
Item_field *item= (Item_field* ) field_it++;
1556
(copy_field_ptr++)->set(item->field, *field, 0);
1558
copy_field_end=copy_field_ptr;
1560
if ((local_error = tmp_table->file->ha_rnd_init(1)))
1563
can_compare_record= (!(table->file->ha_table_flags() &
1564
HA_PARTIAL_COLUMN_READ) ||
1565
bitmap_is_subset(table->write_set,
1570
if (thd->killed && trans_safe)
1572
if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
1574
if (local_error == HA_ERR_END_OF_FILE)
1576
if (local_error == HA_ERR_RECORD_DELETED)
1577
continue; // May happen on dup key
1581
/* call rnd_pos() using rowids from temporary table */
1582
check_opt_it.rewind();
1588
tbl->file->rnd_pos(tbl->record[0],
1589
(uchar *) tmp_table->field[field_num]->ptr)))
1592
} while((tbl= check_opt_it++));
1594
table->status|= STATUS_UPDATED;
1595
store_record(table,record[1]);
1597
/* Copy data from temporary table to current table */
1598
for (copy_field_ptr=copy_field;
1599
copy_field_ptr != copy_field_end;
1601
(*copy_field_ptr->do_copy)(copy_field_ptr);
1603
if (!can_compare_record || table->compare_record())
1605
if ((local_error=table->file->ha_update_row(table->record[1],
1606
table->record[0])) &&
1607
local_error != HA_ERR_RECORD_IS_THE_SAME)
1610
table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
1613
if (local_error != HA_ERR_RECORD_IS_THE_SAME)
1620
if (updated != org_updated)
1622
if (table->file->has_transactions())
1623
transactional_tables= 1;
1626
trans_safe= 0; // Can't do safe rollback
1627
thd->transaction.stmt.modified_non_trans_table= true;
1630
(void) table->file->ha_rnd_end();
1631
(void) tmp_table->file->ha_rnd_end();
1632
check_opt_it.rewind();
1633
while (Table *tbl= check_opt_it++)
1634
tbl->file->ha_rnd_end();
1641
prepare_record_for_error_message(local_error, table);
1642
table->file->print_error(local_error,MYF(ME_FATALERROR));
1645
(void) table->file->ha_rnd_end();
1646
(void) tmp_table->file->ha_rnd_end();
1647
check_opt_it.rewind();
1648
while (Table *tbl= check_opt_it++)
1649
tbl->file->ha_rnd_end();
1651
if (updated != org_updated)
1653
if (table->file->has_transactions())
1654
transactional_tables= 1;
1658
thd->transaction.stmt.modified_non_trans_table= true;
1665
/* out: 1 if error, 0 if success */
1667
bool multi_update::send_eof()
1669
char buff[STRING_BUFFER_USUAL_SIZE];
1671
THD::killed_state killed_status= THD::NOT_KILLED;
1673
thd_proc_info(thd, "updating reference tables");
1676
Does updates for the last n - 1 tables, returns 0 if ok;
1677
error takes into account killed status gained in do_updates()
1679
int local_error = (table_count) ? do_updates() : 0;
1681
if local_error is not set ON until after do_updates() then
1682
later carried out killing should not affect binlogging.
1684
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
1685
thd_proc_info(thd, "end");
1688
Write the SQL statement to the binlog if we updated
1689
rows and we succeeded or if we updated some non
1690
transactional tables.
1692
The query has to binlog because there's a modified non-transactional table
1693
either from the query's list or via a stored routine: bug#13270,23333
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)
1700
if (mysql_bin_log.is_open())
1702
if (local_error == 0)
1704
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
1705
thd->query, thd->query_length,
1706
transactional_tables, false, killed_status) &&
1709
local_error= 1; // Rollback update
1712
if (thd->transaction.stmt.modified_non_trans_table)
1713
thd->transaction.all.modified_non_trans_table= true;
1715
if (local_error != 0)
1716
error_handled= true; // to force early leave from ::send_error()
1718
if (local_error > 0) // if the above log write did not fail ...
1720
/* Safety: If we haven't got an error before (can happen in do_updates) */
1721
my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
1726
id= thd->arg_of_last_insert_id_function ?
1727
thd->first_successful_insert_id_in_prev_stmt : 0;
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);