diff options
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r-- | sql/sql_update.cc | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d36c36ca592..cf30d1342c0 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -32,6 +32,7 @@ #include "sql_view.h" // check_key_in_view #include "sp_head.h" #include "sql_trigger.h" +#include "sql_statistics.h" #include "probes_mysql.h" #include "debug_sync.h" #include "key.h" // is_key_used @@ -342,19 +343,8 @@ int mysql_update(THD *thd, my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); DBUG_RETURN(1); } - if (table->timestamp_field) - { - // Don't set timestamp column if this is modified - if (bitmap_is_set(table->write_set, - table->timestamp_field->field_index)) - table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; - else - { - if (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE) - bitmap_set_bit(table->write_set, - table->timestamp_field->field_index); - } - } + if (table->default_field) + table->mark_default_fields_for_write(); #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check values */ @@ -389,7 +379,7 @@ int mysql_update(THD *thd, to compare records and detect data change. */ if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) && - (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE)) + table->default_field && table->has_default_function(true)) bitmap_union(table->read_set, table->write_set); // Don't count on usage of 'only index' when calculating which key to use table->covering_keys.clear_all(); @@ -404,6 +394,7 @@ int mysql_update(THD *thd, #endif /* Update the table->file->stats.records number */ table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); + set_statistics_for_table(thd, table); select= make_select(table, 0, 0, conds, 0, &error); if (error || !limit || thd->is_error() || @@ -501,13 +492,16 @@ int mysql_update(THD *thd, uint length= 0; SORT_FIELD *sortorder; ha_rows examined_rows; + ha_rows found_rows; table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL)); + MYF(MY_FAE | MY_ZEROFILL | + MY_THREAD_SPECIFIC)); if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) || (table->sort.found_records= filesort(thd, table, sortorder, length, - select, limit, 1, - &examined_rows)) + select, limit, + true, + &examined_rows, &found_rows)) == HA_POS_ERROR) { goto err; @@ -694,8 +688,7 @@ int mysql_update(THD *thd, continue; /* repeat the read of the same row if it still exists */ store_record(table,record[1]); - if (fill_record_n_invoke_before_triggers(thd, fields, values, 0, - table->triggers, + if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0, TRG_EVENT_UPDATE)) break; /* purecov: inspected */ @@ -703,6 +696,11 @@ int mysql_update(THD *thd, if (!can_compare_record || compare_record(table)) { + if (table->default_field && table->update_default_fields()) + { + error= 1; + break; + } if ((res= table_list->view_check_option(thd, ignore)) != VIEW_CHECK_OK) { @@ -1249,11 +1247,6 @@ int mysql_multi_update_prepare(THD *thd) while ((tl= ti++)) { TABLE *table= tl->table; - /* Only set timestamp column if this is not modified */ - if (table->timestamp_field && - bitmap_is_set(table->write_set, - table->timestamp_field->field_index)) - table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; /* if table will be updated then check that it is unique */ if (table->map & tables_for_update) @@ -1503,8 +1496,7 @@ int multi_update::prepare(List<Item> ¬_used_values, to compare records and detect data change. */ if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) && - (((uint) table->timestamp_field_type) & - TIMESTAMP_AUTO_SET_ON_UPDATE)) + table->default_field && table->has_default_function(true)) bitmap_union(table->read_set, table->write_set); } } @@ -1892,10 +1884,10 @@ int multi_update::send_data(List<Item> ¬_used_values) table->status|= STATUS_UPDATED; store_record(table,record[1]); - if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset], + if (fill_record_n_invoke_before_triggers(thd, table, *fields_for_table[offset], *values_for_table[offset], 0, - table->triggers, - TRG_EVENT_UPDATE)) + TRG_EVENT_UPDATE) || + (table->default_field && table->update_default_fields())) DBUG_RETURN(1); /* @@ -1996,7 +1988,7 @@ int multi_update::send_data(List<Item> ¬_used_values) } while ((tbl= tbl_it++)); /* Store regular updated fields in the row. */ - fill_record(thd, + fill_record(thd, tmp_table, tmp_table->field + 1 + unupdated_check_opt_tables.elements, *values_for_table[offset], TRUE, FALSE); @@ -2186,7 +2178,10 @@ int multi_update::do_updates() for (copy_field_ptr=copy_field; copy_field_ptr != copy_field_end; copy_field_ptr++) + { (*copy_field_ptr->do_copy)(copy_field_ptr); + copy_field_ptr->to_field->set_has_explicit_value(); + } if (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, @@ -2196,6 +2191,8 @@ int multi_update::do_updates() if (!can_compare_record || compare_record(table)) { int error; + if (table->default_field && (error= table->update_default_fields())) + goto err2; if ((error= cur_table->view_check_option(thd, ignore)) != VIEW_CHECK_OK) { |