diff options
-rw-r--r-- | sql/sql_base.cc | 17 | ||||
-rw-r--r-- | sql/sql_delete.cc | 4 | ||||
-rw-r--r-- | sql/sql_update.cc | 11 | ||||
-rw-r--r-- | sql/table.cc | 66 | ||||
-rw-r--r-- | sql/table.h | 6 |
5 files changed, 57 insertions, 47 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6e448c00748..86f2b24829f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7837,9 +7837,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values, /* Update virtual fields */ thd->abort_on_warning= FALSE; if (vcol_table && vcol_table->vfield && - update_virtual_fields(thd, vcol_table, - vcol_table->triggers ? VCOL_UPDATE_ALL : - VCOL_UPDATE_FOR_WRITE)) + update_virtual_fields(thd, vcol_table, VCOL_UPDATE_FOR_WRITE)) goto err; thd->abort_on_warning= save_abort_on_warning; thd->no_errors= save_no_errors; @@ -7990,9 +7988,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, if (item_field && table->vfield) { DBUG_ASSERT(table == item_field->field->table); - result= update_virtual_fields(thd, table, - table->triggers ? VCOL_UPDATE_ALL : - VCOL_UPDATE_FOR_WRITE); + result= update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE); } } } @@ -8085,9 +8081,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, /* Update virtual fields */ thd->abort_on_warning= FALSE; if (table->vfield && - update_virtual_fields(thd, table, - table->triggers ? VCOL_UPDATE_ALL : - VCOL_UPDATE_FOR_WRITE)) + update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE)) goto err; thd->abort_on_warning= abort_on_warning_saved; DBUG_RETURN(thd->is_error()); @@ -8141,10 +8135,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, Field **ptr, { DBUG_ASSERT(table == (*ptr)->table); if (table->vfield) - result= update_virtual_fields(thd, table, - table->triggers ? - VCOL_UPDATE_ALL : - VCOL_UPDATE_FOR_WRITE); + result= update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE); } return result; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 4f9afca2f6d..a4e43f87bd0 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -561,9 +561,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { explain->tracker.on_record_read(); if (table->vfield) - update_virtual_fields(thd, table, - table->triggers ? VCOL_UPDATE_ALL : - VCOL_UPDATE_FOR_READ); + update_virtual_fields(thd, table, VCOL_UPDATE_FOR_READ_WRITE); thd->inc_examined_row_count(1); // thd->is_error() is tested to disallow delete row on error if (!select || select->skip_record(thd) > 0) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b452e4fe6ae..3a4bffeb454 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -619,9 +619,7 @@ int mysql_update(THD *thd, { explain->buf_tracker.on_record_read(); if (table->vfield) - update_virtual_fields(thd, table, - table->triggers ? VCOL_UPDATE_ALL : - VCOL_UPDATE_FOR_READ); + update_virtual_fields(thd, table, VCOL_UPDATE_FOR_READ_WRITE); thd->inc_examined_row_count(1); if (!select || (error= select->skip_record(thd)) > 0) { @@ -738,9 +736,7 @@ int mysql_update(THD *thd, { explain->tracker.on_record_read(); if (table->vfield) - update_virtual_fields(thd, table, - table->triggers ? VCOL_UPDATE_ALL : - VCOL_UPDATE_FOR_READ); + update_virtual_fields(thd, table, VCOL_UPDATE_FOR_READ_WRITE); thd->inc_examined_row_count(1); if (!select || select->skip_record(thd) > 0) { @@ -2411,8 +2407,7 @@ int multi_update::do_updates() (error= table->update_default_fields(1, ignore))) goto err2; if (table->vfield && - update_virtual_fields(thd, table, - (table->triggers ? VCOL_UPDATE_ALL : VCOL_UPDATE_FOR_WRITE))) + update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE)) goto err2; if ((error= cur_table->view_check_option(thd, ignore)) != VIEW_CHECK_OK) diff --git a/sql/table.cc b/sql/table.cc index 1e3bc161c6f..ad7e3e17cad 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6200,6 +6200,7 @@ void TABLE::mark_auto_increment_column() void TABLE::mark_columns_needed_for_delete() { + bool need_signal= false; mark_columns_per_binlog_row_image(); if (triggers) @@ -6212,7 +6213,7 @@ void TABLE::mark_columns_needed_for_delete() if ((*reg_field)->flags & PART_KEY_FLAG) bitmap_set_bit(read_set, (*reg_field)->field_index); } - file->column_bitmaps_signal(); + need_signal= true; } if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) { @@ -6226,11 +6227,17 @@ void TABLE::mark_columns_needed_for_delete() else { mark_columns_used_by_index_no_reset(s->primary_key, read_set); - file->column_bitmaps_signal(); + need_signal= true; } } if (check_constraints) + { mark_check_constraint_columns_for_read(); + need_signal= true; + } + + if (need_signal) + file->column_bitmaps_signal(); } @@ -6255,6 +6262,7 @@ void TABLE::mark_columns_needed_for_delete() void TABLE::mark_columns_needed_for_update() { DBUG_ENTER("mark_columns_needed_for_update"); + bool need_signal= false; mark_columns_per_binlog_row_image(); @@ -6270,7 +6278,7 @@ void TABLE::mark_columns_needed_for_update() if (merge_keys.is_overlapping((*reg_field)->part_of_key)) bitmap_set_bit(read_set, (*reg_field)->field_index); } - file->column_bitmaps_signal(); + need_signal= true; } if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) { @@ -6284,16 +6292,19 @@ void TABLE::mark_columns_needed_for_update() else { mark_columns_used_by_index_no_reset(s->primary_key, read_set); - file->column_bitmaps_signal(); + need_signal= true; } } if (default_field) mark_default_fields_for_write(FALSE); /* Mark all virtual columns needed for update */ if (vfield) - mark_virtual_columns_for_write(FALSE); + need_signal|= mark_virtual_columns_for_write(FALSE); if (check_constraints) + { mark_check_constraint_columns_for_read(); + need_signal= true; + } /* If a timestamp field settable on UPDATE is present then to avoid wrong @@ -6302,7 +6313,12 @@ void TABLE::mark_columns_needed_for_update() */ if ((file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) && default_field && s->has_update_default_function) + { bitmap_union(read_set, write_set); + need_signal= true; + } + if (need_signal) + file->column_bitmaps_signal(); DBUG_VOID_RETURN; } @@ -6505,7 +6521,7 @@ bool TABLE::mark_virtual_col(Field *field) through columns from write_set it is also marked in vcol_set, and, besides, it is added to write_set. - @return void + @return whether a bitmap was updated @note Let table t1 have columns a,b,c and let column c be a stored virtual @@ -6518,7 +6534,7 @@ bool TABLE::mark_virtual_col(Field *field) be added to read_set either. */ -void TABLE::mark_virtual_columns_for_write(bool insert_fl) +bool TABLE::mark_virtual_columns_for_write(bool insert_fl) { Field **vfield_ptr, *tmp_vfield; bool bitmap_updated= FALSE; @@ -6554,6 +6570,7 @@ void TABLE::mark_virtual_columns_for_write(bool insert_fl) } if (bitmap_updated) file->column_bitmaps_signal(); + return bitmap_updated; } /* @@ -7247,12 +7264,6 @@ bool is_simple_order(ORDER *order) @details The function computes the values of the virtual columns of the table and stores them in the table record buffer. - If vcol_update_mode is set to VCOL_UPDATE_ALL then all virtual column are - computed. - If vcol_update_mode is set to VCOL_UPDATE_FOR_WRITE then all - fields that are set in vcol_set are updated. - If vcol_update_mode is set to VCOL_UPDATE_FOR_READ then all - fields that are set in vcol_set and are not stored are updated. @retval 0 Success @@ -7265,8 +7276,8 @@ int update_virtual_fields(THD *thd, TABLE *table, { DBUG_ENTER("update_virtual_fields"); Field **vfield_ptr, *vfield; - int error __attribute__ ((unused))= 0; - DBUG_ASSERT(table && table->vfield); + DBUG_ASSERT(table); + DBUG_ASSERT(table->vfield); thd->reset_arena_for_cached_items(table->expr_arena); /* Iterate over virtual fields in the table */ @@ -7276,13 +7287,28 @@ int update_virtual_fields(THD *thd, TABLE *table, Virtual_column_info *vcol_info= vfield->vcol_info; DBUG_ASSERT(vcol_info); DBUG_ASSERT(vcol_info->expr_item); - if ((bitmap_is_set(table->vcol_set, vfield->field_index) && - (vcol_update_mode == VCOL_UPDATE_FOR_WRITE || - !vcol_info->stored_in_db)) || - vcol_update_mode == VCOL_UPDATE_ALL) + + bool update; + switch (vcol_update_mode) { + case VCOL_UPDATE_FOR_READ_WRITE: + if (table->triggers) + { + update= true; + break; + } + case VCOL_UPDATE_FOR_READ: + update= !vcol_info->stored_in_db + && bitmap_is_set(table->vcol_set, vfield->field_index); + break; + case VCOL_UPDATE_FOR_WRITE: + update= table->triggers || bitmap_is_set(table->vcol_set, vfield->field_index); + break; + } + + if (update) { /* Compute the actual value of the virtual fields */ - error= vcol_info->expr_item->save_in_field(vfield, 0); + vcol_info->expr_item->save_in_field(vfield, 0); DBUG_PRINT("info", ("field '%s' - updated", vfield->field_name)); } else diff --git a/sql/table.h b/sql/table.h index cf73a1ca12c..e05fa903773 100644 --- a/sql/table.h +++ b/sql/table.h @@ -326,8 +326,8 @@ enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP }; enum enum_vcol_update_mode { VCOL_UPDATE_FOR_READ= 0, - VCOL_UPDATE_FOR_WRITE, - VCOL_UPDATE_ALL + VCOL_UPDATE_FOR_READ_WRITE, + VCOL_UPDATE_FOR_WRITE }; @@ -1307,7 +1307,7 @@ public: void mark_columns_needed_for_insert(void); void mark_columns_per_binlog_row_image(void); bool mark_virtual_col(Field *field); - void mark_virtual_columns_for_write(bool insert_fl); + bool mark_virtual_columns_for_write(bool insert_fl); void mark_default_fields_for_write(bool insert_fl); void mark_columns_used_by_check_constraints(void); void mark_check_constraint_columns_for_read(void); |