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>
36 #include <drizzled/key.h>
37 #include <drizzled/sql_lex.h>
38 #include <drizzled/diagnostics_area.h>
39 #include <drizzled/util/test.h>
40 #include <drizzled/statistics_variables.h>
41 #include <drizzled/session/transactions.h>
43 #include <boost/dynamic_bitset.hpp>
64 Field **field_p= NULL;
72 if ((error != HA_ERR_FOUND_DUPP_KEY) ||
73 ! (table->
cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
84 boost::dynamic_bitset<> unique_map(table->getShare()->sizeFields());
85 table->mark_columns_used_by_index_no_reset(keynr, unique_map);
88 unique_map-= *table->read_set;
89 unique_map-= *table->write_set;
96 if (unique_map.none())
100 table->
cursor->position(table->getInsertRecord());
102 *table->read_set|= unique_map;
104 (void) table->
cursor->rnd_pos(table->getUpdateRecord(), table->
cursor->ref);
106 for (field_p= table->getFields(); (field= *field_p); field_p++)
108 if (unique_map.test(field->position()))
110 field->copy_from_tmp(table->getShare()->rec_buff_length);
139 uint32_t order_num,
Order *order,
140 ha_rows limit,
enum enum_duplicates,
143 bool using_limit= limit != HA_POS_ERROR;
144 bool used_key_is_modified;
145 bool transactional_table;
147 uint used_index= MAX_KEY, dup_key_found;
148 bool need_sort=
true;
149 ha_rows updated, found;
150 key_map old_covering_keys;
154 Select_Lex *select_lex= &session->lex().select_lex;
157 Session::killed_state_t killed_status= Session::NOT_KILLED;
159 DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
162 DRIZZLE_UPDATE_DONE(1, 0, 0);
167 table= table_list->
table;
170 table->covering_keys= table->getShare()->keys_in_use;
171 table->quick_keys.reset();
173 if (prepare_update(session, table_list, &conds, order_num, order))
175 DRIZZLE_UPDATE_DONE(1, 0, 0);
179 old_covering_keys= table->covering_keys;
181 if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
183 DRIZZLE_UPDATE_DONE(1, 0, 0);
192 table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
196 if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
197 table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
204 if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
207 DRIZZLE_UPDATE_DONE(1, 0, 0);
212 if (select_lex->inner_refs_list.size() &&
213 fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
215 DRIZZLE_UPDATE_DONE(1, 0, 0);
221 Item::cond_result cond_value;
223 if (cond_value == Item::COND_FALSE)
232 if (table->
cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
234 (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
235 table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
237 *table->read_set|= *table->write_set;
240 table->covering_keys.reset();
243 table->
cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
245 select= optimizer::make_select(table, 0, 0, conds, 0, &error);
246 if (error || !limit ||
247 (select && select->check_quick(session,
false, limit)))
258 DRIZZLE_UPDATE_DONE(1, 0, 0);
261 DRIZZLE_UPDATE_DONE(0, 0, 0);
265 if (!select && limit != HA_POS_ERROR)
267 if ((used_index= optimizer::get_index_for_order(table, order, limit)) != MAX_KEY)
271 if (table->quick_keys.none())
273 session->server_status|=SERVER_QUERY_NO_INDEX_USED;
276 table->mark_columns_needed_for_update();
280 if (select && select->
quick)
283 used_key_is_modified= (!select->
quick->unique_key_range() &&
288 used_key_is_modified= 0;
289 if (used_index == MAX_KEY)
290 used_index= table->
cursor->key_used_on_scan;
291 if (used_index != MAX_KEY)
292 used_key_is_modified= is_key_used(table, used_index, *table->write_set);
296 if (used_key_is_modified || order)
302 if (used_index < MAX_KEY && old_covering_keys.test(used_index))
305 table->mark_columns_used_by_index(used_index);
309 table->use_all_columns();
313 if (order && (need_sort || used_key_is_modified))
322 ha_rows examined_rows;
326 sortorder=make_unireg_sortorder(order, &length, NULL);
328 if ((table->sort.found_records= filesort.
run(table, sortorder, length, select, limit, 1, examined_rows)) == HA_POS_ERROR)
345 if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
366 if (used_index == MAX_KEY || (select && select->
quick))
368 if ((error= info.init_read_record(session, table, select, 0,
true)))
378 ha_rows tmp_limit= limit;
380 while (not(error= info.read_record(&info)) && not session->getKilled())
382 if (!(select && select->skip_record()))
387 table->
cursor->position(table->getInsertRecord());
393 if (!--limit && using_limit)
400 table->
cursor->unlock_row();
402 if (session->getKilled() && not error)
406 info.end_read_record();
411 safe_delete(select->
quick);
412 if (select->free_cond)
424 memcpy(select->
file, &tempfile,
sizeof(tempfile));
429 table->restore_column_maps_after_mark_index();
433 table->
cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
438 if ((error= info.init_read_record(session, table, select, 0,
true)))
452 session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
456 transactional_table= table->
cursor->has_transactions();
457 session->setAbortOnWarning(test(!ignore));
463 if (table->
cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
464 table->prepare_for_position();
466 while (not (error=info.read_record(&info)) && not session->getKilled())
468 if (not (select && select->skip_record()))
473 table->storeRecord();
474 if (fill_record(session, fields, values))
482 error= table->
cursor->updateRecord(table->getUpdateRecord(),
483 table->getInsertRecord());
485 table->auto_increment_field_not_null=
false;
487 if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
489 if (error != HA_ERR_RECORD_IS_THE_SAME)
504 flags|= ME_FATALERROR;
507 table->print_error(error,MYF(flags));
513 if (!--limit && using_limit)
520 table->
cursor->unlock_row();
530 killed_status= session->getKilled();
532 error= (killed_status == Session::NOT_KILLED)? error : 1;
534 updated-= dup_key_found;
537 if (!transactional_table && updated > 0)
540 info.end_read_record();
543 table->
cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
561 id= session->arg_of_last_insert_id_function ?
566 char buff[STRING_BUFFER_USUAL_SIZE];
567 snprintf(buff,
sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
575 session->
my_ok((ulong) session->rowCount(), found, id, buff);
576 session->status_var.updated_row_count+= session->rowCount();
578 session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
579 session->setAbortOnWarning(
false);
580 DRIZZLE_UPDATE_DONE((error >= 0 || session->
is_error()), found, updated);
581 return ((error >= 0 || session->
is_error()) ? 1 : 0);
585 table->print_error(error,MYF(0));
592 table->
cursor->extra(HA_EXTRA_NO_KEYREAD);
594 session->setAbortOnWarning(
false);
596 DRIZZLE_UPDATE_DONE(1, 0, 0);
615 bool prepare_update(Session *session, TableList *table_list,
616 Item **conds, uint32_t order_num, Order *order)
618 List<Item> all_fields;
619 Select_Lex *select_lex= &session->lex().select_lex;
621 session->lex().allow_sum_func= 0;
623 if (setup_tables_and_check_access(session, &select_lex->context, &select_lex->top_join_list, table_list, &select_lex->leaf_tables,
false) ||
624 session->setup_conds(table_list, conds))
626 select_lex->setup_ref_array(session, order_num);
627 if (
setup_order(session, select_lex->ref_pointer_array, table_list, all_fields, all_fields, order))
631 if (unique_table(table_list, table_list->next_global))
633 my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
void my_ok(ha_rows affected_rows=0, ha_rows found_rows_arg=0, uint64_t passed_id=0, const char *message=NULL)
void set_proc_info(const char *info)
bool hasModifiedNonTransData() const
virtual bool is_keys_used(const boost::dynamic_bitset<> &fields)
COND * remove_eq_conds(Session *session, COND *cond, Item::cond_result *cond_value)
Table * table
opened table
virtual bool was_semi_consistent_read()
QuickSelectInterface * quick
uint64_t first_successful_insert_id_in_prev_stmt
virtual int reset(void)=0
ha_rows run(Table *table, SortField *sortorder, uint32_t s_length, optimizer::SqlSelect *select, ha_rows max_rows, bool sort_positions, ha_rows &examined_rows)
int update_query(Session *session, TableList *tables, List< Item > &fields, List< Item > &values, COND *conds, uint32_t order_num, Order *order, ha_rows limit, enum enum_duplicates handle_duplicates, bool ignore)
static void prepare_record_for_error_message(int error, Table *table)
void markModifiedNonTransData()
int init_read_record_idx(Session *session, Table *table, bool print_error, uint32_t idx) __attribute__((warn_unused_result))
uint32_t get_dup_key(int error) const
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables, List< Item > &fields, List< Item > &all_fields, Order *order)
field::Epoch * timestamp_field
void free_underlaid_joins(Session *session, Select_Lex *select)
void reset_diagnostics_area()
bool records_are_comparable()
virtual bool is_fatal_error(int error, uint32_t flags)
virtual void try_semi_consistent_read(bool)
internal::io_cache_st * file
bool reinit_io_cache(cache_type type_arg, my_off_t seek_offset, bool use_async_io, bool clear_cache)
Reset the cache.
bool openTablesLock(TableList *)