summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sql_base.cc17
-rw-r--r--sql/sql_delete.cc4
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_update.cc8
-rw-r--r--sql/table.cc21
-rw-r--r--sql/table.h7
7 files changed, 44 insertions, 18 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index addb29861fc..73b8ad86426 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1366,7 +1366,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
bool allow_rowid, uint *cached_field_index_ptr);
Field *
find_field_in_table_sef(TABLE *table, const char *name);
-int update_virtual_fields(THD *thd, TABLE *table, bool ignore_stored= FALSE);
+int update_virtual_fields(THD *thd, TABLE *table,
+ enum enum_vcol_update_mode vcol_update_mode= VCOL_UPDATE_FOR_READ);
#endif /* MYSQL_SERVER */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index f45403696be..32a5bd8356f 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8460,7 +8460,9 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
{
if (vcol_table->vfield)
{
- if (update_virtual_fields(thd, vcol_table, TRUE))
+ if (update_virtual_fields(thd, vcol_table,
+ vcol_table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_WRITE))
goto err;
}
}
@@ -8524,7 +8526,9 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
if (item_field && item_field->field &&
(table= item_field->field->table) &&
table->vfield)
- result= update_virtual_fields(thd, table, TRUE);
+ result= update_virtual_fields(thd, table,
+ table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_WRITE);
}
}
return result;
@@ -8604,7 +8608,10 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
}
/* Update virtual fields*/
thd->abort_on_warning= FALSE;
- if (table->vfield && update_virtual_fields(thd, table, TRUE))
+ if (table->vfield &&
+ update_virtual_fields(thd, table,
+ table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_WRITE))
goto err;
thd->abort_on_warning= abort_on_warning_saved;
DBUG_RETURN(thd->is_error());
@@ -8657,7 +8664,9 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
{
TABLE *table= (*ptr)->table;
if (table->vfield)
- result= update_virtual_fields(thd, table, TRUE);
+ result= update_virtual_fields(thd, table,
+ table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_WRITE);
}
return result;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 72a5b9703b3..90ca139d17b 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -313,7 +313,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
while (!(error=info.read_record(&info)) && !thd->killed &&
! thd->is_error())
{
- update_virtual_fields(thd, table);
+ update_virtual_fields(thd, table,
+ triggers_applicable ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_READ);
thd->examined_row_count++;
// thd->is_error() is tested to disallow delete row on error
if (!select || select->skip_record(thd) > 0)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 6b709915283..9b9ee0a743d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -8066,7 +8066,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
copy_ptr->do_copy(copy_ptr);
}
prev_insert_id= to->file->next_insert_id;
- update_virtual_fields(thd, to, TRUE);
+ update_virtual_fields(thd, to, VCOL_UPDATE_FOR_WRITE);
if (thd->is_error())
{
error= 1;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index b3c001849b5..56b2c508fbc 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -490,7 +490,9 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
- update_virtual_fields(thd, table);
+ update_virtual_fields(thd, table,
+ table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_READ);
thd->examined_row_count++;
if (!select || (error= select->skip_record(thd)) > 0)
{
@@ -605,7 +607,9 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
- update_virtual_fields(thd, table);
+ update_virtual_fields(thd, table,
+ table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_READ);
thd->examined_row_count++;
if (!select || select->skip_record(thd) > 0)
{
diff --git a/sql/table.cc b/sql/table.cc
index d950b7a3a4e..5c1e27b87c7 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5500,22 +5500,25 @@ size_t max_row_length(TABLE *table, const uchar *data)
@param thd Thread handle
@param table The TABLE object
- @param for_write Requests to compute only fields needed for write
+ @param vcol_update_mode Specifies what virtual column are computed
@details
The function computes the values of the virtual columns of the table and
stores them in the table record buffer.
- Only fields from vcol_set are computed, and, when the flag for_write is not
- set to TRUE, a virtual field is computed only if it's not stored.
- The flag for_write is set to TRUE for row insert/update operations.
-
+ If vcol_update_mode is set to VCOL_UPDATE_ALL then all virtual column are
+ computed. Otherwise, only fields from vcol_set are computed: all of them,
+ if vcol_update_mode is set to VCOL_UPDATE_FOR_WRITE, and, only those with
+ the stored_in_db flag set to false, if vcol_update_mode is equal to
+ VCOL_UPDATE_FOR_READ.
+
@retval
0 Success
@retval
>0 Error occurred when storing a virtual field value
*/
-int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
+int update_virtual_fields(THD *thd, TABLE *table,
+ enum enum_vcol_update_mode vcol_update_mode)
{
DBUG_ENTER("update_virtual_fields");
Field **vfield_ptr, *vfield;
@@ -5529,9 +5532,9 @@ int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
{
vfield= (*vfield_ptr);
DBUG_ASSERT(vfield->vcol_info && vfield->vcol_info->expr_item);
- /* Only update those fields that are marked in the vcol_set bitmap */
- if (bitmap_is_set(table->vcol_set, vfield->field_index) &&
- (for_write || !vfield->stored_in_db))
+ if ((bitmap_is_set(table->vcol_set, vfield->field_index) &&
+ (vcol_update_mode == VCOL_UPDATE_FOR_WRITE || !vfield->stored_in_db)) ||
+ vcol_update_mode == VCOL_UPDATE_ALL)
{
/* Compute the actual value of the virtual fields */
error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
diff --git a/sql/table.h b/sql/table.h
index c1a4e952f7b..80544ef3d89 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -156,6 +156,13 @@ enum frm_type_enum
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
+};
+
typedef struct st_filesort_info
{
IO_CACHE *io_cache; /* If sorted through filesort */