105
session thread handler
158
106
fields fields for update
159
107
values values of fields for update
160
108
conds WHERE clause expression
161
order_num number of elemen in ORDER BY clause
162
order ORDER BY clause list
109
order_num number of elemen in order_st BY clause
110
order order_st BY clause list
163
111
limit limit clause
164
112
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
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)),
119
int mysql_update(Session *session, TableList *table_list,
120
List<Item> &fields, List<Item> &values, COND *conds,
121
uint32_t order_num, order_st *order,
122
ha_rows limit, enum enum_duplicates,
183
125
bool using_limit= limit != HA_POS_ERROR;
184
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
126
bool safe_update= test(session->options & OPTION_SAFE_UPDATES);
185
127
bool used_key_is_modified, transactional_table, will_batch;
186
128
bool can_compare_record;
187
129
int error, loc_error;
188
130
uint used_index= MAX_KEY, dup_key_found;
189
131
bool need_sort= true;
191
132
ha_rows updated, found;
192
133
key_map old_covering_keys;
194
135
SQL_SELECT *select;
195
136
READ_RECORD info;
196
SELECT_LEX *select_lex= &thd->lex->select_lex;
137
Select_Lex *select_lex= &session->lex->select_lex;
199
139
List<Item> all_fields;
200
THD::killed_state killed_status= THD::NOT_KILLED;
140
Session::killed_state killed_status= Session::NOT_KILLED;
142
DRIZZLE_UPDATE_START(session->query);
143
if (session->openTablesLock(table_list))
204
if (open_tables(thd, &table_list, &table_count, 0))
207
if (!lock_tables(thd, table_list, table_count, &need_reopen))
211
close_tables_for_reopen(thd, &table_list);
145
DRIZZLE_UPDATE_DONE(1, 0, 0);
214
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
215
(thd->fill_derived_tables() &&
216
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
219
DRIZZLE_UPDATE_START();
220
thd_proc_info(thd, "init");
149
session->set_proc_info("init");
221
150
table= table_list->table;
223
152
/* Calculate "table->covering_keys" based on the WHERE */
224
153
table->covering_keys= table->s->keys_in_use;
225
table->quick_keys.clear_all();
154
table->quick_keys.reset();
227
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
156
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
230
159
old_covering_keys= table->covering_keys; // Keys used in WHERE
231
160
/* Check the fields we are going to modify */
232
if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
233
goto abort; /* purecov: inspected */
161
if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
234
163
if (table->timestamp_field)
236
165
// Don't set timestamp column if this is modified
237
if (bitmap_is_set(table->write_set,
238
table->timestamp_field->field_index))
166
if (table->timestamp_field->isWriteSet())
239
167
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
242
170
if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
243
171
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
244
bitmap_set_bit(table->write_set,
245
table->timestamp_field->field_index);
172
table->setWriteSet(table->timestamp_field->field_index);
249
if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
176
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
251
free_underlaid_joins(thd, select_lex);
252
goto abort; /* purecov: inspected */
178
free_underlaid_joins(session, select_lex);
255
182
if (select_lex->inner_refs_list.elements &&
256
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
183
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
258
DRIZZLE_UPDATE_END();
185
DRIZZLE_UPDATE_DONE(1, 0, 0);
264
191
Item::cond_result cond_value;
265
conds= remove_eq_conds(thd, conds, &cond_value);
192
conds= remove_eq_conds(session, conds, &cond_value);
266
193
if (cond_value == Item::COND_FALSE)
267
194
limit= 0; // Impossible WHERE
747
671
mysql_prepare_update()
672
session - thread handler
749
673
table_list - global/local table list
750
674
conds - conditions
751
order_num - number of ORDER BY list entries
752
order - ORDER BY clause list
675
order_num - number of order_st BY list entries
676
order - order_st BY clause list
758
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
759
Item **conds, uint order_num, ORDER *order)
682
bool mysql_prepare_update(Session *session, TableList *table_list,
683
Item **conds, uint32_t order_num, order_st *order)
761
685
List<Item> all_fields;
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,
686
Select_Lex *select_lex= &session->lex->select_lex;
688
session->lex->allow_sum_func= 0;
690
if (setup_tables_and_check_access(session, &select_lex->context,
781
691
&select_lex->top_join_list,
783
693
&select_lex->leaf_tables,
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,
695
session->setup_conds(table_list, conds) ||
696
select_lex->setup_ref_array(session, order_num) ||
697
setup_order(session, select_lex->ref_pointer_array,
788
698
table_list, all_fields, all_fields, order))
791
701
/* Check that we are not using table that we are updating in a sub select */
793
TABLE_LIST *duplicate;
794
if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
703
TableList *duplicate;
704
if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
796
update_non_unique_table_error(table_list, "UPDATE", duplicate);
797
706
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
806
/***************************************************************************
807
Update multiple tables from join
808
***************************************************************************/
811
Get table map for list of Item_field
814
static table_map get_table_map(List<Item> *items)
816
List_iterator_fast<Item> item_it(*items);
820
while ((item= (Item_field *) item_it++))
821
map|= item->used_tables();
827
make update specific preparation and checks after opening tables
830
mysql_multi_update_prepare()
838
int mysql_multi_update_prepare(THD *thd)
841
TABLE_LIST *table_list= lex->query_tables;
842
TABLE_LIST *tl, *leaves;
843
List<Item> *fields= &lex->select_lex.item_list;
844
table_map tables_for_update;
847
if this multi-update was converted from usual update, here is table
848
counter else junk will be assigned here, but then replaced with real
849
count in open_tables()
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);
854
bool need_reopen= false;
857
/* following need for prepared statements, to run next time multi-update */
858
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
862
/* open tables and create derived ones, but do not lock and fill them */
863
if (((original_multiupdate || need_reopen) &&
864
open_tables(thd, &table_list, &table_count, 0)) ||
865
mysql_handle_derived(lex, &mysql_derived_prepare))
868
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
869
second time, but this call will do nothing (there are check for second
870
call in setup_tables()).
873
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
874
&lex->select_lex.top_join_list,
876
&lex->select_lex.leaf_tables, false))
879
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
882
if (update_view && check_fields(thd, *fields))
887
tables_for_update= get_table_map(fields);
890
Setup timestamp handling and locking mode
892
leaves= lex->select_lex.leaf_tables;
893
for (tl= leaves; tl; tl= tl->next_leaf)
895
TABLE *table= tl->table;
896
/* Only set timestamp column if this is not modified */
897
if (table->timestamp_field &&
898
bitmap_is_set(table->write_set,
899
table->timestamp_field->field_index))
900
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
902
/* if table will be updated then check that it is unique */
903
if (table->map & tables_for_update)
905
table->mark_columns_needed_for_update();
907
If table will be updated we should not downgrade lock for it and
914
If we are using the binary log, we need TL_READ_NO_INSERT to get
915
correct order of statements. Otherwise, we use a TL_READ lock to
918
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
920
/* Update TABLE::lock_type accordingly. */
921
if (!tl->placeholder() && !using_lock_tables)
922
tl->table->reginfo.lock_type= tl->lock_type;
926
/* now lock and fill tables */
927
if (lock_tables(thd, table_list, table_count, &need_reopen))
933
We have to reopen tables since some of them were altered or dropped
934
during lock_tables() or something was done with their triggers.
935
Let us do some cleanups to be able do setup_table() and setup_fields()
938
List_iterator_fast<Item> it(*fields);
943
/* We have to cleanup translation tables of views. */
944
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
945
tbl->cleanup_items();
947
close_tables_for_reopen(thd, &table_list);
952
Check that we are not using table that we are updating, but we should
953
skip all tables of UPDATE SELECT itself
955
lex->select_lex.exclude_from_table_unique_test= true;
956
/* We only need SELECT privilege for columns in the values list */
957
for (tl= leaves; tl; tl= tl->next_leaf)
959
if (tl->lock_type != TL_READ &&
960
tl->lock_type != TL_READ_NO_INSERT)
962
TABLE_LIST *duplicate;
963
if ((duplicate= unique_table(thd, tl, table_list, 0)))
965
update_non_unique_table_error(table_list, "UPDATE", duplicate);
971
Set exclude_from_table_unique_test value back to false. It is needed for
972
further check in multi_update::prepare whether to use record cache.
974
lex->select_lex.exclude_from_table_unique_test= false;
976
if (thd->fill_derived_tables() &&
977
mysql_handle_derived(lex, &mysql_derived_filling))
985
Setup multi-update handling and call SELECT to do the join
988
bool mysql_multi_update(THD *thd,
989
TABLE_LIST *table_list,
994
enum enum_duplicates handle_duplicates, bool ignore,
995
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
997
multi_update *result;
1000
if (!(result= new multi_update(table_list,
1001
thd->lex->select_lex.leaf_tables,
1003
handle_duplicates, ignore)))
1006
thd->abort_on_warning= test(thd->variables.sql_mode &
1007
(MODE_STRICT_TRANS_TABLES |
1008
MODE_STRICT_ALL_TABLES));
1010
List<Item> total_list;
1011
res= mysql_select(thd, &select_lex->ref_pointer_array,
1012
table_list, select_lex->with_wild,
1014
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
1016
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
1017
OPTION_SETUP_TABLES_DONE,
1018
result, unit, select_lex);
1019
res|= thd->is_error();
1022
/* If we had a another error reported earlier then this will be ignored */
1023
result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
1027
thd->abort_on_warning= 0;
1032
multi_update::multi_update(TABLE_LIST *table_list,
1033
TABLE_LIST *leaves_list,
1034
List<Item> *field_list, List<Item> *value_list,
1035
enum enum_duplicates handle_duplicates_arg,
1037
:all_tables(table_list), leaves(leaves_list), update_tables(0),
1038
tmp_tables(0), updated(0), found(0), fields(field_list),
1039
values(value_list), table_count(0), copy_field(0),
1040
handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
1041
transactional_tables(0), ignore(ignore_arg), error_handled(0)
1046
Connect fields with tables and create list of tables that are updated
1049
int multi_update::prepare(List<Item> ¬_used_values __attribute__((unused)),
1050
SELECT_LEX_UNIT *lex_unit __attribute__((unused)))
1052
TABLE_LIST *table_ref;
1054
table_map tables_to_update;
1056
List_iterator_fast<Item> field_it(*fields);
1057
List_iterator_fast<Item> value_it(*values);
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");
1065
tables_to_update= get_table_map(fields);
1067
if (!tables_to_update)
1069
my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
1074
We have to check values after setup_tables to get covering_keys right in
1078
if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0))
1082
Save tables beeing updated in update_tables
1083
update_table->shared is position for table
1084
Don't use key read on tables that are updated
1088
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1090
/* TODO: add support of view of join support */
1091
TABLE *table=table_ref->table;
1093
if (tables_to_update & table->map)
1095
TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
1099
update.link_in_list((uchar*) tl, (uchar**) &tl->next_local);
1100
tl->shared= table_count++;
1101
table->no_keyread=1;
1102
table->covering_keys.clear_all();
1103
table->pos_in_table_list= tl;
1108
table_count= update.elements;
1109
update_tables= (TABLE_LIST*) update.first;
1111
tmp_tables = (TABLE**) thd->calloc(sizeof(TABLE *) * table_count);
1112
tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
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)
1120
for (i=0 ; i < table_count ; i++)
1122
fields_for_table[i]= new List_item;
1123
values_for_table[i]= new List_item;
1125
if (thd->is_fatal_error)
1128
/* Split fields into fields_for_table[] and values_by_table[] */
1130
while ((item= (Item_field *) field_it++))
1132
Item *value= value_it++;
1133
uint offset= item->field->table->pos_in_table_list->shared;
1134
fields_for_table[offset]->push_back(item);
1135
values_for_table[offset]->push_back(value);
1137
if (thd->is_fatal_error)
1140
/* Allocate copy fields */
1142
for (i=0 ; i < table_count ; i++)
1143
set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
1144
copy_field= new Copy_field[max_fields];
1145
return(thd->is_fatal_error != 0);
1150
Check if table is safe to update on fly
1153
safe_update_on_fly()
1155
join_tab How table is used in join
1156
all_tables List of tables
1159
We can update the first table in join on the fly if we know that
1160
a row in this table will never be read twice. This is true under
1161
the following conditions:
1163
- We are doing a table scan and the data is in a separate file (MyISAM) or
1164
if we don't update a clustered key.
1166
- We are doing a range scan and we don't update the scan key or
1167
the primary key for a clustered table handler.
1169
- Table is not joined to itself.
1171
This function gets information about fields to be updated from
1172
the TABLE::write_set bitmap.
1175
This code is a bit dependent of how make_join_readinfo() works.
1178
0 Not safe to update
1182
static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
1183
TABLE_LIST *table_ref, TABLE_LIST *all_tables)
1185
TABLE *table= join_tab->table;
1186
if (unique_table(thd, table_ref, all_tables, 0))
1188
switch (join_tab->type) {
1192
return true; // At most one matching row
1194
case JT_REF_OR_NULL:
1195
return !is_key_used(table, join_tab->ref.key, table->write_set);
1197
/* If range search on index */
1198
if (join_tab->quick)
1199
return !join_tab->quick->is_keys_used(table->write_set);
1200
/* If scanning in clustered key */
1201
if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1202
table->s->primary_key < MAX_KEY)
1203
return !is_key_used(table, table->s->primary_key, table->write_set);
1206
break; // Avoid compler warning
1214
Initialize table for multi table
1217
- Update first table in join on the fly, if possible
1218
- Create temporary tables to store changed values for all other tables
1219
that are updated (and main_table if the above doesn't hold).
1223
multi_update::initialize_tables(JOIN *join)
1225
TABLE_LIST *table_ref;
1227
if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
1229
main_table=join->join_tab->table;
1232
/* Any update has at least one pair (field, value) */
1233
assert(fields->elements);
1235
/* Create a temporary table for keys to all tables, except main table */
1236
for (table_ref= update_tables; table_ref; table_ref= table_ref->next_local)
1238
TABLE *table=table_ref->table;
1239
uint cnt= table_ref->shared;
1240
List<Item> temp_fields;
1242
TMP_TABLE_PARAM *tmp_param;
1244
table->mark_columns_needed_for_update();
1246
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1247
if (table == main_table) // First table in join
1249
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
1251
table_to_update= main_table; // Update table on the fly
1255
table->prepare_for_position();
1257
tmp_param= tmp_table_param+cnt;
1260
Create a temporary table to store all fields that are changed for this
1261
table. The first field in the temporary table is a pointer to the
1262
original row so that we can find and update it. For the updatable
1263
VIEW a few following fields are rowids of tables used in the CHECK
1267
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
1271
Field_string *field= new Field_string(tbl->file->ref_length, 0,
1272
tbl->alias, &my_charset_bin);
1274
Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
1275
tbl->alias, tbl->s, &my_charset_bin);
1281
The field will be converted to varstring when creating tmp table if
1282
table to be updated was created by mysql 4.1. Deny this.
1284
Item_field *ifield= new Item_field((Field *) field);
1287
ifield->maybe_null= 0;
1288
if (temp_fields.push_back(ifield))
1290
} while ((tbl= tbl_it++));
1292
temp_fields.concat(fields_for_table[cnt]);
1294
/* Make an unique key over the first field to avoid duplicated updates */
1295
memset(&group, 0, sizeof(group));
1297
group.item= (Item**) temp_fields.head_ref();
1299
tmp_param->quick_group=1;
1300
tmp_param->field_count=temp_fields.elements;
1301
tmp_param->group_parts=1;
1302
tmp_param->group_length= table->file->ref_length;
1303
if (!(tmp_tables[cnt]=create_tmp_table(thd,
1306
(ORDER*) &group, 0, 0,
1307
TMP_TABLE_ALL_COLUMNS,
1311
tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
1317
multi_update::~multi_update()
1320
for (table= update_tables ; table; table= table->next_local)
1322
table->table->no_keyread= table->table->no_cache= 0;
1324
table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1329
for (uint cnt = 0; cnt < table_count; cnt++)
1331
if (tmp_tables[cnt])
1333
free_tmp_table(thd, tmp_tables[cnt]);
1334
tmp_table_param[cnt].cleanup();
1339
delete [] copy_field;
1340
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
1341
assert(trans_safe || !updated ||
1342
thd->transaction.all.modified_non_trans_table);
1346
bool multi_update::send_data(List<Item> ¬_used_values __attribute__((unused)))
1348
TABLE_LIST *cur_table;
1350
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1352
TABLE *table= cur_table->table;
1353
uint offset= cur_table->shared;
1355
Check if we are using outer join and we didn't find the row
1356
or if we have already updated this row in the previous call to this
1359
The same row may be presented here several times in a join of type
1360
UPDATE t1 FROM t1,t2 SET t1.a=t2.a
1362
In this case we will do the update for the first found row combination.
1363
The join algorithm guarantees that we will not find the a row in
1366
if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
1370
We can use compare_record() to optimize away updates if
1371
the table handler is returning all columns OR if
1372
if all updated columns are read
1374
if (table == table_to_update)
1376
bool can_compare_record;
1377
can_compare_record= (!(table->file->ha_table_flags() &
1378
HA_PARTIAL_COLUMN_READ) ||
1379
bitmap_is_subset(table->write_set,
1381
table->status|= STATUS_UPDATED;
1382
store_record(table,record[1]);
1383
if (fill_record(thd, *fields_for_table[offset],
1384
*values_for_table[offset], 0))
1388
if (!can_compare_record || compare_record(table))
1394
Inform the main table that we are going to update the table even
1395
while we may be scanning it. This will flush the read cache
1398
main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
1400
if ((error=table->file->ha_update_row(table->record[1],
1401
table->record[0])) &&
1402
error != HA_ERR_RECORD_IS_THE_SAME)
1406
table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
1409
If (ignore && error == is ignorable) we don't have to
1410
do anything; otherwise...
1414
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
1415
flags|= ME_FATALERROR; /* Other handler errors are fatal */
1417
prepare_record_for_error_message(error, table);
1418
table->file->print_error(error,MYF(flags));
1424
if (error == HA_ERR_RECORD_IS_THE_SAME)
1429
/* non-transactional or transactional table got modified */
1430
/* either multi_update class' flag is raised in its branch */
1431
if (table->file->has_transactions())
1432
transactional_tables= 1;
1436
thd->transaction.stmt.modified_non_trans_table= true;
1444
TABLE *tmp_table= tmp_tables[offset];
1446
For updatable VIEW store rowid of the updated table and
1447
rowids of tables used in the CHECK OPTION condition.
1450
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
1454
tbl->file->position(tbl->record[0]);
1455
memcpy(tmp_table->field[field_num]->ptr,
1456
tbl->file->ref, tbl->file->ref_length);
1458
} while ((tbl= tbl_it++));
1460
/* Store regular updated fields in the row. */
1462
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
1463
*values_for_table[offset], 1);
1465
/* Write row, ignoring duplicated updates to a row */
1466
error= tmp_table->file->ha_write_row(tmp_table->record[0]);
1467
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
1470
create_myisam_from_heap(thd, tmp_table,
1471
tmp_table_param[offset].start_recinfo,
1472
&tmp_table_param[offset].recinfo,
1476
return(1); // Not a table_is_full error
1486
void multi_update::send_error(uint errcode,const char *err)
1488
/* First send error what ever it is ... */
1489
my_error(errcode, MYF(0), err);
1493
void multi_update::abort()
1495
/* the error was handled or nothing deleted and no side effects return */
1496
if (error_handled ||
1497
(!thd->transaction.stmt.modified_non_trans_table && !updated))
1500
If all tables that has been updated are trans safe then just do rollback.
1501
If not attempt to do remaining updates.
1506
assert(thd->transaction.stmt.modified_non_trans_table);
1507
if (do_update && table_count > 1)
1509
/* Add warning here */
1511
todo/fixme: do_update() is never called with the arg 1.
1512
should it change the signature to become argless?
1517
if (thd->transaction.stmt.modified_non_trans_table)
1520
The query has to binlog because there's a modified non-transactional table
1521
either from the query's list or via a stored routine: bug#13270,23333
1523
if (mysql_bin_log.is_open())
1526
THD::killed status might not have been set ON at time of an error
1527
got caught and if happens later the killed error is written
1530
thd->binlog_query(THD::ROW_QUERY_TYPE,
1531
thd->query, thd->query_length,
1532
transactional_tables, false);
1534
thd->transaction.all.modified_non_trans_table= true;
1536
assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
1540
int multi_update::do_updates()
1542
TABLE_LIST *cur_table;
1544
ha_rows org_updated;
1545
TABLE *table, *tmp_table;
1546
List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
1548
do_update= 0; // Don't retry this function
1551
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1553
bool can_compare_record;
1554
uint offset= cur_table->shared;
1556
table = cur_table->table;
1557
if (table == table_to_update)
1558
continue; // Already updated
1559
org_updated= updated;
1560
tmp_table= tmp_tables[cur_table->shared];
1561
tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache
1562
(void) table->file->ha_rnd_init(0);
1563
table->file->extra(HA_EXTRA_NO_CACHE);
1565
check_opt_it.rewind();
1566
while(TABLE *tbl= check_opt_it++)
1568
if (tbl->file->ha_rnd_init(1))
1570
tbl->file->extra(HA_EXTRA_CACHE);
1574
Setup copy functions to copy fields from temporary table
1576
List_iterator_fast<Item> field_it(*fields_for_table[offset]);
1577
Field **field= tmp_table->field +
1578
1 + unupdated_check_opt_tables.elements; // Skip row pointers
1579
Copy_field *copy_field_ptr= copy_field, *copy_field_end;
1580
for ( ; *field ; field++)
1582
Item_field *item= (Item_field* ) field_it++;
1583
(copy_field_ptr++)->set(item->field, *field, 0);
1585
copy_field_end=copy_field_ptr;
1587
if ((local_error = tmp_table->file->ha_rnd_init(1)))
1590
can_compare_record= (!(table->file->ha_table_flags() &
1591
HA_PARTIAL_COLUMN_READ) ||
1592
bitmap_is_subset(table->write_set,
1597
if (thd->killed && trans_safe)
1599
if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
1601
if (local_error == HA_ERR_END_OF_FILE)
1603
if (local_error == HA_ERR_RECORD_DELETED)
1604
continue; // May happen on dup key
1608
/* call rnd_pos() using rowids from temporary table */
1609
check_opt_it.rewind();
1615
tbl->file->rnd_pos(tbl->record[0],
1616
(uchar *) tmp_table->field[field_num]->ptr)))
1619
} while((tbl= check_opt_it++));
1621
table->status|= STATUS_UPDATED;
1622
store_record(table,record[1]);
1624
/* Copy data from temporary table to current table */
1625
for (copy_field_ptr=copy_field;
1626
copy_field_ptr != copy_field_end;
1628
(*copy_field_ptr->do_copy)(copy_field_ptr);
1630
if (!can_compare_record || compare_record(table))
1632
if ((local_error=table->file->ha_update_row(table->record[1],
1633
table->record[0])) &&
1634
local_error != HA_ERR_RECORD_IS_THE_SAME)
1637
table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
1640
if (local_error != HA_ERR_RECORD_IS_THE_SAME)
1647
if (updated != org_updated)
1649
if (table->file->has_transactions())
1650
transactional_tables= 1;
1653
trans_safe= 0; // Can't do safe rollback
1654
thd->transaction.stmt.modified_non_trans_table= true;
1657
(void) table->file->ha_rnd_end();
1658
(void) tmp_table->file->ha_rnd_end();
1659
check_opt_it.rewind();
1660
while (TABLE *tbl= check_opt_it++)
1661
tbl->file->ha_rnd_end();
1668
prepare_record_for_error_message(local_error, table);
1669
table->file->print_error(local_error,MYF(ME_FATALERROR));
1672
(void) table->file->ha_rnd_end();
1673
(void) tmp_table->file->ha_rnd_end();
1674
check_opt_it.rewind();
1675
while (TABLE *tbl= check_opt_it++)
1676
tbl->file->ha_rnd_end();
1678
if (updated != org_updated)
1680
if (table->file->has_transactions())
1681
transactional_tables= 1;
1685
thd->transaction.stmt.modified_non_trans_table= true;
1692
/* out: 1 if error, 0 if success */
1694
bool multi_update::send_eof()
1696
char buff[STRING_BUFFER_USUAL_SIZE];
1698
THD::killed_state killed_status= THD::NOT_KILLED;
1700
thd_proc_info(thd, "updating reference tables");
1703
Does updates for the last n - 1 tables, returns 0 if ok;
1704
error takes into account killed status gained in do_updates()
1706
int local_error = (table_count) ? do_updates() : 0;
1708
if local_error is not set ON until after do_updates() then
1709
later carried out killing should not affect binlogging.
1711
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
1712
thd_proc_info(thd, "end");
1715
Write the SQL statement to the binlog if we updated
1716
rows and we succeeded or if we updated some non
1717
transactional tables.
1719
The query has to binlog because there's a modified non-transactional table
1720
either from the query's list or via a stored routine: bug#13270,23333
1723
assert(trans_safe || !updated ||
1724
thd->transaction.stmt.modified_non_trans_table);
1725
if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
1727
if (mysql_bin_log.is_open())
1729
if (local_error == 0)
1731
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
1732
thd->query, thd->query_length,
1733
transactional_tables, false, killed_status) &&
1736
local_error= 1; // Rollback update
1739
if (thd->transaction.stmt.modified_non_trans_table)
1740
thd->transaction.all.modified_non_trans_table= true;
1742
if (local_error != 0)
1743
error_handled= true; // to force early leave from ::send_error()
1745
if (local_error > 0) // if the above log write did not fail ...
1747
/* Safety: If we haven't got an error before (can happen in do_updates) */
1748
my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
1753
id= thd->arg_of_last_insert_id_function ?
1754
thd->first_successful_insert_id_in_prev_stmt : 0;
1755
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
1756
(ulong) thd->cuted_fields);
1757
thd->row_count_func=
1758
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1759
::my_ok(thd, (ulong) thd->row_count_func, id, buff);