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;
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
92
table->cursor->position(table->getInsertRecord());
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
96
(void) table->cursor->rnd_pos(table->getUpdateRecord(), 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);
313
302
uint32_t length= 0;
314
303
SortField *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()))
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 */
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;
611
608
bool mysql_prepare_update(Session *session, TableList *table_list,
612
Item **conds, uint32_t order_num, Order *order)
609
Item **conds, uint32_t order_num, order_st *order)
614
611
List<Item> all_fields;
615
612
Select_Lex *select_lex= &session->lex->select_lex;
632
629
TableList *duplicate;
633
630
if ((duplicate= unique_table(table_list, table_list->next_global)))
635
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
632
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);