12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
29
29
#include "drizzled/records.h"
30
30
#include "drizzled/internal/my_sys.h"
31
31
#include "drizzled/internal/iocache.h"
32
#include "drizzled/transaction_services.h"
33
#include "drizzled/filesort.h"
35
#include <boost/dynamic_bitset.hpp>
38
35
using namespace std;
46
43
If we got a duplicate key error, we want to write an error
47
44
message containing the value of the duplicate key. If we do not have
48
all fields of the key value in getInsertRecord(), we need to re-read the
45
all fields of the key value in record[0], we need to re-read the
49
46
record with a proper read_set.
51
48
@param[in] error error number
55
52
static void prepare_record_for_error_message(int error, Table *table)
57
Field **field_p= NULL;
57
MyBitmap unique_map; /* Fields in offended unique. */
58
my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
62
61
Only duplicate key errors print the key value.
63
62
If storage engine does always read all columns, we have the value alraedy.
65
64
if ((error != HA_ERR_FOUND_DUPP_KEY) ||
66
! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
65
!(table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
76
75
/* Create unique_map with all fields used by that index. */
77
boost::dynamic_bitset<> unique_map(table->getShare()->sizeFields()); /* Fields in offended unique. */
78
table->mark_columns_used_by_index_no_reset(keynr, unique_map);
76
unique_map.init(unique_map_buf, table->s->fields);
77
table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
80
79
/* Subtract read_set and write_set. */
81
unique_map-= *table->read_set;
82
unique_map-= *table->write_set;
80
bitmap_subtract(&unique_map, table->read_set);
81
bitmap_subtract(&unique_map, table->write_set);
85
84
If the unique index uses columns that are neither in read_set
86
85
nor in write_set, we must re-read the record.
87
86
Otherwise no need to do anything.
89
if (unique_map.none())
88
if (unique_map.isClearAll())
92
91
/* Get identifier of last read record into table->cursor->ref. */
93
table->cursor->position(table->getInsertRecord());
92
table->cursor->position(table->record[0]);
94
93
/* Add all fields used by unique index to read_set. */
95
*table->read_set|= unique_map;
94
bitmap_union(table->read_set, &unique_map);
96
95
/* Read record that is identified by table->cursor->ref. */
97
(void) table->cursor->rnd_pos(table->getUpdateRecord(), table->cursor->ref);
96
(void) table->cursor->rnd_pos(table->record[1], table->cursor->ref);
98
97
/* Copy the newly read columns into the new record. */
99
for (field_p= table->getFields(); (field= *field_p); field_p++)
101
if (unique_map.test(field->field_index))
103
field->copy_from_tmp(table->getShare()->rec_buff_length);
98
for (field_p= table->field; (field= *field_p); field_p++)
99
if (unique_map.isBitSet(field->field_index))
100
field->copy_from_tmp(table->s->rec_buff_length);
130
125
int mysql_update(Session *session, TableList *table_list,
131
126
List<Item> &fields, List<Item> &values, COND *conds,
132
uint32_t order_num, Order *order,
127
uint32_t order_num, order_st *order,
133
128
ha_rows limit, enum enum_duplicates,
144
139
key_map old_covering_keys;
146
141
optimizer::SqlSelect *select= NULL;
148
143
Select_Lex *select_lex= &session->lex->select_lex;
150
145
List<Item> all_fields;
151
Session::killed_state_t killed_status= Session::NOT_KILLED;
146
Session::killed_state killed_status= Session::NOT_KILLED;
153
DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
148
DRIZZLE_UPDATE_START(session->query.c_str());
154
149
if (session->openTablesLock(table_list))
156
151
DRIZZLE_UPDATE_DONE(1, 0, 0);
161
156
table= table_list->table;
163
158
/* Calculate "table->covering_keys" based on the WHERE */
164
table->covering_keys= table->getShare()->keys_in_use;
159
table->covering_keys= table->s->keys_in_use;
165
160
table->quick_keys.reset();
167
162
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
169
DRIZZLE_UPDATE_DONE(1, 0, 0);
173
165
old_covering_keys= table->covering_keys; // Keys used in WHERE
174
166
/* Check the fields we are going to modify */
175
167
if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
177
DRIZZLE_UPDATE_DONE(1, 0, 0);
181
169
if (table->timestamp_field)
183
171
// Don't set timestamp column if this is modified
184
172
if (table->timestamp_field->isWriteSet())
186
173
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
190
176
if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
191
177
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
193
178
table->setWriteSet(table->timestamp_field->field_index);
198
182
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
200
184
free_underlaid_joins(session, select_lex);
201
DRIZZLE_UPDATE_DONE(1, 0, 0);
206
188
if (select_lex->inner_refs_list.elements &&
227
209
table->timestamp_field &&
228
210
(table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
229
211
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
231
*table->read_set|= *table->write_set;
212
bitmap_union(table->read_set, table->write_set);
233
213
// Don't count on usage of 'only index' when calculating which key to use
234
214
table->covering_keys.reset();
248
228
session->main_da.reset_diagnostics_area();
249
229
free_underlaid_joins(session, select_lex);
252
DRIZZLE_UPDATE_DONE(1, 0, 0);
231
goto abort; // Error in where
255
232
DRIZZLE_UPDATE_DONE(0, 0, 0);
256
233
session->my_ok(); // No matching records
283
260
if (used_index == MAX_KEY) // no index for sort order
284
261
used_index= table->cursor->key_used_on_scan;
285
262
if (used_index != MAX_KEY)
286
used_key_is_modified= is_key_used(table, used_index, *table->write_set);
263
used_key_is_modified= is_key_used(table, used_index, table->write_set);
312
289
NOTE: filesort will call table->prepare_for_position()
314
291
uint32_t length= 0;
315
SortField *sortorder;
292
SORT_FIELD *sortorder;
316
293
ha_rows examined_rows;
317
FileSort filesort(*session);
319
table->sort.io_cache= new internal::IO_CACHE;
295
table->sort.io_cache = new internal::IO_CACHE;
296
memset(table->sort.io_cache, 0, sizeof(internal::IO_CACHE));
321
298
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
322
(table->sort.found_records= filesort.run(table, sortorder, length,
324
examined_rows)) == HA_POS_ERROR)
299
(table->sort.found_records= filesort(session, table, sortorder, length,
343
321
internal::IO_CACHE tempfile;
344
if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
322
if (open_cached_file(&tempfile, drizzle_tmpdir,TEMP_PREFIX,
323
DISK_BUFFER_SIZE, MYF(MY_WME)))
349
326
/* If quick select is used, initialize it before retrieving rows. */
350
327
if (select && select->quick && select->quick->reset())
365
342
if (used_index == MAX_KEY || (select && select->quick))
367
info.init_read_record(session, table, select, 0, true);
343
init_read_record(&info,session,table,select,0,1);
371
info.init_read_record_idx(session, table, 1, used_index);
345
init_read_record_idx(&info, session, table, 1, used_index);
374
347
session->set_proc_info("Searching rows for update");
375
348
ha_rows tmp_limit= limit;
377
while (not(error= info.read_record(&info)) && not session->getKilled())
350
while (!(error=info.read_record(&info)) && !session->killed)
379
352
if (!(select && select->skip_record()))
381
354
if (table->cursor->was_semi_consistent_read())
382
355
continue; /* repeat the read of the same row if it still exists */
384
table->cursor->position(table->getInsertRecord());
357
table->cursor->position(table->record[0]);
385
358
if (my_b_write(&tempfile,table->cursor->ref,
386
359
table->cursor->ref_length))
398
371
table->cursor->unlock_row();
400
if (session->getKilled() && not error)
373
if (session->killed && !error)
401
374
error= 1; // Aborted
402
375
limit= tmp_limit;
403
376
table->cursor->try_semi_consistent_read(0);
404
info.end_read_record();
377
end_read_record(&info);
406
379
/* Change select to use tempfile */
417
390
select= new optimizer::SqlSelect;
418
391
select->head=table;
420
if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
393
if (reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
422
395
// Read row ptrs from this cursor
423
396
memcpy(select->file, &tempfile, sizeof(tempfile));
434
407
if (select && select->quick && select->quick->reset())
436
409
table->cursor->try_semi_consistent_read(1);
437
info.init_read_record(session, table, select, 0, true);
410
init_read_record(&info,session,table,select,0,1);
439
412
updated= found= 0;
464
437
the table handler is returning all columns OR if
465
438
if all updated columns are read
467
can_compare_record= (! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
468
table->write_set->is_subset_of(*table->read_set));
440
can_compare_record= (!(table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
441
bitmap_is_subset(table->write_set, table->read_set));
470
while (not (error=info.read_record(&info)) && not session->getKilled())
443
while (!(error=info.read_record(&info)) && !session->killed)
472
if (not (select && select->skip_record()))
445
if (!(select && select->skip_record()))
474
447
if (table->cursor->was_semi_consistent_read())
475
448
continue; /* repeat the read of the same row if it still exists */
477
450
table->storeRecord();
478
451
if (fill_record(session, fields, values))
481
* If we updated some rows before this one failed (updated > 0),
482
* then we will need to undo adding those records to the
483
* replication Statement message.
487
TransactionServices &ts= TransactionServices::singleton();
488
ts.removeStatementRecords(session, updated);
496
456
if (!can_compare_record || table->compare_record())
498
458
/* Non-batched update */
499
error= table->cursor->updateRecord(table->getUpdateRecord(),
500
table->getInsertRecord());
502
table->auto_increment_field_not_null= false;
459
error= table->cursor->ha_update_row(table->record[1],
504
461
if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
506
463
if (error != HA_ERR_RECORD_IS_THE_SAME)
512
469
table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
515
472
If (ignore && error is ignorable) we don't have to
516
473
do anything; otherwise...
521
478
flags|= ME_FATALERROR; /* Other handler errors are fatal */
523
480
prepare_record_for_error_message(error, table);
524
table->print_error(error,MYF(flags));
481
table->print_error(error,MYF(flags));
530
487
if (!--limit && using_limit)
546
503
It's assumed that if an error was set in combination with an effective
547
504
killed status then the error is due to killing.
549
killed_status= session->getKilled(); // get the status of the volatile
506
killed_status= session->killed; // get the status of the volatile
550
507
// simulated killing after the loop must be ineffective for binlogging
551
508
error= (killed_status == Session::NOT_KILLED)? error : 1;
566
523
last one without error. error > 0 means an error (e.g. unique key
567
524
violation and no IGNORE or REPLACE). error == 0 is also an error (if
568
525
preparing the record or invoking before triggers fails). See
569
autocommitOrRollback(error>=0) and return(error>=0) below.
526
ha_autocommit_or_rollback(error>=0) and return(error>=0) below.
570
527
Sometimes we want to binlog even if we updated no rows, in case user used
571
528
it to be sure master and slave are in same state.
587
544
char buff[STRING_BUFFER_USUAL_SIZE];
588
snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
545
sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
589
546
(ulong) session->cuted_fields);
590
547
session->row_count_func= updated;
595
552
session->main_da.reset_diagnostics_area();
596
553
session->my_ok((ulong) session->row_count_func, found, id, buff);
597
session->status_var.updated_row_count+= session->row_count_func;
599
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; /* calc cuted fields */
555
session->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
600
556
session->abort_on_warning= 0;
601
557
DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
602
558
return ((error >= 0 || session->is_error()) ? 1 : 0);
633
590
bool mysql_prepare_update(Session *session, TableList *table_list,
634
Item **conds, uint32_t order_num, Order *order)
591
Item **conds, uint32_t order_num, order_st *order)
636
593
List<Item> all_fields;
637
594
Select_Lex *select_lex= &session->lex->select_lex;
654
611
TableList *duplicate;
655
612
if ((duplicate= unique_table(table_list, table_list->next_global)))
657
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
614
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);