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->getMutableShare()->sizeFields());
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
98
for (field_p= table->getFields(); (field= *field_p); field_p++)
101
if (unique_map.test(field->position()))
100
if (unique_map.isBitSet(field->field_index))
103
102
field->copy_from_tmp(table->getShare()->rec_buff_length);
130
130
int mysql_update(Session *session, TableList *table_list,
131
131
List<Item> &fields, List<Item> &values, COND *conds,
132
uint32_t order_num, Order *order,
132
uint32_t order_num, order_st *order,
133
133
ha_rows limit, enum enum_duplicates,
136
136
bool using_limit= limit != HA_POS_ERROR;
137
137
bool used_key_is_modified;
138
138
bool transactional_table;
139
bool can_compare_record;
140
141
uint used_index= MAX_KEY, dup_key_found;
141
142
bool need_sort= true;
147
148
Select_Lex *select_lex= &session->lex->select_lex;
149
150
List<Item> all_fields;
150
Session::killed_state_t killed_status= Session::NOT_KILLED;
151
Session::killed_state killed_status= Session::NOT_KILLED;
152
DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
153
DRIZZLE_UPDATE_START(session->query.c_str());
153
154
if (session->openTablesLock(table_list))
155
156
DRIZZLE_UPDATE_DONE(1, 0, 0);
164
165
table->quick_keys.reset();
166
167
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
168
DRIZZLE_UPDATE_DONE(1, 0, 0);
172
170
old_covering_keys= table->covering_keys; // Keys used in WHERE
173
171
/* Check the fields we are going to modify */
174
172
if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
176
DRIZZLE_UPDATE_DONE(1, 0, 0);
180
174
if (table->timestamp_field)
182
176
// Don't set timestamp column if this is modified
189
183
if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
190
184
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
192
table->setWriteSet(table->timestamp_field->position());
186
table->setWriteSet(table->timestamp_field->field_index);
197
191
if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
199
193
free_underlaid_joins(session, select_lex);
200
DRIZZLE_UPDATE_DONE(1, 0, 0);
205
197
if (select_lex->inner_refs_list.elements &&
227
219
(table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
228
220
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
230
*table->read_set|= *table->write_set;
222
bitmap_union(table->read_set, table->write_set);
232
224
// Don't count on usage of 'only index' when calculating which key to use
233
225
table->covering_keys.reset();
247
239
session->main_da.reset_diagnostics_area();
248
240
free_underlaid_joins(session, select_lex);
251
DRIZZLE_UPDATE_DONE(1, 0, 0);
242
goto abort; // Error in where
254
243
DRIZZLE_UPDATE_DONE(0, 0, 0);
255
244
session->my_ok(); // No matching records
282
271
if (used_index == MAX_KEY) // no index for sort order
283
272
used_index= table->cursor->key_used_on_scan;
284
273
if (used_index != MAX_KEY)
285
used_key_is_modified= is_key_used(table, used_index, *table->write_set);
274
used_key_is_modified= is_key_used(table, used_index, table->write_set);
311
300
NOTE: filesort will call table->prepare_for_position()
313
302
uint32_t length= 0;
314
SortField *sortorder;
303
SORT_FIELD *sortorder;
315
304
ha_rows examined_rows;
316
FileSort filesort(*session);
318
table->sort.io_cache= new internal::IO_CACHE;
306
table->sort.io_cache = new internal::IO_CACHE;
320
308
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
321
(table->sort.found_records= filesort.run(table, sortorder, length,
323
examined_rows)) == HA_POS_ERROR)
309
(table->sort.found_records= filesort(session, table, sortorder, length,
342
331
internal::IO_CACHE tempfile;
343
if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
332
if (open_cached_file(&tempfile, drizzle_tmpdir.c_str(),TEMP_PREFIX,
333
DISK_BUFFER_SIZE, MYF(MY_WME)))
348
336
/* If quick select is used, initialize it before retrieving rows. */
349
337
if (select && select->quick && select->quick->reset())
373
361
session->set_proc_info("Searching rows for update");
374
362
ha_rows tmp_limit= limit;
376
while (not(error= info.read_record(&info)) && not session->getKilled())
364
while (!(error=info.read_record(&info)) && !session->killed)
378
366
if (!(select && select->skip_record()))
380
368
if (table->cursor->was_semi_consistent_read())
381
369
continue; /* repeat the read of the same row if it still exists */
383
table->cursor->position(table->getInsertRecord());
371
table->cursor->position(table->record[0]);
384
372
if (my_b_write(&tempfile,table->cursor->ref,
385
373
table->cursor->ref_length))
416
404
select= new optimizer::SqlSelect;
417
405
select->head=table;
419
if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
407
if (reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
421
409
// Read row ptrs from this cursor
422
410
memcpy(select->file, &tempfile, sizeof(tempfile));
458
446
if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
459
447
table->prepare_for_position();
461
while (not (error=info.read_record(&info)) && not session->getKilled())
450
We can use compare_record() to optimize away updates if
451
the table handler is returning all columns OR if
452
if all updated columns are read
454
can_compare_record= (!(table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
455
bitmap_is_subset(table->write_set, table->read_set));
457
while (!(error=info.read_record(&info)) && !session->killed)
463
if (not (select && select->skip_record()))
459
if (!(select && select->skip_record()))
465
461
if (table->cursor->was_semi_consistent_read())
466
462
continue; /* repeat the read of the same row if it still exists */
474
if (! table->records_are_comparable() || table->compare_records())
470
if (!can_compare_record || table->compare_record())
476
472
/* Non-batched update */
477
error= table->cursor->updateRecord(table->getUpdateRecord(),
478
table->getInsertRecord());
473
error= table->cursor->updateRecord(table->record[1],
480
476
table->auto_increment_field_not_null= false;
482
478
if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
484
480
if (error != HA_ERR_RECORD_IS_THE_SAME)
490
486
table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
493
489
If (ignore && error is ignorable) we don't have to
494
490
do anything; otherwise...
499
495
flags|= ME_FATALERROR; /* Other handler errors are fatal */
501
497
prepare_record_for_error_message(error, table);
502
table->print_error(error,MYF(flags));
498
table->print_error(error,MYF(flags));
508
504
if (!--limit && using_limit)
524
520
It's assumed that if an error was set in combination with an effective
525
521
killed status then the error is due to killing.
527
killed_status= session->getKilled(); // get the status of the volatile
523
killed_status= session->killed; // get the status of the volatile
528
524
// simulated killing after the loop must be ineffective for binlogging
529
525
error= (killed_status == Session::NOT_KILLED)? error : 1;
573
569
session->main_da.reset_diagnostics_area();
574
570
session->my_ok((ulong) session->row_count_func, found, id, buff);
575
session->status_var.updated_row_count+= session->row_count_func;
577
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; /* calc cuted fields */
572
session->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
578
573
session->abort_on_warning= 0;
579
574
DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
580
575
return ((error >= 0 || session->is_error()) ? 1 : 0);
611
607
bool mysql_prepare_update(Session *session, TableList *table_list,
612
Item **conds, uint32_t order_num, Order *order)
608
Item **conds, uint32_t order_num, order_st *order)
614
610
List<Item> all_fields;
615
611
Select_Lex *select_lex= &session->lex->select_lex;
632
628
TableList *duplicate;
633
629
if ((duplicate= unique_table(table_list, table_list->next_global)))
635
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
631
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);