summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2012-11-20 13:57:49 +0100
committerunknown <knielsen@knielsen-hq.org>2012-11-20 13:57:49 +0100
commitecf04668a2db3d7fc91e421e68eeb5ab25064aa0 (patch)
tree67fb1a5b050c913ad21f9c30628ff3ef0fd81f2c
parentdd2d59924e06afb29e36a6dda56f6fb393ef6c6e (diff)
parentcbae294396429682a22371f23a048dcd0d4c71da (diff)
downloadmariadb-git-ecf04668a2db3d7fc91e421e68eeb5ab25064aa0.tar.gz
Merge MariaDB 5.2->5.3
-rw-r--r--mysql-test/r/information_schema.result6
-rw-r--r--mysql-test/suite/vcol/inc/vcol_trigger_sp.inc41
-rw-r--r--mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result40
-rw-r--r--mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result40
-rw-r--r--mysql-test/t/information_schema.test11
-rw-r--r--mysys/mf_pack.c14
-rw-r--r--plugin/feedback/url_http.cc9
-rw-r--r--sql/log.cc24
-rw-r--r--sql/log.h2
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sql_acl.cc20
-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
17 files changed, 223 insertions, 46 deletions
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 886b6f4d7f3..a9dd69ef698 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1689,4 +1689,10 @@ SELECT length(CAST(b AS CHAR)) FROM ubig;
length(CAST(b AS CHAR))
20
DROP TABLE ubig;
+select 1 from information_schema.tables where table_schema=repeat('a', 2000);
+1
+grant usage on *.* to mysqltest_1@localhost;
+select 1 from information_schema.tables where table_schema=repeat('a', 2000);
+1
+drop user mysqltest_1@localhost;
End of 5.1 tests.
diff --git a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
index ddf13fef6a1..eb7e6ad32b9 100644
--- a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
+++ b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
@@ -108,3 +108,44 @@ select * from t1;
drop table t1,t2;
drop procedure p1;
+
+--echo #
+--echo # Bug mdev-3845: values of virtual columns are not computed for triggers
+--echo #
+
+CREATE TABLE t1 (
+ a INTEGER UNSIGNED NULL DEFAULT NULL,
+ b INTEGER UNSIGNED GENERATED ALWAYS AS (a) VIRTUAL
+);
+
+CREATE TABLE t2 (c INTEGER UNSIGNED NOT NULL);
+
+DELIMITER |;
+
+CREATE TRIGGER t1_ins_aft
+ AFTER INSERT
+ ON t1
+ FOR EACH ROW
+BEGIN
+ INSERT INTO t2 (c) VALUES (NEW.b);
+END |
+
+CREATE TRIGGER t1_del_bef
+ BEFORE DELETE
+ ON t1
+ FOR EACH ROW
+BEGIN
+ INSERT INTO t2 (c) VALUES (OLD.b);
+END |
+
+DELIMITER ;|
+
+INSERT INTO t1 (a) VALUES (1), (2), (3);
+SELECT * FROM t2;
+DELETE FROM t1;
+SELECT * FROM t2;
+
+DROP TRIGGER t1_ins_aft;
+DROP TRIGGER t1_del_bef;
+DROP TABLE t1,t2;
+
diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
index e903bc4eafd..1d78bbf50e4 100644
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
@@ -85,3 +85,43 @@ a b c
300 30 30
drop table t1,t2;
drop procedure p1;
+#
+# Bug mdev-3845: values of virtual columns are not computed for triggers
+#
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b INTEGER UNSIGNED GENERATED ALWAYS AS (a) VIRTUAL
+);
+CREATE TABLE t2 (c INTEGER UNSIGNED NOT NULL);
+CREATE TRIGGER t1_ins_aft
+AFTER INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (NEW.b);
+END |
+CREATE TRIGGER t1_del_bef
+BEFORE DELETE
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (OLD.b);
+END |
+INSERT INTO t1 (a) VALUES (1), (2), (3);
+SELECT * FROM t2;
+c
+1
+2
+3
+DELETE FROM t1;
+SELECT * FROM t2;
+c
+1
+2
+3
+1
+2
+3
+DROP TRIGGER t1_ins_aft;
+DROP TRIGGER t1_del_bef;
+DROP TABLE t1,t2;
diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
index c2a66d656b5..77efa8fe6b9 100644
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
@@ -85,3 +85,43 @@ a b c
300 30 30
drop table t1,t2;
drop procedure p1;
+#
+# Bug mdev-3845: values of virtual columns are not computed for triggers
+#
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b INTEGER UNSIGNED GENERATED ALWAYS AS (a) VIRTUAL
+);
+CREATE TABLE t2 (c INTEGER UNSIGNED NOT NULL);
+CREATE TRIGGER t1_ins_aft
+AFTER INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (NEW.b);
+END |
+CREATE TRIGGER t1_del_bef
+BEFORE DELETE
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (OLD.b);
+END |
+INSERT INTO t1 (a) VALUES (1), (2), (3);
+SELECT * FROM t2;
+c
+1
+2
+3
+DELETE FROM t1;
+SELECT * FROM t2;
+c
+1
+2
+3
+1
+2
+3
+DROP TRIGGER t1_ins_aft;
+DROP TRIGGER t1_del_bef;
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index e1962255cf6..616b22245f3 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1441,6 +1441,17 @@ SELECT length(CAST(b AS CHAR)) FROM ubig;
DROP TABLE ubig;
+#
+# Bug #13889741: HANDLE_FATAL_SIGNAL IN _DB_ENTER_ | HANDLE_FATAL_SIGNAL IN STRNLEN
+#
+select 1 from information_schema.tables where table_schema=repeat('a', 2000);
+grant usage on *.* to mysqltest_1@localhost;
+connect (con1, localhost, mysqltest_1,,);
+connection con1;
+select 1 from information_schema.tables where table_schema=repeat('a', 2000);
+connection default;
+disconnect con1;
+drop user mysqltest_1@localhost;
--echo End of 5.1 tests.
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index 86fd61537e7..e6b576b6d96 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -35,7 +35,7 @@ void pack_dirname(char * to, const char *from)
int cwd_err;
size_t d_length,length,UNINIT_VAR(buff_length);
char * start;
- char buff[FN_REFLEN];
+ char buff[FN_REFLEN + 1];
DBUG_ENTER("pack_dirname");
(void) intern_filename(to,from); /* Change to intern name */
@@ -132,7 +132,7 @@ size_t cleanup_dirname(register char *to, const char *from)
reg3 char * from_ptr;
reg4 char * start;
char parent[5], /* for "FN_PARENTDIR" */
- buff[FN_REFLEN+1],*end_parentdir;
+ buff[FN_REFLEN + 1],*end_parentdir;
#ifdef BACKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
@@ -245,7 +245,7 @@ my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
#ifdef USE_SYMDIR
void symdirget(char *dir)
{
- char buff[FN_REFLEN+1];
+ char buff[FN_REFLEN + 1];
char *pos=strend(dir);
if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK))
{
@@ -295,7 +295,7 @@ void symdirget(char *dir)
size_t normalize_dirname(char *to, const char *from)
{
size_t length;
- char buff[FN_REFLEN];
+ char buff[FN_REFLEN + 1];
DBUG_ENTER("normalize_dirname");
/*
@@ -423,7 +423,7 @@ static char * NEAR_F expand_tilde(char * *path)
size_t unpack_filename(char * to, const char *from)
{
size_t length, n_length, buff_length;
- char buff[FN_REFLEN];
+ char buff[FN_REFLEN + 1];
DBUG_ENTER("unpack_filename");
length=dirname_part(buff, from, &buff_length);/* copy & convert dirname */
@@ -459,7 +459,7 @@ size_t system_filename(char * to, const char *from)
int libchar_found;
size_t length;
char * to_pos,from_pos,pos;
- char buff[FN_REFLEN];
+ char buff[FN_REFLEN + 1];
DBUG_ENTER("system_filename");
libchar_found=0;
@@ -516,7 +516,7 @@ size_t system_filename(char * to, const char *from)
char *intern_filename(char *to, const char *from)
{
size_t length, to_length;
- char buff[FN_REFLEN];
+ char buff[FN_REFLEN + 1];
if (from == to)
{ /* Dirname may destroy from */
strmov(buff,from);
diff --git a/plugin/feedback/url_http.cc b/plugin/feedback/url_http.cc
index 71b67a52807..b0028292707 100644
--- a/plugin/feedback/url_http.cc
+++ b/plugin/feedback/url_http.cc
@@ -258,18 +258,21 @@ int Url_http::send(const char* data, size_t data_length)
Extract the first string between <h1>...</h1> tags
and put it as a server reply into the error log.
*/
+ len= 0;
for (;;)
{
- size_t i= vio_read(vio, (uchar*)buf + len, sizeof(buf) - len - 1);
+ size_t i= sizeof(buf) - len - 1;
+ if (i)
+ i= vio_read(vio, (uchar*)buf + len, i);
if ((int)i <= 0)
break;
len+= i;
}
- if (len && len < sizeof(buf))
+ if (len)
{
char *from;
- buf[len+1]= 0; // safety
+ buf[len]= 0; // safety
if ((from= strstr(buf, "<h1>")))
{
diff --git a/sql/log.cc b/sql/log.cc
index 05e8a66ed04..1aea7a33e0d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -6322,8 +6322,9 @@ int TC_LOG_MMAP::open(const char *opt_name)
syncing= 0;
active=pages;
+ DBUG_ASSERT(npages >= 2);
pool=pages+1;
- pool_last=pages+npages-1;
+ pool_last_ptr= &((pages+npages-1)->next);
commit_ordered_queue= NULL;
commit_ordered_queue_busy= false;
@@ -6356,8 +6357,8 @@ void TC_LOG_MMAP::get_active_from_pool()
do
{
best_p= p= &pool;
- if ((*p)->waiters == 0) // can the first page be used ?
- break; // yes - take it.
+ if ((*p)->waiters == 0 && (*p)->free > 0) // can the first page be used ?
+ break; // yes - take it.
best_free=0; // no - trying second strategy
for (p=&(*p)->next; *p; p=&(*p)->next)
@@ -6374,10 +6375,10 @@ void TC_LOG_MMAP::get_active_from_pool()
safe_mutex_assert_owner(&LOCK_active);
active=*best_p;
- if ((*best_p)->next) // unlink the page from the pool
- *best_p=(*best_p)->next;
- else
- pool_last=*best_p;
+ /* Unlink the page from the pool. */
+ if (!(*best_p)->next)
+ pool_last_ptr= best_p;
+ *best_p=(*best_p)->next;
pthread_mutex_unlock(&LOCK_pool);
pthread_mutex_lock(&active->lock);
@@ -6484,12 +6485,9 @@ int TC_LOG_MMAP::log_one_transaction(my_xid xid)
pthread_mutex_unlock(&LOCK_active);
pthread_mutex_lock(&p->lock);
p->waiters++;
- for (;;)
+ while (p->state == DIRTY && syncing)
{
- int not_dirty = p->state != DIRTY;
pthread_mutex_unlock(&p->lock);
- if (not_dirty || !syncing)
- break;
pthread_cond_wait(&p->cond, &LOCK_sync);
pthread_mutex_lock(&p->lock);
}
@@ -6541,8 +6539,8 @@ int TC_LOG_MMAP::sync()
/* page is synced. let's move it to the pool */
pthread_mutex_lock(&LOCK_pool);
- pool_last->next=syncing;
- pool_last=syncing;
+ (*pool_last_ptr)=syncing;
+ pool_last_ptr=&(syncing->next);
syncing->next=0;
syncing->state= err ? ERROR : POOL;
pthread_cond_signal(&COND_pool); // in case somebody's waiting
diff --git a/sql/log.h b/sql/log.h
index bfa63b79ffe..156a8e6f1b6 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -129,7 +129,7 @@ class TC_LOG_MMAP: public TC_LOG
my_off_t file_length;
uint npages, inited;
uchar *data;
- struct st_page *pages, *syncing, *active, *pool, *pool_last;
+ struct st_page *pages, *syncing, *active, *pool, **pool_last_ptr;
/*
note that, e.g. LOCK_active is only used to protect
'active' pointer, to protect the content of the active page
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 5f20e9f0591..78f77db597b 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1517,7 +1517,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);
int dynamic_column_error_message(enum_dyncol_func_result rc);
#endif /* MYSQL_SERVER */
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 81e9bc8c46f..0e6ad5dfbf1 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1352,14 +1352,20 @@ ulong acl_get(const char *host, const char *ip,
acl_entry *entry;
DBUG_ENTER("acl_get");
- VOID(pthread_mutex_lock(&acl_cache->lock));
- end=strmov((tmp_db=strmov(strmov(key, ip ? ip : "")+1,user)+1),db);
+ tmp_db= strmov(strmov(key, ip ? ip : "") + 1, user) + 1;
+ end= strnmov(tmp_db, db, key + sizeof(key) - tmp_db);
+
+ if (end >= key + sizeof(key)) // db name was truncated
+ DBUG_RETURN(0); // no privileges for an invalid db name
+
if (lower_case_table_names)
{
my_casedn_str(files_charset_info, tmp_db);
db=tmp_db;
}
key_length= (size_t) (end-key);
+
+ VOID(pthread_mutex_lock(&acl_cache->lock));
if (!db_is_pattern && (entry=(acl_entry*) acl_cache->search((uchar*) key,
key_length)))
{
@@ -4365,11 +4371,17 @@ static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash)
bool check_grant_db(THD *thd,const char *db)
{
Security_context *sctx= thd->security_ctx;
- char helping [SAFE_NAME_LEN + USERNAME_LENGTH+2];
+ char helping [SAFE_NAME_LEN + USERNAME_LENGTH+2], *end;
uint len;
bool error= TRUE;
- len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1;
+ end= strmov(helping, sctx->priv_user) + 1;
+ end= strnmov(end, db, helping + sizeof(helping) - end);
+
+ if (end >= helping + sizeof(helping)) // db name was truncated
+ return 1; // no privileges for an invalid db name
+
+ len= (uint) (end - helping) + 1;
rw_rdlock(&LOCK_grant);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index e93e4fb3b67..0fd92189937 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8707,7 +8707,9 @@ fill_record(THD * thd, 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, TRUE))
+ update_virtual_fields(thd, vcol_table,
+ vcol_table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_WRITE))
goto err;
thd->abort_on_warning= save_abort_on_warning;
thd->no_errors= save_no_errors;
@@ -8772,7 +8774,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;
@@ -8856,7 +8860,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());
@@ -8909,7 +8916,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 24b1828b177..480868241f7 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -333,7 +333,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
! thd->is_error())
{
if (table->vfield)
- 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 7f5df6a0958..7c125e18cde 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -8109,7 +8109,7 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
}
prev_insert_id= to->file->next_insert_id;
if (to->vfield)
- 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 7d6eb62f57d..9d00118f450 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -507,7 +507,9 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
if (table->vfield)
- 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)
{
@@ -623,7 +625,9 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
if (table->vfield)
- 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 faa248f43f6..d42fd14120c 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5801,22 +5801,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;
@@ -5829,9 +5832,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 a2d3aa73f7e..d66a6a44753 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -157,6 +157,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 */