18
18
Single table and multi table updates of tables.
19
Multi-table updates were introduced by Sinisa & Monty
23
#include <drizzled/sql_select.h>
24
#include <drizzled/error.h>
25
#include <drizzled/probes.h>
26
#include <drizzled/sql_base.h>
27
#include <drizzled/field/epoch.h>
28
#include <drizzled/sql_parse.h>
29
#include <drizzled/optimizer/range.h>
30
#include <drizzled/records.h>
31
#include <drizzled/internal/my_sys.h>
32
#include <drizzled/internal/iocache.h>
33
#include <drizzled/transaction_services.h>
34
#include <drizzled/filesort.h>
35
#include <drizzled/plugin/storage_engine.h>
22
#include "drizzled/sql_select.h"
23
#include "drizzled/error.h"
24
#include "drizzled/probes.h"
25
#include "drizzled/sql_base.h"
26
#include "drizzled/field/timestamp.h"
27
#include "drizzled/sql_parse.h"
28
#include "drizzled/optimizer/range.h"
29
#include "drizzled/records.h"
30
#include "drizzled/internal/my_sys.h"
31
#include "drizzled/internal/iocache.h"
32
#include "drizzled/transaction_services.h"
37
34
#include <boost/dynamic_bitset.hpp>
100
97
/* Copy the newly read columns into the new record. */
101
98
for (field_p= table->getFields(); (field= *field_p); field_p++)
103
if (unique_map.test(field->position()))
100
if (unique_map.test(field->field_index))
105
102
field->copy_from_tmp(table->getShare()->rec_buff_length);
132
int update_query(Session *session, TableList *table_list,
129
int mysql_update(Session *session, TableList *table_list,
133
130
List<Item> &fields, List<Item> &values, COND *conds,
134
uint32_t order_num, Order *order,
131
uint32_t order_num, order_st *order,
135
132
ha_rows limit, enum enum_duplicates,
138
135
bool using_limit= limit != HA_POS_ERROR;
139
136
bool used_key_is_modified;
140
137
bool transactional_table;
138
bool can_compare_record;
142
140
uint used_index= MAX_KEY, dup_key_found;
143
141
bool need_sort= true;
144
142
ha_rows updated, found;
147
145
optimizer::SqlSelect *select= NULL;
149
Select_Lex *select_lex= &session->getLex()->select_lex;
147
Select_Lex *select_lex= &session->lex->select_lex;
151
149
List<Item> all_fields;
152
Session::killed_state_t killed_status= Session::NOT_KILLED;
150
Session::killed_state killed_status= Session::NOT_KILLED;
154
DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
152
DRIZZLE_UPDATE_START(session->query.c_str());
155
153
if (session->openTablesLock(table_list))
157
155
DRIZZLE_UPDATE_DONE(1, 0, 0);
165
163
table->covering_keys= table->getShare()->keys_in_use;
166
164
table->quick_keys.reset();
168
if (prepare_update(session, table_list, &conds, order_num, order))
166
if (mysql_prepare_update(session, table_list, &conds, order_num, order))
170
168
DRIZZLE_UPDATE_DONE(1, 0, 0);
191
189
if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
192
190
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
194
table->setWriteSet(table->timestamp_field->position());
192
table->setWriteSet(table->timestamp_field->field_index);
208
206
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
210
208
DRIZZLE_UPDATE_DONE(1, 0, 0);
249
247
session->main_da.reset_diagnostics_area();
250
248
free_underlaid_joins(session, select_lex);
251
if (error || session->is_error())
253
251
DRIZZLE_UPDATE_DONE(1, 0, 0);
315
313
uint32_t length= 0;
316
314
SortField *sortorder;
317
315
ha_rows examined_rows;
318
FileSort filesort(*session);
320
table->sort.io_cache= new internal::IO_CACHE;
317
table->sort.io_cache = new internal::IO_CACHE;
322
319
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
323
(table->sort.found_records= filesort.run(table, sortorder, length,
325
examined_rows)) == HA_POS_ERROR)
320
(table->sort.found_records= filesort(session, table, sortorder, length,
343
342
internal::IO_CACHE tempfile;
344
if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
343
if (open_cached_file(&tempfile, drizzle_tmpdir.c_str(),TEMP_PREFIX,
344
DISK_BUFFER_SIZE, MYF(MY_WME)))
349
347
/* If quick select is used, initialize it before retrieving rows. */
350
348
if (select && select->quick && select->quick->reset())
365
363
if (used_index == MAX_KEY || (select && select->quick))
367
if ((error= info.init_read_record(session, table, select, 0, true)))
365
info.init_read_record(session, table, select, 0, true);
372
if ((error= info.init_read_record_idx(session, table, 1, used_index)))
369
info.init_read_record_idx(session, table, 1, used_index);
376
372
session->set_proc_info("Searching rows for update");
377
373
ha_rows tmp_limit= limit;
379
while (not(error= info.read_record(&info)) && not session->getKilled())
375
while (!(error=info.read_record(&info)) && !session->killed)
381
377
if (!(select && select->skip_record()))
408
404
/* Change select to use tempfile */
411
safe_delete(select->quick);
407
delete select->quick;
412
408
if (select->free_cond)
413
409
delete select->cond;
418
select= new optimizer::SqlSelect();
415
select= new optimizer::SqlSelect;
419
416
select->head=table;
421
if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
418
if (reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
423
420
// Read row ptrs from this cursor
424
421
memcpy(select->file, &tempfile, sizeof(tempfile));
435
432
if (select && select->quick && select->quick->reset())
437
434
table->cursor->try_semi_consistent_read(1);
438
if ((error= info.init_read_record(session, table, select, 0, true)))
435
info.init_read_record(session, table, select, 0, true);
443
437
updated= found= 0;
454
448
session->set_proc_info("Updating");
456
450
transactional_table= table->cursor->has_transactions();
457
session->setAbortOnWarning(test(!ignore));
451
session->abort_on_warning= test(!ignore);
460
454
Assure that we can use position()
463
457
if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
464
458
table->prepare_for_position();
466
while (not (error=info.read_record(&info)) && not session->getKilled())
461
We can use compare_record() to optimize away updates if
462
the table handler is returning all columns OR if
463
if all updated columns are read
465
can_compare_record= (! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
466
table->write_set->is_subset_of(*table->read_set));
468
while (! (error=info.read_record(&info)) && !session->killed)
468
if (not (select && select->skip_record()))
470
if (! (select && select->skip_record()))
470
472
if (table->cursor->was_semi_consistent_read())
471
473
continue; /* repeat the read of the same row if it still exists */
473
475
table->storeRecord();
474
476
if (fill_record(session, fields, values))
479
* If we updated some rows before this one failed (updated > 0),
480
* then we will need to undo adding those records to the
481
* replication Statement message.
485
TransactionServices &ts= TransactionServices::singleton();
486
ts.removeStatementRecords(session, updated);
479
if (! table->records_are_comparable() || table->compare_records())
494
if (!can_compare_record || table->compare_record())
481
496
/* Non-batched update */
482
497
error= table->cursor->updateRecord(table->getUpdateRecord(),
529
544
It's assumed that if an error was set in combination with an effective
530
545
killed status then the error is due to killing.
532
killed_status= session->getKilled(); // get the status of the volatile
547
killed_status= session->killed; // get the status of the volatile
533
548
// simulated killing after the loop must be ineffective for binlogging
534
549
error= (killed_status == Session::NOT_KILLED)? error : 1;
578
593
session->main_da.reset_diagnostics_area();
579
session->my_ok((ulong) session->rowCount(), found, id, buff);
580
session->status_var.updated_row_count+= session->rowCount();
594
session->my_ok((ulong) session->row_count_func, found, id, buff);
595
session->status_var.updated_row_count+= session->row_count_func;
582
597
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; /* calc cuted fields */
583
session->setAbortOnWarning(false);
598
session->abort_on_warning= 0;
584
599
DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
585
600
return ((error >= 0 || session->is_error()) ? 1 : 0);
589
table->print_error(error,MYF(0));
592
604
free_underlaid_joins(session, select_lex);
593
605
if (table->key_read)
595
607
table->key_read=0;
596
608
table->cursor->extra(HA_EXTRA_NO_KEYREAD);
598
session->setAbortOnWarning(false);
610
session->abort_on_warning= 0;
600
612
DRIZZLE_UPDATE_DONE(1, 0, 0);
619
bool prepare_update(Session *session, TableList *table_list,
620
Item **conds, uint32_t order_num, Order *order)
631
bool mysql_prepare_update(Session *session, TableList *table_list,
632
Item **conds, uint32_t order_num, order_st *order)
622
634
List<Item> all_fields;
623
Select_Lex *select_lex= &session->getLex()->select_lex;
635
Select_Lex *select_lex= &session->lex->select_lex;
625
session->getLex()->allow_sum_func= 0;
637
session->lex->allow_sum_func= 0;
627
639
if (setup_tables_and_check_access(session, &select_lex->context,
628
640
&select_lex->top_join_list,