[Commits] Rev 3602: Merge MariaDB 5.2->5.3 in http://bazaar.launchpad.net/~maria-captains/maria/5.3

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Tue Nov 20 14:57:55 EET 2012


At http://bazaar.launchpad.net/~maria-captains/maria/5.3

------------------------------------------------------------
revno: 3602 [merge]
revision-id: knielsen at knielsen-hq.org-20121120125749-l55gvliervi5nnaf
parent: timour at askmonty.org-20121119161746-esvfmmd1zpbr6m45
parent: knielsen at knielsen-hq.org-20121120124013-qnivsxzem6453tma
committer: knielsen at knielsen-hq.org
branch nick: mariadb-5.3
timestamp: Tue 2012-11-20 13:57:49 +0100
message:
  Merge MariaDB 5.2->5.3
modified:
  mysql-test/r/information_schema.result sp1f-information_schema.r-20041113105544-waoxa2fjjsicturpothmjmi6jc3yrovn
  mysql-test/suite/vcol/inc/vcol_trigger_sp.inc vcol_trigger_sp.inc-20091016212105-1lx2muao9vwbl1c1-18
  mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result vcol_trigger_sp_inno-20091016212105-1lx2muao9vwbl1c1-46
  mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result vcol_trigger_sp_myis-20091016212105-1lx2muao9vwbl1c1-47
  mysql-test/t/information_schema.test sp1f-information_schema.t-20041113105545-lgutyhqnhpfgiswiwj2ykmjnolmsfq5h
  mysys/mf_pack.c                sp1f-mf_pack.c-19700101030959-u7bzjnr4w3idabvny244w5gzcf33butm
  plugin/feedback/url_http.cc    url_http.cc-20111001192155-ovlxw2bsz88kc0sq-8
  sql/log.cc                     sp1f-log.cc-19700101030959-r3hdfovek4kl6nd64ovoaknmirota6bq
  sql/log.h                      sp1f-log.h-20051222053446-ggv6hdi5fnxggnjemezvv7n2bcbkx45e
  sql/mysql_priv.h               sp1f-mysql_priv.h-19700101030959-4fl65tqpop5zfgxaxkqotu2fa2ree5ci
  sql/sql_acl.cc                 sp1f-sql_acl.cc-19700101030959-c4hku3uqxzujthqnndeprbrhamqy6a4i
  sql/sql_base.cc                sp1f-sql_base.cc-19700101030959-w7tul2gb2n4jzayjwlslj3ybmf3uhk6a
  sql/sql_delete.cc              sp1f-sql_delete.cc-19700101030959-ch2a6r6ushvc2vfwxt7ehcjuplelwthr
  sql/sql_table.cc               sp1f-sql_table.cc-19700101030959-tzdkvgigezpuaxnldqh3fx2h7h2ggslu
  sql/sql_update.cc              sp1f-sql_update.cc-19700101030959-edlgskfuer2ylczbw2znrr5gzfefiyw7
  sql/table.cc                   sp1f-table.cc-19700101030959-nsxtem2adyqzwe6nz4cgrpcmts3o54v7
  sql/table.h                    sp1f-table.h-19700101030959-dv72bajftxj5fbdjuajquappanuv2ija
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result	2012-11-09 08:11:20 +0000
+++ b/mysql-test/r/information_schema.result	2012-11-20 12:57:49 +0000
@@ -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 at localhost;
+select 1 from information_schema.tables where table_schema=repeat('a', 2000);
+1
+drop user mysqltest_1 at localhost;
 End of 5.1 tests.

=== modified file 'mysql-test/suite/vcol/inc/vcol_trigger_sp.inc'
--- a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc	2009-10-16 22:57:48 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc	2012-11-10 07:51:51 +0000
@@ -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;
+

=== modified file 'mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result	2009-10-16 22:57:48 +0000
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result	2012-11-10 07:51:51 +0000
@@ -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;

=== modified file 'mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result	2009-10-16 22:57:48 +0000
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result	2012-11-10 07:51:51 +0000
@@ -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;

=== modified file 'mysql-test/t/information_schema.test'
--- a/mysql-test/t/information_schema.test	2011-11-26 22:23:00 +0000
+++ b/mysql-test/t/information_schema.test	2012-11-20 12:57:49 +0000
@@ -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 at 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 at localhost;
 
 --echo End of 5.1 tests.
 

=== modified file 'mysys/mf_pack.c'
--- a/mysys/mf_pack.c	2011-11-21 17:13:14 +0000
+++ b/mysys/mf_pack.c	2012-11-10 19:36:18 +0000
@@ -35,7 +35,7 @@ void pack_dirname(char * to, const char
   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
   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
 #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 *
 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
   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 *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);

=== modified file 'plugin/feedback/url_http.cc'
--- a/plugin/feedback/url_http.cc	2011-11-13 12:28:35 +0000
+++ b/plugin/feedback/url_http.cc	2012-11-19 10:18:40 +0000
@@ -258,18 +258,21 @@ int Url_http::send(const char* data, siz
       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>")))
       {

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2012-08-30 08:53:49 +0000
+++ b/sql/log.cc	2012-11-20 12:57:49 +0000
@@ -6322,8 +6322,9 @@ int TC_LOG_MMAP::open(const char *opt_na
 
   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_
     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

=== modified file 'sql/log.h'
--- a/sql/log.h	2012-08-22 14:45:25 +0000
+++ b/sql/log.h	2012-11-20 12:57:49 +0000
@@ -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

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2012-09-27 08:18:07 +0000
+++ b/sql/mysql_priv.h	2012-11-20 12:57:49 +0000
@@ -1517,7 +1517,8 @@ find_field_in_table(THD *thd, TABLE *tab
                     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 */

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2012-05-02 15:04:28 +0000
+++ b/sql/sql_acl.cc	2012-11-20 12:57:49 +0000
@@ -1352,14 +1352,20 @@ ulong acl_get(const char *host, const ch
   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 *
 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);
 

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2012-08-24 13:39:34 +0000
+++ b/sql/sql_base.cc	2012-11-20 12:57:49 +0000
@@ -8707,7 +8707,9 @@ fill_record(THD * thd, List<Item> &field
   /* 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
       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<
   }
   /* 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
   {
     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;
 

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2012-03-23 16:22:39 +0000
+++ b/sql/sql_delete.cc	2012-11-20 12:57:49 +0000
@@ -333,7 +333,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *
          ! 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)

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2012-08-24 12:02:32 +0000
+++ b/sql/sql_table.cc	2012-11-20 12:57:49 +0000
@@ -8109,7 +8109,7 @@ copy_data_between_tables(THD *thd, TABLE
     }
     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;

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2012-08-29 08:35:42 +0000
+++ b/sql/sql_update.cc	2012-11-20 12:57:49 +0000
@@ -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)
     {

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2012-10-10 19:42:50 +0000
+++ b/sql/table.cc	2012-11-20 12:57:49 +0000
@@ -5801,22 +5801,25 @@ size_t max_row_length(TABLE *table, cons
 
   @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, TABL
   {
     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);

=== modified file 'sql/table.h'
--- a/sql/table.h	2012-10-05 09:26:55 +0000
+++ b/sql/table.h	2012-11-20 12:57:49 +0000
@@ -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 */



More information about the commits mailing list