summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_base.cc17
-rw-r--r--sql/sql_delete.cc4
-rw-r--r--sql/sql_update.cc11
-rw-r--r--sql/table.cc66
-rw-r--r--sql/table.h6
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);