← Back to team overview

maria-developers team mailing list archive

bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (igor:2744)

 

#At lp:maria based on revid:knielsen@xxxxxxxxxxxxxxx-20091006183755-y08lid6fg8mnr8sk

 2744 Igor Babaev	2009-10-16
      The main commit of Andrey Zhakov's patch introducing vurtual(computed) columns.
      The original patch has been ameliorated by Sanja and Igor.
added:
  mysql-test/suite/vcol/
  mysql-test/suite/vcol/inc/
  mysql-test/suite/vcol/inc/vcol_blocked_sql_funcs_main.inc
  mysql-test/suite/vcol/inc/vcol_cleanup.inc
  mysql-test/suite/vcol/inc/vcol_column_def_options.inc
  mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc
  mysql-test/suite/vcol/inc/vcol_handler.inc
  mysql-test/suite/vcol/inc/vcol_init_vars.pre
  mysql-test/suite/vcol/inc/vcol_ins_upd.inc
  mysql-test/suite/vcol/inc/vcol_keys.inc
  mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc
  mysql-test/suite/vcol/inc/vcol_partition.inc
  mysql-test/suite/vcol/inc/vcol_select.inc
  mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc
  mysql-test/suite/vcol/inc/vcol_supported_sql_funcs_main.inc
  mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
  mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc
  mysql-test/suite/vcol/inc/vcol_view.inc
  mysql-test/suite/vcol/r/
  mysql-test/suite/vcol/r/rpl_vcol.result
  mysql-test/suite/vcol/r/vcol_archive.result
  mysql-test/suite/vcol/r/vcol_blackhole.result
  mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_innodb.result
  mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_myisam.result
  mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result
  mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result
  mysql-test/suite/vcol/r/vcol_csv.result
  mysql-test/suite/vcol/r/vcol_handler_innodb.result
  mysql-test/suite/vcol/r/vcol_handler_myisam.result
  mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result
  mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result
  mysql-test/suite/vcol/r/vcol_keys_innodb.result
  mysql-test/suite/vcol/r/vcol_keys_myisam.result
  mysql-test/suite/vcol/r/vcol_memory.result
  mysql-test/suite/vcol/r/vcol_merge.result
  mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result
  mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result
  mysql-test/suite/vcol/r/vcol_partition_innodb.result
  mysql-test/suite/vcol/r/vcol_partition_myisam.result
  mysql-test/suite/vcol/r/vcol_select_innodb.result
  mysql-test/suite/vcol/r/vcol_select_myisam.result
  mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result
  mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result
  mysql-test/suite/vcol/r/vcol_syntax.result
  mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
  mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
  mysql-test/suite/vcol/r/vcol_view_innodb.result
  mysql-test/suite/vcol/r/vcol_view_myisam.result
  mysql-test/suite/vcol/t/
  mysql-test/suite/vcol/t/rpl_vcol.test
  mysql-test/suite/vcol/t/vcol_archive.test
  mysql-test/suite/vcol/t/vcol_blackhole.test
  mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_innodb.test
  mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_myisam.test
  mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test
  mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test
  mysql-test/suite/vcol/t/vcol_csv.test
  mysql-test/suite/vcol/t/vcol_handler_innodb.test
  mysql-test/suite/vcol/t/vcol_handler_myisam.test
  mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test
  mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test
  mysql-test/suite/vcol/t/vcol_keys_innodb.test
  mysql-test/suite/vcol/t/vcol_keys_myisam.test
  mysql-test/suite/vcol/t/vcol_memory.test
  mysql-test/suite/vcol/t/vcol_merge.test
  mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test
  mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test
  mysql-test/suite/vcol/t/vcol_partition_innodb.test
  mysql-test/suite/vcol/t/vcol_partition_myisam.test
  mysql-test/suite/vcol/t/vcol_select_innodb.test
  mysql-test/suite/vcol/t/vcol_select_myisam.test
  mysql-test/suite/vcol/t/vcol_supported_sql_funcs_innodb.test
  mysql-test/suite/vcol/t/vcol_supported_sql_funcs_myisam.test
  mysql-test/suite/vcol/t/vcol_syntax.test
  mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test
  mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test
  mysql-test/suite/vcol/t/vcol_view_innodb.test
  mysql-test/suite/vcol/t/vcol_view_myisam.test
modified:
  include/mysql_com.h
  sql/field.cc
  sql/field.h
  sql/filesort.cc
  sql/ha_partition.cc
  sql/ha_partition.h
  sql/handler.h
  sql/item.cc
  sql/item.h
  sql/item_func.cc
  sql/item_func.h
  sql/item_row.h
  sql/item_strfunc.h
  sql/item_subselect.h
  sql/item_sum.h
  sql/item_timefunc.h
  sql/item_xmlfunc.cc
  sql/item_xmlfunc.h
  sql/lex.h
  sql/mysql_priv.h
  sql/procedure.h
  sql/records.cc
  sql/share/errmsg.txt
  sql/sp_head.cc
  sql/sql_base.cc
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_handler.cc
  sql/sql_insert.cc
  sql/sql_lex.cc
  sql/sql_lex.h
  sql/sql_parse.cc
  sql/sql_partition.cc
  sql/sql_select.cc
  sql/sql_show.cc
  sql/sql_table.cc
  sql/sql_yacc.yy
  sql/table.cc
  sql/table.h
  sql/unireg.cc
  sql/unireg.h
  storage/innobase/handler/ha_innodb.cc
  storage/innobase/handler/ha_innodb.h
  storage/myisam/ha_myisam.cc
  storage/myisam/ha_myisam.h
  storage/pbxt/src/discover_xt.cc
  storage/xtradb/handler/ha_innodb.cc
  storage/xtradb/handler/ha_innodb.h

=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h	2008-10-10 15:28:41 +0000
+++ b/include/mysql_com.h	2009-10-16 22:57:48 +0000
@@ -67,7 +67,8 @@ enum enum_server_command
   COM_END
 };
 
-
+/* sql type stored in .frm files for virtual fields */
+#define MYSQL_TYPE_VIRTUAL 245
 /*
   Length of random string sent by server on handshake; this is also length of
   obfuscated password, recieved from client

=== added directory 'mysql-test/suite/vcol'
=== added directory 'mysql-test/suite/vcol/inc'
=== added file 'mysql-test/suite/vcol/inc/vcol_blocked_sql_funcs_main.inc'
--- a/mysql-test/suite/vcol/inc/vcol_blocked_sql_funcs_main.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_blocked_sql_funcs_main.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,344 @@
+################################################################################
+# inc/vcol_blocked_sql_funcs_main.inc                                          #
+#                                                                              #
+# Purpose:                                                                     #
+#  Tests around sql functions                                                  #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+#
+# NOTE:  All SQL functions should be rejected, otherwise BUG.
+#
+
+--echo # RAND()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (b double as (rand()));
+
+--echo # LOAD_FILE()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(64), b varchar(1024) as (load_file(a)));
+
+--echo # CURDATE()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (curdate()));
+
+--echo # CURRENT_DATE(), CURRENT_DATE
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (current_date));
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (current_date()));
+
+--echo # CURRENT_TIME(), CURRENT_TIME
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (current_time));
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (current_time()));
+
+--echo # CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (current_timestamp()));
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (current_timestamp));
+
+--echo # CURTIME()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime as (curtime()));
+
+--echo # LOCALTIME(), LOCALTIME
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b varchar(10) as (localtime())); 
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b varchar(10) as (localtime)); 
+
+--echo # LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6)
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b varchar(10) as (localtimestamp()));
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b varchar(10) as (localtimestamp));
+
+--echo # NOW()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b varchar(10) as (now()));
+
+--echo # SYSDATE()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b varchar(10) as (sysdate()));
+
+--echo # UNIX_TIMESTAMP()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b datetime as (unix_timestamp()));
+
+--echo # UTC_DATE()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b datetime as (utc_date()));
+
+--echo # UTC_TIME()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b datetime as (utc_time()));
+
+--echo # UTC_TIMESTAMP()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a datetime, b datetime as (utc_timestamp()));
+
+--echo # MATCH()
+if (!$skip_full_text_checks)
+{
+  -- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+  create table t1 (a varchar(32), b bool as (match a against ('sample text')));
+}
+
+--echo # BENCHMARK()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3)));
+
+--echo # CONNECTION_ID()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int as (connection_id()));
+
+--echo # CURRENT_USER(), CURRENT_USER
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32) as (current_user()));
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32) as (current_user));
+
+--echo # DATABASE()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (database()));
+
+--echo # FOUND_ROWS()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (found_rows()));
+
+--echo # GET_LOCK()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10)));
+
+--echo # IS_FREE_LOCK()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a)));
+
+--echo # IS_USED_LOCK()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a)));
+
+--echo # LAST_INSERT_ID()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int as (last_insert_id()));
+
+--echo # MASTER_POS_WAIT()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32), b int as (master_pos_wait(a,0,2)));
+
+--echo # NAME_CONST()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32) as (name_const('test',1)));
+
+--echo # RELEASE_LOCK()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32), b int as (release_lock(a)));
+
+--echo # ROW_COUNT()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int as (row_count()));
+
+--echo # SCHEMA()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32) as (schema()));
+
+--echo # SESSION_USER()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32) as (session_user()));
+
+--echo # SLEEP()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (sleep(a)));
+
+--echo # SYSTEM_USER()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32) as (system_user()));
+
+--echo # USER()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (user()));
+
+--echo # UUID_SHORT()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024) as (uuid_short()));
+
+--echo # UUID()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024) as (uuid()));
+
+--echo # VALUES()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (values(a)));
+
+--echo # VERSION()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (version())); 
+
+--echo # ENCRYPT()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (encrypt(a)));
+
+--echo # Stored procedures
+
+delimiter //;
+create procedure p1()
+begin
+  select current_user();
+end //
+
+create function f1()
+returns int
+begin
+ return 1;
+end //
+
+delimiter ;//
+
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int as (p1()));
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int as (f1()));
+
+drop procedure p1;
+drop function f1;
+
+--echo # Unknown functions
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int as (f1()));
+
+--echo #
+--echo # GROUP BY FUNCTIONS
+--echo #
+
+--echo # AVG()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (avg(a)));
+
+--echo # BIT_AND()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (bit_and(a)));
+
+--echo # BIT_OR()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (bit_or(a)));
+
+--echo # BIT_XOR()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (bit_xor(a)));
+
+--echo # COUNT(DISTINCT)
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (count(distinct a)));
+
+--echo # COUNT()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (count(a)));
+
+--echo # GROUP_CONCAT()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(32), b int as (group_concat(a,'')));
+
+--echo # MAX()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (max(a)));
+
+--echo # MIN()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (min(a)));
+
+--echo # STD()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (std(a)));
+
+--echo # STDDEV_POP()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (stddev_pop(a)));
+
+--echo # STDDEV_SAMP()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (stddev_samp(a)));
+
+--echo # STDDEV()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (stddev(a)));
+
+--echo # SUM()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (sum(a)));
+
+--echo # VAR_POP()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (var_pop(a)));
+
+--echo # VAR_SAMP()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (var_samp(a)));
+
+--echo # VARIANCE()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (variance(a)));
+
+--echo #
+--echo # XML FUNCTIONS
+--echo #
+
+--echo # ExtractValue()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]')));
+
+--echo # UpdateXML()
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>')));
+
+--echo #
+--echo # Sub-selects
+--echo #
+
+create table t1 (a int);
+-- error ER_PARSE_ERROR
+create table t2 (a int, b int as (select count(*) from t1));
+drop table t1;
+
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as ((select 1)));
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (a+(select 1)));
+
+--echo #
+--echo # SP functions
+--echo #
+
+--disable_warnings
+drop function if exists sub1;
+--enable_warnings
+create function sub1(i int) returns int deterministic
+  return i+1;
+select sub1(1);
+-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b int as (a+sub3(1)));
+drop function sub1;
+
+--echo #
+--echo # Long expression
+
+let $tmp_long_string = `SELECT repeat('a',240)`;
+eval create table t1 (a int, b varchar(300) as (concat(a,'$tmp_long_string')));
+drop table t1;
+let $tmp_long_string = `SELECT repeat('a',243)`;
+--error ER_WRONG_STRING_LENGTH
+eval create table t1 (a int, b varchar(300) as (concat(a,'$tmp_long_string')));
+
+--echo #
+--echo # Constant expression
+--error ER_CONST_EXPR_IN_VCOL
+create table t1 (a int as (PI()));

=== added file 'mysql-test/suite/vcol/inc/vcol_cleanup.inc'
--- a/mysql-test/suite/vcol/inc/vcol_cleanup.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_cleanup.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,25 @@
+################################################################################
+# inc/vcol_cleanup.inc                                                         #
+#                                                                              #
+# Purpose:                                                                     #
+#   Removal of the objects created by the t/<test_name>.test                   #
+#   scripts.                                                                   #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+--disable_warnings
+--disable_query_log
+DROP VIEW  IF EXISTS v1,v2;
+DROP TABLE IF EXISTS t1,t2,t3;
+DROP PROCEDURE IF EXISTS p1;
+DROP FUNCTION IF EXISTS f1;
+DROP TRIGGER IF EXISTS trg1;
+DROP TRIGGER IF EXISTS trg2;
+--enable_query_log
+--enable_warnings

=== added file 'mysql-test/suite/vcol/inc/vcol_column_def_options.inc'
--- a/mysql-test/suite/vcol/inc/vcol_column_def_options.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_column_def_options.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,113 @@
+################################################################################
+# inc/vcol_column_def_options.inc                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing different optional parameters specified when defining               #
+#  a virtual column.                                                           #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+--echo #
+--echo # Section 1. Wrong column definition options
+--echo #            - NOT NULL
+--echo #            - NULL
+--echo #            - DEFAULT <value>
+--echo #            - AUTO_INCREMENT
+--echo #            - [PRIMARY] KEY
+
+--echo # NOT NULL
+--error ER_PARSE_ERROR
+create table t1 (a int, b int as (a+1) not null);
+create table t1 (a int);
+--error ER_PARSE_ERROR
+alter table t1 add column b int as (a+1) not null;
+drop table t1;
+
+--echo # NULL  
+--error ER_PARSE_ERROR
+create table t1 (a int, b int as (a+1) null);
+create table t1 (a int);
+--error ER_PARSE_ERROR
+alter table t1 add column b int as (a+1) null;
+drop table t1;
+
+--echo # DEFAULT
+--error ER_PARSE_ERROR
+create table t1 (a int, b int as (a+1) default 0);
+create table t1 (a int);
+--error ER_PARSE_ERROR
+alter table t1 add column b int as (a+1) default 0;
+drop table t1;
+
+--echo # AUTO_INCREMENT
+--error ER_PARSE_ERROR
+create table t1 (a int, b int as (a+1) AUTO_INCREMENT);
+create table t1 (a int);
+--error ER_PARSE_ERROR
+alter table t1 add column b int as (a+1) AUTO_INCREMENT;
+drop table t1;
+
+--echo # [PRIMARY] KEY
+--error ER_PARSE_ERROR
+create table t1 (a int, b int as (a+1) key);
+--error ER_PARSE_ERROR
+create table t1 (a int, b int as (a+1) primary key);
+create table t1 (a int);
+--error ER_PARSE_ERROR
+alter table t1 add column b int as (a+1) key;
+--error ER_PARSE_ERROR
+alter table t1 add column b int as (a+1) primary key;
+drop table t1;
+
+--echo # Section 2. Other column definition options
+--echo #            - COMMENT
+--echo #            - REFERENCES (only syntax testing here)
+--echo #            - STORED (only systax testing here)
+create table t1 (a int, b int as (a % 2) comment 'my comment');
+show create table t1;
+describe t1;
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) comment 'my comment';
+show create table t1;
+describe t1;
+insert into t1 (a) values (1);
+select * from t1;
+insert into t1 values (2,default);
+select a,b from t1;
+create table t2 like t1;
+show create table t2;
+describe t2;
+insert into t2 (a) values (1);
+select * from t2;
+insert into t2 values (2,default);
+select a,b from t2;
+drop table t2;
+drop table t1;
+
+create table t1 (a int, b int as (a % 2) persistent); 
+show create table t1;
+describe t1;
+insert into t1 (a) values (1);
+select * from t1;
+insert into t1 values (2,default);
+select a,b from t1;
+drop table t1;
+
+
+create table t2 (a int);
+create table t1 (a int, b int as (a % 2) persistent references t2(a));
+show create table t1;
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+--error ER_PARSE_ERROR
+alter table t1 modify b int as (a % 2) persistent references t2(a);
+show create table t1;
+drop table t1;

=== added file 'mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc'
--- a/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,43 @@
+################################################################################
+# inc/vcol_dependencies_on_vcol.inc                                            #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing scenarios when columns depend on virtual columns, i.e. such as      #
+#   - a virtual column is based on a virtual column                            #
+#   - a "real" column on which a virtual one is renamed/dropped                #
+#   - a virtual column involved in partitioning is renamed/dropped             #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+--echo # Can't define a virtual column on another virtual column
+--error ER_VCOL_BASED_ON_VCOL
+create table t1 (a int, b int as (a+1), c int as (b+1));
+create table t1 (a int, b int as (a+1));
+--error ER_VCOL_BASED_ON_VCOL
+alter table t1 add column c int as (b+1);
+drop table t1;
+
+--echo # Can't rename or drop a column used in the function of a virtual column
+create table t1 (a int, b int as (a+1));
+--echo # On renaming/dropping a column on which a virtual field is 
+--echo # defined the following error is displayed: 
+--echo # "Unknown column 'a' in 'virtual column function'"
+--error ER_BAD_FIELD_ERROR
+alter table t1 drop column a;
+--error ER_BAD_FIELD_ERROR
+alter table t1 change a c int;
+drop table t1;
+
+--echo # Can't rename or drop a virtual column used by the paritition function
+create table t1 (a int, b int as (a+1)) partition by hash(b);  
+--error ER_BAD_FIELD_ERROR
+alter table t1 drop b;                                               
+--error ER_BAD_FIELD_ERROR
+alter table t1 change b c int as (a+1);
+

=== added file 'mysql-test/suite/vcol/inc/vcol_handler.inc'
--- a/mysql-test/suite/vcol/inc/vcol_handler.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_handler.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,77 @@
+################################################################################
+# inc/vcol_handler.inc                                                         #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing HANDLER.                                                            #
+#                                                                              #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+create table t1 (a int, 
+                 b int as (-a),
+		 c int as (-a) persistent,
+		 d char(1),
+		 index (a),
+		 index (c));
+insert into t1 (a,d) values (4,'a'), (2,'b'), (1,'c'), (3,'d');
+select * from t1;
+
+--echo # HANDLER tbl_name OPEN
+handler t1 open;
+
+--echo # HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...)
+handler t1 read a > (2);
+
+--echo # HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE non-vcol_field=expr
+handler t1 read a > (2) where d='c';
+
+--echo # HANDLER tbl_name READ vcol_index_name = (value1,value2,...)
+handler t1 read c = (-2);
+
+--echo # HANDLER tbl_name READ vcol_index_name = (value1,value2,...) WHERE non-vcol_field=expr
+handler t1 read c = (-2) where d='c';
+
+--echo # HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE vcol_field=expr
+handler t1 read a > (2) where b=-3 && c=-3;
+
+--echo # HANDLER tbl_name READ vcol_index_name <= (value1,value2,...)
+handler t1 read c <= (-2);
+
+--echo # HANDLER tbl_name READ vcol_index_name > (value1,value2,...) WHERE vcol_field=expr
+handler t1 read c <= (-2) where b=-3;
+
+--echo # HANDLER tbl_name READ vcol_index_name FIRST
+handler t1 read c first;
+
+--echo # HANDLER tbl_name READ vcol_index_name NEXT
+handler t1 read c next;
+
+--echo # HANDLER tbl_name READ vcol_index_name PREV
+handler t1 read c prev;
+
+--echo # HANDLER tbl_name READ vcol_index_name LAST
+handler t1 read c last;
+
+--echo # HANDLER tbl_name READ FIRST where non-vcol=expr
+handler t1 read FIRST where a >= 2; 
+
+--echo # HANDLER tbl_name READ FIRST where vcol=expr
+handler t1 read FIRST where b >= -2; 
+
+--echo # HANDLER tbl_name READ NEXT where non-vcol=expr
+handler t1 read NEXT where d='c'; 
+
+--echo # HANDLER tbl_name READ NEXT where vcol=expr
+handler t1 read NEXT where b<=-4; 
+
+--echo # HANDLER tbl_name CLOSE
+handler t1 close;
+
+drop table t1;

=== added file 'mysql-test/suite/vcol/inc/vcol_init_vars.pre'
--- a/mysql-test/suite/vcol/inc/vcol_init_vars.pre	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_init_vars.pre	2009-10-16 22:57:48 +0000
@@ -0,0 +1,17 @@
+################################################################################
+# inc/vcol_init_vars.pre                                                       #
+#                                                                              #
+# Purpose:                                                                     #
+#  Initialize variables used in t/<name> test cases.                           #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+let $skip_full_text_check = 0;
+let $skip_spatial_index_check = 0;

=== added file 'mysql-test/suite/vcol/inc/vcol_ins_upd.inc'
--- a/mysql-test/suite/vcol/inc/vcol_ins_upd.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_ins_upd.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,289 @@
+################################################################################
+# inc/vcol_ins_upd.inc                                                         #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing DDL operations such as INSERT, UPDATE, REPLACE and DELETE.          #
+#                                                                              #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+let $create1 = create table t1 (a int, 
+                                b int as (-a),
+				c int as (-a) persistent);
+let $create2 = create table t1 (a int unique, 
+                                b int as (-a),
+				c int as (-a) persistent);
+let $create3 = create table t1 (a int, 
+                                b int as (-a),
+				c int as (-a) persistent unique);
+let $create4 = create table t1 (a int, 
+                                b int as (-a),
+				c int as (-a) persistent unique,
+				d varchar(16));
+eval $create1;
+set sql_warnings = 1;
+
+--echo #
+--echo # *** INSERT ***
+--echo #
+
+--echo # INSERT INTO tbl_name VALUES... DEFAULT is specified against vcols
+insert into t1 values (1,default,default);
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # INSERT INTO tbl_name VALUES... NULL is specified against vcols
+insert into t1 values (1,null,null);
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols
+insert into t1 values (1,2,3);
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # INSERT INTO tbl_name (<non_vcol_list>) VALUES...
+insert into t1 (a) values (1), (2);
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # INSERT INTO tbl_name (<normal+vcols>) VALUES... DEFAULT is specified 
+--echo # against vcols
+insert into t1 (a,b) values (1,default), (2,default);
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # INSERT INTO tbl_name (<normal+vcols>) VALUES... NULL is specified against vcols
+insert into t1 (a,b) values (1,null), (2,null);
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # INSERT INTO tbl_name (<normal+vcols>) VALUES... a non-NULL value is specified 
+--echo # against vcols
+insert into t1 (a,b) values (1,3), (2,4);
+select * from t1;
+delete from t1;
+select * from t1;
+drop table t1;
+
+--echo # Table with UNIQUE non-vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE 
+--echo # KEY UPDATE <non_vcol>=expr, <vcol>=expr
+eval $create2;
+insert into t1 values (1,default,default);
+insert into t1 values (1,default,default) 
+       on duplicate key update a=2, b=default;
+select a,b,c from t1;
+delete from t1 where b in (1,2);
+select * from t1;
+drop table t1;
+
+--echo # Table with UNIQUE vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE 
+--echo # KEY UPDATE <non_vcol>=expr, <vcol>=expr
+eval $create3;
+insert into t1 values (1,default,default);
+insert into t1 values (1,default,default) 
+       on duplicate key update a=2, b=default;
+select a,b,c from t1;
+
+--echo # CREATE new_table ... LIKE old_table
+--echo # INSERT INTO new_table SELECT * from old_table
+create table t2 like t1;
+insert into t2 select * from t1;
+select * from t1;
+drop table t2;
+
+--echo # CREATE new_table ... LIKE old_table INSERT INTO new_table (<non-vcols>, <vcols>) 
+--echo # SELECT <non-vcols>, <vcols> from old_table
+insert into t1 values (1,default,default);
+select * from t1;
+create table t2 like t1;
+insert into t2 (a,b) select a,b from t1;
+select * from t2;
+drop table t2;
+drop table t1;
+
+--echo #
+--echo # *** UPDATE ***
+--echo #
+
+--echo # UPDATE tbl_name SET non-vcol=expr WHERE non-vcol=expr
+eval $create1;
+insert into t1 (a) values (1), (2);
+select * from t1;
+update t1 set a=3 where a=2;
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # UPDATE tbl_name SET vcol=expr WHERE non-vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+update t1 set c=3 where a=2;
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+update t1 set a=3 where b=-2;
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # UPDATE tbl_name SET vcol=expr WHERE vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+update t1 set c=3 where b=-2;
+select * from t1;
+delete from t1;
+select * from t1;
+drop table t1;
+
+--echo # INDEX created on vcol 
+--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=const
+eval $create3;
+insert into t1 (a) values (1), (2);
+select * from t1;
+update t1 set a=3 where c=-2;
+select * from t1;
+delete from t1;
+select * from t1;
+
+
+--echo # INDEX created on vcol 
+--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2
+insert into t1 (a) values (1), (2);
+select * from t1;
+update t1 set a=3 where c between -3 and -2;
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # No INDEX created on vcol 
+--echo # UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2
+insert into t1 (a) values (1), (2);
+select * from t1;
+update t1 set a=3 where b between -3 and -2;
+select * from t1;
+delete from t1;
+select * from t1;
+
+--echo # INDEX created on vcol 
+--echo # UPDATE tbl_name SET non-vcol=expr 
+--echo # WHERE vcol=between const1 and const2 ORDER BY vcol
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+update t1 set a=6 where c between -1 and 0
+          order by c;
+select * from t1;
+delete from t1 where c between -6 and 0;
+select * from t1;
+
+--echo # INDEX created on vcol 
+--echo # UPDATE tbl_name SET non-vcol=expr 
+--echo # WHERE vcol=between const1 and const2 ORDER BY vcol LIMIT 2
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+update t1 set a=6 where c between -1 and 0
+          order by c limit 2;
+select * from t1;
+delete from t1 where c between -2 and 0 order by c;
+select * from t1;
+delete from t1;
+
+--echo # INDEX created on vcol 
+--echo # UPDATE tbl_name SET non-vcol=expr
+--echo # WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+update t1 set a=6 where (c between -2 and 0) and (b=-1);
+select * from t1;
+delete from t1;
+
+--echo # INDEX created on vcol 
+--echo # UPDATE tbl_name SET non-vcol=expr
+--echo # WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3
+--echo # ORDER BY indexed vcol
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+update t1 set a=6 where (c between -2 and 0) and (b=-1) order by c;
+select * from t1;
+delete from t1;
+drop table t1;
+
+let $innodb_engine = `SELECT @@session.storage_engine='innodb'`;
+if ($innodb_engine)
+{
+  --echo #
+  --echo # Verify ON UPDATE/DELETE actions of FOREIGN KEYs
+  create table t2 (a int primary key, name varchar(10));
+  create table t1 (a int primary key, b int as (a % 10) persistent);
+  insert into t2 values (1, 'value1'), (2,'value2'), (3,'value3');
+  insert into t1 (a) values (1),(2),(3);
+  select * from t1;
+  select * from t2;
+  select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+
+  --echo #  - ON UPDATE RESTRICT
+  alter table t1 add foreign key (b) references t2(a) on update restrict;
+  --error ER_NO_REFERENCED_ROW_2
+  insert into t1 (a) values (4);
+  --error ER_ROW_IS_REFERENCED_2
+  update t2 set a=4 where a=3;
+  select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+  alter table t1 drop foreign key t1_ibfk_1;
+
+  --echo #  - ON DELETE RESTRICT
+  alter table t1 add foreign key (b) references t2(a) on delete restrict;
+  --error ER_ROW_IS_REFERENCED_2
+  delete from t2 where a=3;
+  select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+  select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a);
+  alter table t1 drop foreign key t1_ibfk_1;
+
+  --echo #  - ON DELETE CASCADE
+  alter table t1 add foreign key (b) references t2(a) on delete cascade;
+  delete from t2 where a=3;
+  select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+  select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a);
+  alter table t1 drop foreign key t1_ibfk_1;
+
+  drop table t1;
+  drop table t2;
+}
+
+--echo #
+--echo # *** REPLACE ***
+--echo #
+
+--echo # UNIQUE INDEX on vcol
+--echo # REPLACE tbl_name (non-vcols) VALUES (non-vcols);
+eval $create4;
+insert into t1 (a,d) values (1,'a'), (2,'b');
+select * from t1;
+replace t1 (a,d) values (1,'c');
+select * from t1;
+delete from t1;
+select * from t1;
+
+
+# *** DELETE
+# All required tests for DELETE are performed as part of the above testing
+# for INSERT, UPDATE and REPLACE.
+
+set sql_warnings = 0;
+drop table t1;

=== added file 'mysql-test/suite/vcol/inc/vcol_keys.inc'
--- a/mysql-test/suite/vcol/inc/vcol_keys.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_keys.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,163 @@
+################################################################################
+# inc/vcol_keys.inc                                                            #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing keys, indexes defined upon virtual columns.                         #
+#                                                                              #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+
+--echo #            - UNIQUE KEY
+--echo #            - INDEX
+--echo #            - FULLTEXT INDEX
+--echo #            - SPATIAL INDEX (not supported)
+--echo #            - FOREIGN INDEX (partially supported)
+--echo #            - CHECK (allowed but not used)
+
+--echo # UNIQUE
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a*2) unique);
+create table t1 (a int, b int as (a*2) persistent unique);
+show create table t1;
+describe t1;
+drop table t1;
+
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a*2), unique key (b));
+create table t1 (a int, b int as (a*2) persistent, unique (b));
+show create table t1;
+describe t1;
+drop table t1;
+
+create table t1 (a int, b int as (a*2));
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+alter table t1 add unique key (b);
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add unique key (b);
+drop table t1;
+
+--echo # Testing data manipulation operations involving UNIQUE keys 
+--echo # on virtual columns can be found in:
+--echo #  - vcol_ins_upd.inc
+--echo #  - vcol_select.inc
+
+--echo # 
+--echo # INDEX
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a*2), index (b));
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a*2), index (a,b));
+
+create table t1 (a int, b int as (a*2) persistent, index (b));
+show create table t1;
+describe t1;
+drop table t1;
+
+create table t1 (a int, b int as (a*2) persistent, index (a,b));
+show create table t1;
+describe t1;
+drop table t1;
+
+create table t1 (a int, b int as (a*2));
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+alter table t1 add index (b);
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+alter table t1 add index (a,b);
+drop table t1;
+
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add index (b);
+drop table t1;
+
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add index (a,b);
+create table t2 like t1;
+drop table t2;
+drop table t1;
+
+--echo # Testing data manipulation operations involving INDEX
+--echo # on virtual columns can be found in:
+--echo #  - vcol_select.inc
+
+--echo #
+--echo # TODO: FULLTEXT INDEX
+
+--echo # SPATIAL INDEX
+if (!$skip_spatial_index_check)
+{
+  --echo # Error "All parts of a SPATIAL index must be NOT NULL"
+  --error ER_SPATIAL_CANT_HAVE_NULL
+  create table t1 (a int, b int as (a+1) persistent, spatial index (b));
+  create table t1 (a int, b int as (a+1) persistent);
+  --error ER_SPATIAL_CANT_HAVE_NULL
+  alter table t1 add spatial index (b);
+  drop table t1;
+}
+
+--echo # FOREIGN KEY
+
+--echo # Rejected FK options.
+--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN 
+create table t1 (a int, b int as (a+1) persistent,
+                 foreign key (b) references t2(a) on update set null);
+--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN 
+create table t1 (a int, b int as (a+1) persistent,
+                 foreign key (b) references t2(a) on update cascade);
+--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN 
+create table t1 (a int, b int as (a+1) persistent,
+                 foreign key (b) references t2(a) on delete set null);
+
+create table t1 (a int, b int as (a+1) persistent);
+--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN 
+alter table t1 add foreign key (b) references t2(a) on update set null;
+--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN 
+alter table t1 add foreign key (b) references t2(a) on update cascade;
+--error ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN 
+alter table t1 add foreign key (b) references t2(a) on delete set null;
+drop table t1;
+
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a+1),
+                 foreign key (b) references t2(a));
+
+create table t1 (a int, b int as (a+1));
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+alter table t1 add foreign key (b) references t2(a);
+drop table t1;
+
+--echo # Allowed FK options.
+create table t2 (a int primary key, b char(5));
+create table t1 (a int, b int as (a % 10) persistent,
+                 foreign key (b) references t2(a) on update restrict);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+                 foreign key (b) references t2(a) on update no action);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+                 foreign key (b) references t2(a) on delete restrict);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+                 foreign key (b) references t2(a) on delete cascade);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+                 foreign key (b) references t2(a) on delete no action);
+drop table t1;
+
+--echo 
+--echo # Testing data manipulation operations involving FOREIGN KEY 
+--echo # on virtual columns can be found in:
+--echo #  - vcol_ins_upd.inc
+--echo #  - vcol_select.inc
+
+--echo #
+--echo # TODO: CHECK
+

=== added file 'mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc'
--- a/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,162 @@
+################################################################################
+# inc/vcol_non_stored_columns.inc                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#  Ensure that MySQL behaviour is consistent irrelevant of                     #
+#    - the place of a non-stored column among other columns,                   #
+#    - the total number of non-stored fields.                                  #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+--echo # Case 1. All non-stored columns.
+--echo # This scenario is currently impossible due to the fact that virtual columns
+--echo # with a constant expression are not allowed.
+
+--echo # Case 2. CREATE
+--echo #  - Column1: "real"
+--echo #  - Column 2: virtual non-stored
+create table t1 (a int, b int as (-a));
+insert into t1 values (1,default);
+select * from t1;
+insert into t1 values (2,default);
+select * from t1;
+drop table t1;
+
+--echo # Case 3. CREATE
+--echo #  - Column1: "real"
+--echo #  - Column 2: virtual stored
+create table t1 (a int, b int as (-a) persistent);
+insert into t1 values (1,default);
+select * from t1;
+insert into t1 values (2,default);
+select * from t1;
+drop table t1;
+
+--echo # Case 4. CREATE
+--echo #  - Column1: virtual non-stored
+--echo #  - Column2: "real"
+create table t1 (a int as (-b), b int);
+insert into t1 values (default,1);
+select * from t1;
+insert into t1 values (default,2);
+select * from t1;
+drop table t1;
+
+--echo # Case 5. CREATE
+--echo #  - Column1: virtual stored
+--echo #  - Column2: "real"
+create table t1 (a int as (-b) persistent, b int);
+insert into t1 values (default,1);
+select * from t1;
+insert into t1 values (default,2);
+select * from t1;
+drop table t1;
+
+--echo # Case 6. CREATE
+--echo #  - Column1: "real"
+--echo #  - Column2: virtual non-stored
+--echo #  - Column3: virtual stored
+create table t1 (a int, b int as (-a), c int as (-a) persistent);
+insert into t1 values (1,default,default);
+select * from t1;
+insert into t1 values (2,default,default);
+select * from t1;
+drop table t1;
+
+--echo # Case 7. ALTER. Modify virtual stored -> virtual non-stored
+create table t1 (a int, b int as (a % 2) persistent);
+--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+alter table t1 modify b int as (a % 2);
+show create table t1;
+drop table t1;
+
+--echo # Case 8. ALTER. Modify virtual non-stored -> virtual stored
+create table t1 (a int, b int as (a % 2));
+--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+alter table t1 modify b int as (a % 2) persistent;
+show create table t1;
+drop table t1;
+
+--echo # Case 9. CREATE LIKE
+--echo #  - Column1: "real"
+--echo #  - Column2: virtual non-stored
+--echo #  - Column3: virtual stored
+create table t1 (a int, b int as (-a), c int as (-a) persistent);
+create table t2 like t1;
+insert into t2 values (1,default,default);
+select * from t2;
+insert into t2 values (2,default,default);
+select * from t2;
+drop table t2;
+drop table t1;
+
+--echo # Case 10. ALTER. Dropping a virtual non-stored column.
+--echo #  - Column1: virtual non-stored
+--echo #  - Column2: "real"
+create table t1 (a int as (-b), b int, c varchar(5));
+insert into t1 values (default,1,'v1');
+insert into t1 values (default,2,'v2');
+select * from t1;
+alter table t1 drop column a;
+select * from t1;
+show create table t1;
+drop table t1;
+
+--echo # Case 11. ALTER. Dropping a virtual stored column.
+--echo #  - Column1: virtual stored
+--echo #  - Column2: "real"
+create table t1 (a int as (-b) persistent, b int, c char(5));
+insert into t1 values (default,1,'v1');
+insert into t1 values (default,2,'v2');
+select * from t1;
+alter table t1 drop column a;
+select * from t1;
+show create table t1;
+drop table t1;
+
+--echo # Case 12. ALTER. Adding a new virtual non-stored column.
+create table t1 (a int, b datetime);
+insert into t1 values (1,'2008-09-04');
+insert into t1 values (2,'2008-09-05');
+select * from t1;
+alter table t1 add column c int as (dayofyear(b)) after a;
+select * from t1;
+show create table t1;
+drop table t1;
+
+--echo # Case 13. ALTER. Adding a new virtual stored column.
+create table t1 (a int, b datetime);
+insert into t1 values (1,'2008-09-04');
+insert into t1 values (2,'2008-09-05');
+select * from t1;
+alter table t1 add column c int as (dayofyear(b)) persistent after a;
+select * from t1;
+show create table t1;
+drop table t1;
+
+--echo # Case 14. ALTER. Changing the expression of a virtual stored column.
+create table t1 (a int, b datetime, c int as (week(b)) persistent);
+insert into t1 values (1,'2008-09-04',default);
+insert into t1 values (2,'2008-09-05',default);
+select * from t1;
+alter table t1 change column c c int as (week(b,1)) persistent;
+select * from t1;
+show create table t1;
+drop table t1;
+
+--echo # Case 15. ALTER. Changing the expression of a virtual non-stored column.
+create table t1 (a int, b datetime, c int as (week(b)));
+insert into t1 values (1,'2008-09-04',default);
+insert into t1 values (2,'2008-09-05',default);
+select * from t1;
+alter table t1 change column c c int as (week(b,1));
+select * from t1;
+show create table t1;
+drop table t1;
+

=== added file 'mysql-test/suite/vcol/inc/vcol_partition.inc'
--- a/mysql-test/suite/vcol/inc/vcol_partition.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_partition.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,160 @@
+################################################################################
+# inc/vcol_partition.inc                                                       #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing partitioning tables with virtual columns.                           #
+#                                                                              #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+--source include/have_partition.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--echo # Case 1. Partitioning by RANGE based on a non-stored virtual column.
+
+CREATE TABLE t1 (
+    a DATE NOT NULL,
+    b int as (year(a))
+)
+PARTITION BY RANGE( b ) (
+    PARTITION p0 VALUES LESS THAN (2006),
+    PARTITION p2 VALUES LESS THAN (2008)
+);
+
+insert into t1 values ('2006-01-01',default);
+insert into t1 values ('2007-01-01',default);
+insert into t1 values ('2005-01-01',default);
+select * from t1;
+
+# Specifically for MyISAM, check that data is written into correct 
+# $MYSQLTEST_VARDIR/mysqld.1/data/test/t1*p?.MYD files
+let $myisam_engine = `select @@session.storage_engine='myisam'`;
+if ($myisam_engine)
+{
+ --echo # Check how data is physically partitioned.
+ --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+ --exec du -b $MYSQLTEST_VARDIR/mysqld.1/data/test/t1*p?.MYD
+}
+
+--echo # Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+
+select * from t1;
+
+if ($myisam_engine)
+{
+ --echo # Check how data is physically partitioned.
+ --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+ --exec du -b $MYSQLTEST_VARDIR/mysqld.1/data/test/t1*p?.MYD
+}
+
+drop table t1;
+
+--echo # Case 2. Partitioning by LIST based on a stored virtual column.
+
+CREATE TABLE t1 (a int, b int as (a % 3 ) persistent)
+PARTITION BY LIST (a+1)
+(PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2));
+
+insert into t1 values (1,default);
+if ($myisam_engine)
+{
+ --echo # Check how data is physically partitioned.
+ --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+ --exec du -b $MYSQLTEST_VARDIR/mysqld.1/data/test/t1*p?.MYD
+}
+select * from t1;
+
+#
+# NOTE: The following tests are currently failing due to a
+#       [suspected] bug in the existing partition functionality.
+#       Here is what was observed when using mysqld compiled prior 
+#       to adding the virtual column functionality.
+#         mysql> create table t1 (a int) partition by list (a) 
+#                (partition p1 values in (1), partition p2 values in (2));
+#         Query OK, 0 rows affected (0.00 sec)
+#
+#         mysql> insert into t1 values (1), (1), (2);                                                                   
+#         Query OK, 3 rows affected (0.00 sec)
+#         Records: 3  Duplicates: 0  Warnings: 0
+#
+#         mysql> select * from t1;                                                                                      
+#         +------+
+#         | a    |
+#         +------+
+#         |    1 | 
+#         |    1 | 
+#         |    2 | 
+#         +------+
+#         3 rows in set (0.00 sec)
+#       
+#         mysql> alter table t1 reorganize partition p1 into 
+#                (partition p1 values in (3));                              
+#         Query OK, 2 rows affected (3.90 sec)
+#         Records: 2  Duplicates: 2  Warnings: 0
+#         
+#         mysql> select * from t1;                                                        
+#         +------+
+#         | a    |
+#         +------+
+#         |    2 |             <- Two row have been lost!!! 
+#         +------+
+#         1 row in set (0.00 sec)
+
+#
+#alter table t1 change b b int as ((a % 3)+1) persistent;
+#--error ER_NO_PARTITION_FOR_GIVEN_VALUE
+#alter table t1 change b b int as (a % 2) persistent;
+#if ($myisam_engine)
+#{
+# --echo # Check how data is physically partitioned.
+# --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+# --exec du -b $MYSQLTEST_VARDIR/mysqld.1/data/test/t1*p?.MYD
+#}
+
+select * from t1;
+
+drop table t1;
+
+--echo # Case 3. Partitioning by HASH based on a non-stored virtual column.
+
+CREATE TABLE t1 (
+    a DATE NOT NULL,
+    b int as (year(a))
+)
+PARTITION BY HASH( b % 3 ) PARTITIONS 3;
+
+insert into t1 values ('2005-01-01',default);
+insert into t1 values ('2006-01-01',default);
+select * from t1;
+
+if ($myisam_engine)
+{
+ --echo # Check how data is physically partitioned.
+ --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+ --exec du -b $MYSQLTEST_VARDIR/mysqld.1/data/test/t1*p?.MYD
+}
+
+--echo # Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+
+select * from t1;
+
+if ($myisam_engine)
+{
+ --echo # Check how data is physically partitioned.
+ --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+ --exec du -b $MYSQLTEST_VARDIR/mysqld.1/data/test/t1*p?.MYD
+}
+
+drop table t1;

=== added file 'mysql-test/suite/vcol/inc/vcol_select.inc'
--- a/mysql-test/suite/vcol/inc/vcol_select.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_select.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,216 @@
+################################################################################
+# inc/vcol_select.inc                                                          #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing different SELECTs.                                                  #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-18                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+# Table t1 is used below to test:
+#  - Join type of ALL (sequential scan of the entire table)
+#  - Join type of Index
+#  - Join type of Range
+#  - Join type of Ref_or_null
+create table t1 (a int,
+                 b int as (-a),
+                 c int as (-a) persistent,
+                 index (c));
+insert into t1 (a) values (2), (1), (1), (3), (NULL);
+
+# Table t2 is used below to test:
+#  - Join type of system and const
+create table t2 like t1;
+insert into t2 (a) values (1);
+
+# Table t3 is used below to test
+#  - Join type of Eq_ref with a unique virtual column
+#  - Join type of Const
+create table t3 (a int primary key, 
+                 b int as (-a),
+		 c int as (-a) persistent unique);
+insert into t3 (a) values (2),(1),(3);
+
+
+--echo # select_type=SIMPLE, type=system
+let $s = select * from t2;
+eval $s;
+eval explain $s;
+
+let $s = select * from t2 where c=-1;
+eval $s;
+eval explain $s;
+
+--echo # select_type=SIMPLE, type=ALL
+let $s = select * from t1 where b=-1;
+eval $s;
+eval explain $s;
+
+--echo # select_type=SIMPLE, type=const
+let $s = select * from t3 where a=1;
+eval $s;
+eval explain $s;
+
+--echo # select_type=SIMPLE, type=range
+let $s = select * from t3 where c>=-1;
+eval $s;
+eval explain $s;
+
+--echo # select_type=SIMPLE, type=ref
+let $s = select * from t1,t3 where t1.c=t3.c and t3.c=-1;
+eval $s;
+eval explain $s;
+
+--echo # select_type=PRIMARY, type=index,ALL
+let $s = select * from t1 where b in (select c from t3);
+eval $s;
+eval explain $s;
+
+--echo # select_type=PRIMARY, type=range,ref
+let $s = select * from t1 where c in (select c from t3 where c between -2 and -1);
+eval $s;
+eval explain $s;
+
+--echo # select_type=UNION, type=system
+--echo # select_type=UNION RESULT, type=<union1,2>
+let $s = select * from t1 union select * from t2;
+eval $s;
+eval explain $s;
+
+--echo # select_type=DERIVED, type=system
+let $s = select * from (select a,b,c from t1) as t11;
+eval $s;
+eval explain $s;
+
+--echo ###
+--echo ### Using aggregate functions with/without DISTINCT
+--echo ###
+--echo # SELECT COUNT(*) FROM tbl_name
+let $s = select count(*) from t1;
+eval $s;
+eval explain $s;
+
+--echo # SELECT COUNT(DISTINCT <non-vcol>) FROM tbl_name
+let $s = select count(distinct a) from t1;
+eval $s;
+eval explain $s;
+
+--echo # SELECT COUNT(DISTINCT <non-stored vcol>) FROM tbl_name
+let $s = select count(distinct b) from t1;
+eval $s;
+eval explain $s;
+
+--echo # SELECT COUNT(DISTINCT <stored vcol>) FROM tbl_name
+let $s = select count(distinct c) from t1;
+eval $s;
+eval explain $s;
+
+--echo ###
+--echo ### filesort & range-based utils
+--echo ###
+--echo # SELECT * FROM tbl_name WHERE <vcol expr>
+let $s = select * from t3 where c >= -2;
+eval $s;
+eval explain $s;
+
+--echo # SELECT * FROM tbl_name WHERE <non-vcol expr>
+let $s = select * from t3 where a between 1 and 2;
+eval $s;
+eval explain $s;
+
+--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr>
+let $s = select * from t3 where b between -2 and -1;
+eval $s;
+eval explain $s;
+
+--echo # SELECT * FROM tbl_name WHERE <indexed vcol expr>
+let $s = select * from t3 where c between -2 and -1;
+eval $s;
+eval explain $s;
+
+#### Remove for MyISAM due to a bug
+#### when all the three records are returned (a=1,2,3) 
+#### instead of just two (a=1,2).
+#### This bug is presumably in base SQL routines as the same happens
+#### with this table:
+####   create table t4 (a int primary key, b int, c int unique);
+let $myisam_engine = `SELECT @@session.storage_engine='myisam'`;
+if (!$myisam_engine)
+{
+  --echo # SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <non-indexed vcol>
+  let $s = select * from t3 where a between 1 and 2 order by b;
+  eval $s;
+  eval explain $s;
+}
+
+--echo # SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol>
+let $s = select * from t3 where a between 1 and 2 order by c;
+eval $s;
+eval explain $s;
+
+--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol>
+let $s = select * from t3 where b between -2 and -1 order by a;
+eval $s;
+eval explain $s;
+
+#### Remove for MyISAM due to a bug
+#### when all the three records are returned (a=1,2,3) 
+#### instead of just two (a=1,2).
+#### This bug is presumably in base SQL routines as the same happens
+#### with this table:
+####   create table t4 (a int primary key, b int, c int unique);
+let $innodb_engine = `SELECT @@session.storage_engine='innodb'`;
+if (!$innodb_engine)
+{
+  --echo # SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-vcol>
+  let $s = select * from t3 where c between -2 and -1 order by a;
+  eval $s;
+  eval explain $s;
+}
+
+--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol>
+let $s = select * from t3 where b between -2 and -1 order by b;
+eval $s;
+eval explain $s;
+
+--echo # SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-indexed vcol>
+let $s = select * from t3 where c between -2 and -1 order by b;
+eval $s;
+eval explain $s;
+
+--echo # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol>
+let $s = select * from t3 where b between -2 and -1 order by c;
+eval $s;
+eval explain $s;
+
+--echo # SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <indexed vcol>
+let $s = select * from t3 where c between -2 and -1 order by c;
+eval $s;
+eval explain $s;
+
+--echo # SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
+let $s = select sum(b) from t1 group by b;
+eval $s;
+eval explain $s;
+
+--echo # SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <indexed vcol>
+let $s = select sum(c) from t1 group by c;
+eval $s;
+eval explain $s;
+
+--echo # SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <indexed vcol>
+let $s = select sum(b) from t1 group by c;
+eval $s;
+eval explain $s;
+
+--echo # SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
+let $s = select sum(c) from t1 group by b;
+eval $s;
+eval explain $s;
+

=== added file 'mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc'
--- a/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,42 @@
+################################################################################
+# inc/vcol_supported_sql_funcs.inc                                             #
+#                                                                              #
+# Purpose:                                                                     #
+#  Tests frame for allowed sql functions                                       #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+--enable_warnings
+set sql_warnings = 1;
+eval create table t1 ($cols);
+show create table t1;
+if ($rows)
+{
+  eval insert into t1 values ($values1);
+  dec $rows;
+}
+if ($rows)
+{
+  eval insert into t1 values ($values2);
+  dec $rows;
+}
+if ($rows)
+{
+  eval insert into t1 values ($values3);
+  dec $rows;
+}
+if ($rows)
+{
+  eval insert into t1 values ($values4);
+  dec $rows;
+}
+select * from t1;
+drop table t1;
+set sql_warnings = 0;

=== added file 'mysql-test/suite/vcol/inc/vcol_supported_sql_funcs_main.inc'
--- a/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs_main.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs_main.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,1228 @@
+################################################################################
+# inc/vcol_supported_sql_funcs_main.inc                                        #
+#                                                                              #
+# Purpose:                                                                     #
+#  Tests frame for allowed sql functions                                       #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+--echo #
+--echo # NUMERIC FUNCTIONS
+--echo #
+
+--echo # ABS()
+let $cols = a int, b int as (abs(a));
+let $values1 = -1, default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ACOS()
+let $cols = a double, b double as (format(acos(a),6));
+let $values1 = 1, default;
+let $values2 = 1.0001,default;
+let $values3 = 0,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ASIN()
+let $cols = a double, b double as (format(asin(a),6));
+let $values1 = 0.2, default;
+let $values2 = 1.0001,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo #ATAN
+let $cols = a double, b double, c double as (format(atan(a,b),6));
+let $values1 = -2,2,default;
+let $values2 = format(PI(),6),0,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+let $cols = a double, c double as (format(atan(a),6));
+let $values1 = -2,default;
+let $values2 = format(PI(),6),default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ATAN2
+let $cols = a double, b double, c double as (format(atan2(a,b),6));
+let $values1 = -2,2,default;
+let $values2 = format(PI(),6),0,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CEIL()
+let $cols = a double, b int as (ceil(a));
+let $values1 = 1.23,default;
+let $values2 = -1.23,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CONV()
+let $cols = a varchar(10), b int, c int, d varchar(10) as (conv(a,b,c));
+let $values1 = 'a',16,2,default;
+let $values2 = '6e',18,8,default;
+let $values3 = -17,10,-18,default;
+let $values4 = 10+'10'+'10'+0xa,10,10,default;
+let $rows = 4;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # COS()
+let $cols = a double, b double as (format(cos(a),6));
+let $values1 = format(PI(),6),default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # COT()
+let $cols = a double, b double as (format(cot(a),6));
+let $values1 = 12,default;
+let $values2 = 0,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CRC32()
+let $cols = a varchar(10), b long as (crc32(a));
+let $values1 = 'MySQL',default;
+let $values2 = 'mysql',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DEGREES()
+let $cols = a double, b double as (format(degrees(a),6));
+let $values1 = format(PI(),6),default;
+let $values2 = format(PI()/2,6),default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # /
+let $cols = a double, b double as (a/2);
+let $values1 = 2,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # EXP()
+let $cols = a double, b double as (format(exp(a),6));
+let $values1 = 2,default;
+let $values2 = -2,default;
+let $values3 = 0,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # FLOOR()
+let $cols = a double, b long as (floor(a));
+let $values1 = 1.23,default;
+let $values2 = -1.23,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LN()
+let $cols = a double, b double as (format(ln(a),6));
+let $values1 = 2,default;
+let $values2 = -2,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LOG()
+let $cols = a double, b double, c double as (format(log(a,b),6));
+let $values1 = 2,65536,default;
+let $values2 = 10,100,default;
+let $values3 = 1,100,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+let $cols = a double, b double as (format(log(a),6));
+let $values1 = 2,default;
+let $values2 = -2,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LOG2()
+let $cols = a double, b double as (format(log2(a),6));
+let $values1 = 65536,default;
+let $values2 = -100,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LOG10()
+let $cols = a double, b double as (format(log10(a),6));
+let $values1 = 2,default;
+let $values2 = 100,default;
+let $values3 = -100,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # -
+let $cols = a double, b double as (a-1);
+let $values1 = 2,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MOD()
+let $cols = a int, b int as (mod(a,10));
+let $values1 = 1,default;
+let $values2 = 11,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # %
+let $cols = a int, b int as (a % 10);
+let $values1 = 1,default;
+let $values2 = 11,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # OCT()
+let $cols = a double, b varchar(10) as (oct(a));
+let $values1 = 12,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # PI()
+let $cols = a double, b double as (format(PI()*a*a,6));
+let $values1 = 1,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # +
+let $cols = a int, b int as (a+1);
+let $values1 = 1,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # POW, POWER
+let $cols = a int, b int as (pow(a,2)), c int as (power(a,2));
+let $values1 = 1,default,default;
+let $values2 = 2,default,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # RADIANS()
+let $cols = a double, b double as (format(radians(a),6));
+let $values1 = 90,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ROUND()
+let $cols = a double, b int as (round(a));
+let $values1 = -1.23,default;
+let $values2 = -1.58,default;
+let $values3 = 1.58,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+let $cols = a double, b double, c int as (round(a,b));
+let $values1 = 1.298,1,default;
+let $values2 = 1.298,0,default;
+let $values3 = 23.298,-1,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SIGN()
+let $cols = a double, b int as (sign(a));
+let $values1 = -32,default;
+let $values2 = 0,default;
+let $values3 = 234,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SIN()
+let $cols = a double, b double as (format(sin(a),6));
+let $values1 = format(PI()/2,6),default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SQRT()
+let $cols = a double, b double as (format(sqrt(a),6));
+let $values1 = 4,default;
+let $values2 = 20,default;
+let $values3 = -16,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TAN()
+let $cols = a double, b double as (format(tan(a),6));
+let $values1 = format(PI(),6),default;
+let $values2 = format(PI()+1,6),default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # *
+let $cols = a double, b double as (a*3);
+let $values1 = 0,default;
+let $values2 = 1,default;
+let $values3 = 2,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TRUNCATE()
+let $cols = a double, b double as (truncate(a,4));
+let $values1 = 1.223,default;
+let $values2 = 1.999,default;
+let $values3 = 1.999,default;
+let $values4 = 122,default;
+let $rows = 4;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # Unary -
+let $cols = a double, b double as (-a);
+let $values1 = 1,default;
+let $values2 = -1,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo #
+--echo # STRING FUNCTIONS
+--echo #
+
+--echo # ASCII()
+let $cols = a char(2), b int as (ascii(a));
+let $values1 = '2',default;
+let $values2 = 2,default;
+let $values3 = 'dx',default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # BIN()
+let $cols = a int, b varchar(10) as (bin(a));
+let $values1 = 12,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # BIT_LENGTH()
+let $cols = a varchar(10), b long as (bit_length(a));
+let $values1 = 'text',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CHAR_LENGTH()
+let $cols = a varchar(10), b long as (char_length(a));
+let $values1 = 'text',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CHAR()
+let $cols = a int, b int, c varbinary(10) as (char(a,b));
+let $values1 = 77,121,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CHARACTER_LENGTH()
+let $cols = a varchar(10), b long as (character_length(a));
+let $values1 = 'text',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CONCAT_WS()
+let $cols = a varchar(10), b varchar(10), c varchar(20) as (concat_ws(',',a,b));
+let $values1 = 'value1','value2',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CONCAT()
+let $cols = a varchar(10), b varchar(10), c varchar(20) as (concat(a,',',b));
+let $values1 = 'value1','value2',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ELT()
+let $cols = a varchar(10), b varchar(10), c int, d varchar(10) as (elt(c,a,b));
+let $values1 = 'value1','value2',1,default;
+let $values2 = 'value1','value2',2,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # EXPORT_SET()
+let $cols = a int, b varchar(10) as (export_set(a,'1','0','',10));
+let $values1 = 6,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # FIELD()
+let $cols = a varchar(10), b varchar(10), c int as (field('aa',a,b));
+let $values1 = 'aa','bb',default;
+let $values2 = 'bb','aa',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # FIND_IN_SET()
+let $cols = a varchar(10), b varchar(10), c int as (find_in_set(a,b));
+let $values1 = 'aa','aa,bb,cc',default;
+let $values2 = 'aa','bb,aa,cc',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # FORMAT()
+let $cols = a double, b varchar(20) as (format(a,2));
+let $values1 = 12332.123456,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # HEX()
+let $cols = a int, b varchar(10) as (hex(a));
+let $values1 = 17,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+let $cols = a varchar(10), b varchar(10) as (hex(a));
+let $values1 = 'abc',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # INSERT()
+let $cols = a varchar(10), b varchar(10), c varchar(20) as (insert(a,length(a),length(b),b));
+let $values1 = 'start,','end',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # INSTR()
+let $cols = a varchar(10), b varchar(10), c int as (instr(a,b));
+let $values1 = 'foobarbar,','bar',default;
+let $values2 = 'xbar,','foobar',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LCASE()
+let $cols = a varchar(10), b varchar(10) as (lcase(a));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LEFT()
+let $cols = a varchar(10), b varchar(5) as (left(a,5));
+let $values1 = 'foobarbar',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LENGTH()
+let $cols = a varchar(10), b int as (length(a));
+let $values1 = 'text',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LIKE
+let $cols = a varchar(10), b bool as (a like 'H%o');
+let $values1 = 'Hello',default;
+let $values2 = 'MySQL',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LOCATE()
+let $cols = a varchar(10), b varchar(10) as (locate('bar',a));
+let $values1 = 'foobarbar',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LOWER()
+let $cols = a varchar(10), b varchar(10) as (lower(a));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LPAD()
+let $cols = a varchar(10), b varchar(10) as (lpad(a,4,' '));
+let $values1 = 'MySQL',default;
+let $values2 = 'M',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LTRIM()
+let $cols = a varchar(10), b varchar(10) as (ltrim(a));
+let $values1 = '  MySQL',default;
+let $values2 = 'MySQL',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MAKE_SET()
+let $cols = a varchar(10), b varchar(10), c int, d varchar(30) as (make_set(c,a,b));
+let $values1 = 'a','b',1,default;
+let $values2 = 'a','b',3,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MID()
+let $cols = a varchar(10), b varchar(10) as (mid(a,1,2));
+let $values1 = 'foobarbar',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # NOT LIKE
+let $cols = a varchar(10), b bool as (a not like 'H%o');
+let $values1 = 'Hello',default;
+let $values2 = 'MySQL',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # NOT REGEXP
+let $cols = a varchar(10), b bool as (a not regexp 'H.+o');
+let $values1 = 'Hello',default;
+let $values2 = 'hello',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # OCTET_LENGTH()
+let $cols = a varchar(10), b int as (octet_length(a));
+let $values1 = 'text',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ORD()
+let $cols = a varchar(10), b long as (ord(a));
+let $values1 = '2',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # POSITION()
+let $cols = a varchar(10), b varchar(10) as (position('bar' in a));
+let $values1 = 'foobarbar',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # QUOTE()
+let $cols = a varchar(10), b varchar(10) as (quote(a));
+let $values1 = 'Don\'t',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # REGEXP()
+let $cols = a varchar(10), b bool as (a regexp 'H.+o');
+let $values1 = 'Hello',default;
+let $values2 = 'hello',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # REPEAT()
+let $cols = a varchar(10), b varchar(30) as (repeat(a,3));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # REPLACE()
+let $cols = a varchar(10), b varchar(30) as (replace(a,'aa','bb'));
+let $values1 = 'maa',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # REVERSE()
+let $cols = a varchar(10), b varchar(30) as (reverse(a));
+let $values1 = 'maa',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # RIGHT()
+let $cols = a varchar(10), b varchar(10) as (right(a,4));
+let $values1 = 'foobarbar',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # RLIKE()
+let $cols = a varchar(10), b bool as (a rlike 'H.+o');
+let $values1 = 'Hello',default;
+let $values2 = 'MySQL',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # RPAD()
+let $cols = a varchar(10), b varchar(10) as (rpad(a,4,'??'));
+let $values1 = 'He',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # RTRIM();
+let $cols = a varchar(10), b varchar(10) as (rtrim(a));
+let $values1 = 'Hello  ',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SOUNDEX()
+let $cols = a varchar(10), b varchar(20) as (soundex(a));
+let $values1 = 'Hello',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SOUNDS LIKE
+let $cols = a varchar(10), b varchar(10), c bool as (a sounds like b);
+let $values1 = 'Hello','Hello',default;
+let $values2 = 'Hello','MySQL',default;
+let $values3 = 'Hello','hello',default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SPACE()
+let $cols = a varchar(5), b varchar(10) as (concat(a,space(5)));
+let $values1 = 'Hello', default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # STRCMP()
+let $cols = a varchar(9), b varchar(9), c tinyint(1) as (strcmp(a,b));
+let $values1 = 'Hello','Hello', default;
+let $values2 = 'Hello','Hello1', default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SUBSTR()
+let $cols = a varchar(5), b varchar(10) as (substr(a,2));
+let $values1 = 'Hello',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SUBSTRING_INDEX()
+let $cols = a varchar(15), b varchar(10) as (substring_index(a,'.',2));
+let $values1 = 'www.mysql.com',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SUBSTRING()
+let $cols = a varchar(5), b varchar(10) as (substring(a from 2 for 2));
+let $values1 = 'Hello',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TRIM()
+let $cols = a varchar(15), b varchar(10) as (trim(a));
+let $values1 = ' aa ',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # UCASE()
+let $cols = a varchar(5), b varchar(10) as (ucase(a));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # UNHEX()
+let $cols = a varchar(15), b varchar(10) as (unhex(a));
+let $values1 = '4D7953514C',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # UPPER()
+let $cols = a varchar(5), b varchar(10) as (upper(a));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo #
+--echo # CONTROL FLOW FUNCTIONS
+--echo #
+
+--echo # CASE
+let $cols = a varchar(10), b varchar(16) as (case a when NULL then 'asd' when 'b' then 'B' else a end);
+let $values1 = NULL,default;
+let $values2 = 'b',default;
+let $values3 = 'c',default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # IF
+let $cols = a int, b int, c int as (if(a=1,a,b));
+let $values1 = 1,2,default;
+let $values2 = 3,4,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # IFNULL
+let $cols = a varchar(10), b varchar(10), c varchar(10) as (ifnull(a,'DEFAULT'));
+let $values1 = NULL,'adf',default;
+let $values2 = 'a','adf',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # NULLIF
+let $cols = a varchar(10), b varchar(10) as (nullif(a,'DEFAULT'));
+let $values1 = 'DEFAULT',default;
+let $values2 = 'a',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo #
+--echo # OPERATORS
+--echo #
+
+--echo # AND, && 
+let $cols = a int, b bool as (a>0 && a<2);
+let $values1 = -1,default;
+let $values2 = 1,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # BETWEEN ... AND ... 
+let $cols = a int, b bool as (a between 0 and 2);
+let $values1 = -1,default;
+let $values2 = 1,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # BINARY
+let $cols = a varchar(10), b varbinary(10) as (binary a);
+let $values1 = '11',default;
+let $values2 = 1,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # &
+let $cols = a int, b int as (a & 5);
+let $values1 = 1,default;
+let $values2 = 0,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ~
+let $cols = a int, b int as (~a);
+let $values1 = 1,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # |
+let $cols = a int, b int as (a | 5);
+let $values1 = 1,default;
+let $values2 = 0,default;
+let $values3 = 2,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ^
+let $cols = a int, b int as (a ^ 5);
+let $values1 = 1,default;
+let $values2 = 0,default;
+let $values3 = 2,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DIV
+let $cols = a int, b int as (a div 5);
+let $values1 = 1,default;
+let $values2 = 7,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # <=>
+let $cols = a int, b int, c bool as (a <=> b);
+let $values1 = 1,1,default;
+let $values2 = NULL,NULL,default;
+let $values3 = 1,NULL,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # =
+let $cols = a varchar(10), b varchar(10), c bool as (a=b);
+let $values1 = 'a','b',default;
+let $values2 = 'a','a',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # >=
+let $cols = a varchar(10), b varchar(10), c bool as (a >= b);
+let $values1 = 'a','b',default;
+let $values2 = 'a','a',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # >
+let $cols = a varchar(10), b varchar(10), c bool as (a > b);
+let $values1 = 'a','b',default;
+let $values2 = 'a','a',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # IS NOT NULL
+let $cols = a int, b bool as (a is not null);
+let $values1 = 1,default;
+let $values2 = NULL,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # IS NULL
+let $cols = a int, b bool as (a is null);
+let $values1 = 1,default;
+let $values2 = NULL,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # <<
+let $cols = a int, b int as (a << 2);
+let $values1 = 1,default;
+let $values2 = 3,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # <=
+let $cols = a varchar(10), b varchar(10), c bool as (a <= b);
+let $values1 = 'b','a',default;
+let $values2 = 'b','b',default;
+let $values3 = 'b','c',default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # <
+let $cols = a varchar(10), b varchar(10), c bool as (a < b);
+let $values1 = 'b','a',default;
+let $values2 = 'b','b',default;
+let $values3 = 'b','c',default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # NOT BETWEEN ... AND ...
+let $cols = a int, b bool as (a not between 0 and 2);
+let $values1 = -1,default;
+let $values2 = 1,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # <>
+let $cols = a varchar(10), b varchar(10), c bool as (a <> b);
+let $values1 = 'b','a',default;
+let $values2 = 'b','b',default;
+let $values3 = 'b','c',default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # !=
+let $cols = a varchar(10), b varchar(10), c bool as (a != b);
+let $values1 = 'b','a',default;
+let $values2 = 'b','b',default;
+let $values3 = 'b','c',default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ||, OR
+let $cols = a int, b int as (a>5 || a<3);
+let $values1 = 1,default;
+let $values2 = 4,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # >>
+let $cols = a int, b int as (a >> 2);
+let $values1 = 8,default;
+let $values2 = 3,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # XOR
+let $cols = a int, b int as (a xor 5);
+let $values1 = 0,default;
+let $values2 = 1,default;
+let $values3 = 2,default;
+let $rows = 3;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo #
+--echo # DATE AND TIME FUNCTIONS
+--echo #
+
+--echo # ADDDATE()
+let $cols = a datetime, b datetime as (adddate(a,interval 1 month));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ADDTIME()
+let $cols = a datetime, b datetime as (addtime(a,'02:00:00'));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CONVERT_TZ()
+let $cols = a datetime, b datetime as (convert_tz(a,'MET','UTC'));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DATE_ADD()
+let $cols = a datetime, b datetime as (date_add(a,interval 1 month));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DATE_FORMAT()
+let $cols = a datetime, b varchar(64) as (date_format(a,'%W %M %D'));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DATE_SUB()
+let $cols = a datetime, b datetime as (date_sub(a,interval 1 month));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DATE()
+let $cols = a datetime, b datetime as (date(a));
+let $values1 = '2008-08-31 02:00:00',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DATEDIFF()
+let $cols = a datetime, b long as (datediff(a,'2000-01-01'));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DAY()
+let $cols = a datetime, b int as (day(a));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DAYNAME()
+let $cols = a datetime, b varchar(10) as (dayname(a));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DAYOFMONTH()
+let $cols = a datetime, b int as (dayofmonth(a));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DAYOFWEEK()
+let $cols = a datetime, b int as (dayofweek(a));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DAYOFYEAR()
+let $cols = a datetime, b int as (dayofyear(a));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # EXTRACT
+let $cols = a datetime, b int as (extract(year from a));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # FROM_DAYS()
+let $cols = a long, b datetime as (from_days(a));
+let $values1 = 730669,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # FROM_UNIXTIME()
+let $cols = a long, b datetime as (from_unixtime(a));
+let $values1 = 1196440219,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # GET_FORMAT()
+let $cols = a datetime, b varchar(32) as (date_format(a,get_format(DATE,'EUR')));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # HOUR()
+let $cols = a time, b long as (hour(a));
+let $values1 = '10:05:03',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # LAST_DAY()
+let $cols = a datetime, b datetime as (last_day(a));
+let $values1 = '2003-02-05',default;
+let $values2 = '2003-02-32',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MAKEDATE()
+let $cols = a int, b datetime as (makedate(a,1));
+let $values1 = 2001,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MAKETIME()
+let $cols = a int, b time as (maketime(a,1,3));
+let $values1 = 12,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MICROSECOND()
+let $cols = a datetime, b long as (microsecond(a));
+let $values1 = '2009-12-31 12:00:00.123456',default;
+let $values2 = '2009-12-31 23:59:59.000010',default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MINUTE()
+let $cols = a datetime, b int as (minute(a));
+let $values1 = '2009-12-31 23:59:59.000010',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MONTH()
+let $cols = a datetime, b int as (month(a));
+let $values1 = '2009-12-31 23:59:59.000010',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MONTHNAME()
+let $cols = a datetime, b varchar(16) as (monthname(a));
+let $values1 = '2009-12-31 23:59:59.000010',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # PERIOD_ADD()
+let $cols = a int, b int as (period_add(a,2));
+let $values1 = 200801,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # PERIOD_DIFF()
+let $cols = a int, b int, c int as (period_diff(a,b));
+let $values1 = 200802,200703,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # QUARTER()
+let $cols = a datetime, b int as (quarter(a));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SEC_TO_TIME()
+let $cols = a long, b time as (sec_to_time(a));
+let $values1 = 2378,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SECOND()
+let $cols = a datetime, b int as (second(a));
+let $values1 = '10:05:03',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # STR_TO_DATE()
+let $cols = a varchar(64), b datetime as (str_to_date(a,'%m/%d/%Y'));
+let $values1 = '04/30/2004',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SUBDATE()
+let $cols = a datetime, b datetime as (subdate(a,interval 1 month));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SUBTIME()
+let $cols = a datetime, b datetime as (subtime(a,'02:00:00'));
+let $values1 = '2008-08-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIME_FORMAT()
+let $cols = a datetime, b varchar(32) as (time_format(a,'%r'));
+let $values1 = '2008-08-31 02:03:04',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIME_TO_SEC()
+let $cols = a time, b long as (time_to_sec(a));
+let $values1 = '22:23:00',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIME()
+let $cols = a datetime, b time as (time(a));
+let $values1 = '2008-08-31 02:03:04',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIMEDIFF()
+let $cols = a datetime, b datetime, c long as (timediff(a,b));
+let $values1 = '2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIMESTAMP()
+let $cols = a datetime, b timestamp as (timestamp(a));
+let $values1 = '2008-12-31',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIMESTAMPADD()
+let $cols = a datetime, b timestamp as (timestampadd(minute,1,a));
+let $values1 = '2003-01-02',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIMESTAMPDIFF()
+let $cols = a timestamp, b timestamp, c long as (timestampdiff(MONTH, a,b));
+let $values1 = '2003-02-01','2003-05-01',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TO_DAYS()
+let $cols = a datetime, b long as (to_days(a));
+let $values1 = '2007-10-07',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # WEEK()
+let $cols = a datetime, b int as (week(a));
+let $values1 = '2008-09-01',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # WEEKDAY()
+let $cols = a datetime, b int as (weekday(a));
+let $values1 = '2008-09-01',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # WEEKOFYEAR()
+let $cols = a datetime, b int as (weekofyear(a));
+let $values1 = '2008-09-01',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # YEAR()
+let $cols = a datetime, b int as (year(a));
+let $values1 = '2008-09-01',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # YEARWEEK()
+let $cols = a datetime, b int as (yearweek(a));
+let $values1 = '2008-09-01',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo #
+--echo # FULL TEXT SEARCH FUNCTIONS
+--echo #
+--echo # None.
+
+--echo #
+--echo # CAST FUNCTIONS AND OPERATORS
+--echo #
+
+--echo # CAST()
+let $cols = a int, b long as (cast(a as unsigned));
+let $values1 = 1,default;
+let $values2 = -1,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # Convert()
+let $cols = a int, b long as (convert(a,unsigned));
+let $values1 = 1,default;
+let $values2 = -1,default;
+let $rows = 2;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo #
+--echo # XML FUNCTIONS
+--echo #
+--echo # None.
+
+
+--echo #
+--echo # OTHER FUNCTIONS
+--echo #
+
+--echo # AES_DECRYPT(), AES_ENCRYPT()
+let $cols = a varchar(1024), b varchar(1024) as (aes_encrypt(aes_decrypt(a,'adf'),'adf'));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # BIT_COUNT()
+let $cols = a int, b int as (bit_count(a));
+let $values1 = 5,default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CHARSET()
+let $cols = a varchar(1024), b varchar(1024) as (charset(a));
+let $values1 = 'abc',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # COERCIBILITY()
+let $cols = a varchar(1024), b int as (coercibility(a));
+let $values1 = 'abc',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # COLLATION()
+let $cols = a varchar(1024), b varchar(1024) as (collation(a));
+let $values1 = 'abc',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # COMPRESS(), UNCOMPRESS()
+let $cols = a varchar(1024), b varchar(1024) as (uncompress(compress(a)));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # ENCODE(), DECODE()
+let $cols = a varchar(1024), b varchar(1024) as (decode(encode(a,'abc'),'abc'));
+let $values1 = 'MySQL',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DEFAULT()
+let $cols = a varchar(1024) default 'aaa', b varchar(1024) as (ifnull(a,default(a)));
+let $values1 = 'any value',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+#--echo # DES_ENCRYPT(), DES_DECRYPT()
+#--source include/have_ssl.inc
+#let $cols = a varchar(1024), b varchar(1024) as (des_encrypt(des_decrypt(a,'adf'),'adf'));
+#let $values1 = 'MySQL',default;
+#let $rows = 1;
+#--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # INET_ATON(), INET_NTOA()
+let $cols = a varchar(1024), b varchar(1024) as (inet_ntoa(inet_aton(a)));
+let $values1 = '127.0.0.1',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # MD5()
+let $cols = a varchar(1024), b varbinary(32) as (md5(a));
+let $values1 = 'testing',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # OLD_PASSWORD()
+let $cols = a varchar(1024), b varchar(1024) as (old_password(a));
+let $values1 = 'badpwd',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # PASSWORD()
+let $cols = a varchar(1024), b varchar(1024) as (password(a));
+let $values1 = 'badpwd',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SHA1()
+let $cols = a varchar(1024), b varchar(1024) as (sha1(a));
+let $values1 = 'abc',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # SHA()
+let $cols = a varchar(1024), b varchar(1024) as (sha(a));
+let $values1 = 'abc',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # UNCOMPRESSED_LENGTH()
+let $cols = a char, b varchar(1024) as (uncompressed_length(compress(repeat(a,30))));
+let $values1 = 'a',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+

=== added file 'mysql-test/suite/vcol/inc/vcol_trigger_sp.inc'
--- a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,110 @@
+################################################################################
+# inc/vcol_trigger_sp.inc                                                      #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing triggers, stored procedures and functions                           #
+#  defined on tables with virtual columns.                                     #
+#                                                                              #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+create table t1 (a int, 
+                 b int as (a/10),
+		 c int as (a/10) persistent);
+
+create table t2 (a timestamp);
+
+delimiter |;
+
+create trigger trg1 before insert on t1 for each row
+begin
+  if (new.b < 10) then
+    set new.a:= 100;
+    set new.b:= 9;
+    set new.c:= 9;
+  end if;
+
+  if (new.c > 50) then
+    set new.a:= 500; 
+  end if;
+end|
+
+create trigger trg2 after insert on t1 for each row
+begin
+  if (new.b >= 60) then
+    insert into t2 values (now()); 
+  end if;
+end|
+
+create function f1()
+returns int
+begin
+  declare sum1 int default '0';
+  declare cur1 cursor for select sum(b) from t1;
+  open cur1;
+  fetch cur1 into sum1;
+  close cur1;
+  return sum1;
+end|
+
+delimiter ;|
+
+set sql_warnings = 1;
+
+insert into t1 (a) values (200);
+select * from t1;
+select * from t2;
+
+insert into t1 (a) values (10);
+select * from t1;
+select * from t2;
+
+insert into t1 (a) values (600);
+select * from t1;
+--replace_column 1 <timestamp>
+select * from t2;
+
+select f1();
+
+set sql_warnings = 0;
+
+drop trigger trg1;
+drop trigger trg2;
+drop table t2;
+
+delimiter |;
+
+create procedure p1()
+begin
+  declare i int default '0';
+  create table t2 like t1;
+  insert into t2 (a) values (100), (200);
+  begin
+    declare cur1 cursor for select sum(c) from t2;
+    open cur1;
+    fetch cur1 into i;
+    close cur1;
+    if (i=30) then
+      insert into t1 values (300,default,default);
+    end if;
+  end;
+end|
+
+delimiter ;|
+
+delete from t1;
+
+call p1();
+
+select * from t2;
+select * from t1;
+
+drop table t1,t2;
+drop procedure p1;

=== added file 'mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc'
--- a/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,21 @@
+################################################################################
+# inc/vcol_unsupported_storage_engines.inc                                     #
+#                                                                              #
+# Purpose:                                                                     #
+#  Ensure that defining a virtual column for an unsupported table type         #
+#  results in a graceful error.                                                #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a+1));
+create table t1 (a int);
+--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+alter table t1 add column b int as (a+1);
+drop table t1;

=== added file 'mysql-test/suite/vcol/inc/vcol_view.inc'
--- a/mysql-test/suite/vcol/inc/vcol_view.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/inc/vcol_view.inc	2009-10-16 22:57:48 +0000
@@ -0,0 +1,201 @@
+################################################################################
+# inc/vcol_view.inc                                                            #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing views defined on tables with virtual columns.                       #
+#                                                                              #
+#                                                                              #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+
+
+create table t1 (a int not null,
+                 b int as (-a), 
+		 c int as (-a) persistent);
+insert into t1 (a) values (1), (1), (2), (2), (3);
+
+# simple view
+create view v1 (d,e) as select abs(b), abs(c) from t1;
+select d,e from v1;
+select is_updatable from information_schema.views where table_name='v1';
+
+# view with different algorithms (explain output differs)
+explain extended select d,e from v1;
+create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1;
+show create view v2;
+select d,e from v2;
+explain extended select d,e from v2;
+
+# VIEW on VIEW test
+create view v3 (d,e) as select d*2, e*2 from v1;
+select * from v3;
+explain extended select * from v3;
+
+drop view v1,v2,v3;
+drop table t1;
+
+#
+# DISTINCT option for VIEW
+#
+create table t1 (a int not null,
+                 b int as (-a), 
+		 c int as (-a) persistent);
+insert into t1 (a) values (1), (2), (3), (1), (2), (3);
+create view v1 as select distinct b from t1;
+select * from v1;
+explain select * from v1;
+select * from t1;
+drop view v1;
+create view v1 as select distinct c from t1;
+select * from v1;
+explain select * from v1;
+select * from t1;
+drop view v1;
+drop table t1;
+
+#
+# LIMIT clause test
+#
+create table t1 (a int not null,
+                 b int as (-a), 
+		 c int as (-a) persistent);
+insert into t1 (a) values (1), (2), (3), (4);
+create view v1 as select b+1 from t1 order by 1 desc limit 2;
+select * from v1;
+explain select * from v1;
+drop view v1;
+create view v1 as select c+1 from t1 order by 1 desc limit 2;
+select * from v1;
+explain select * from v1;
+drop view v1;
+drop table t1;
+
+#
+# simple view + simple update, insert and delete
+#
+create table t1 (a int,
+                 b int,
+		 c int as (-a),
+		 d int as (-a) persistent,
+                 primary key(a));
+insert into t1 (a,b) values (10,2), (20,3), (30,4), (40,5), (50,10);
+create view v1 (a,e,f,g) as select a, b+1,c+1,d+1 from t1;
+# updatable field of updateable view
+update v1 set a=a+e;
+select * from v1;
+select * from t1;
+delete from v1;
+select * from v1;
+select * from t1;
+--error ER_NON_INSERTABLE_TABLE
+insert into v1 (a,e) values (60,15);
+drop table t1;
+drop view v1;
+
+#
+# outer join based on VIEW with WHERE clause
+#
+create table t1 (a int, 
+		 b int as (-a),
+		 c int as (-a) persistent,
+                 primary key(a));
+insert into t1 (a) values (1), (2), (3);
+create view v1 (x,y,z) as select a,b,c from t1 where b < -1;
+select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.b= v1.y);
+drop view v1;
+create view v1 (x,y,z) as select a,b,c from t1 where c < -1;
+select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.c= v1.z);
+drop view v1;
+drop table t1;
+
+#
+# VIEW built over UNION
+#
+create table t1 (a1 int,
+                 b1 int as (-a1),
+		 c1 int as (-a1) persistent);
+create table t2 (a2 int,
+                 b2 int as (-a2),
+		 c2 int as (-a2) persistent);
+insert into t1 (a1) values (1), (2);
+insert into t2 (a2) values (2), (3);
+create view v1 as select * from t1,t2 union all select * from t1,t2;
+select * from v1;
+drop view v1;
+drop table t1, t2;
+
+#
+# Showing VIEW with VIEWs in subquery
+#
+create table t1 (a int,
+                 b int as (-a),
+		 c int as (-a) persistent);
+create table t2 like t1;
+create view v1 as select a,b,c from t1;
+create view v2 as select a,b,c from t2 where b in (select b from v1);
+show create view v2;
+drop view v2, v1;
+drop table t1, t2;
+
+#
+# TODO: VIEW with full text
+#
+#CREATE TABLE t1 (c1 int not null auto_increment primary key, c2 varchar(20), fulltext(c2));
+#insert into t1 (c2) VALUES ('real Beer'),('Water'),('Kossu'),('Coca-Cola'),('Vodka'),('Wine'),('almost real Beer');
+#select * from t1 WHERE match (c2) against ('Beer');
+#CREATE VIEW v1 AS SELECT  * from t1 WHERE match (c2) against ('Beer');
+#select * from v1;
+#drop view v1;
+#drop table t1;
+
+#
+# distinct in temporary table with a VIEW
+#
+create table t1 (a int,
+                 b int as (-a),
+		 c int as (-a) persistent);
+insert into t1 (a) values (1),(1),(2),(2),(3),(3);
+create view v1 as select b from t1;
+select distinct b from v1;
+select distinct b from v1 limit 2;
+select distinct b from t1 limit 2;
+prepare stmt1 from "select distinct b from v1 limit 2";
+execute stmt1;
+execute stmt1;
+deallocate prepare stmt1;
+drop view v1;
+create view v1 as select c from t1;
+select distinct c from v1;
+select distinct c from v1 limit 2;
+select distinct c from t1 limit 2;
+prepare stmt1 from "select distinct c from v1 limit 2";
+execute stmt1;
+execute stmt1;
+deallocate prepare stmt1;
+drop view v1;
+drop table t1;
+
+#
+# WITH CHECK OPTION insert/update test
+#
+create table t1 (a int,
+                 b int as (-a),
+		 c int as (-a) persistent);
+create view v1 as select * from t1 where b > -2 && c >-2 with check option;
+# simple insert
+insert into v1 (a) values (1);
+-- error 1369
+insert into v1 (a) values (3);
+# simple insert with ignore
+insert ignore into v1 (a) values (2),(3),(0);
+select * from t1;
+drop view v1;
+drop table t1;
+

=== added directory 'mysql-test/suite/vcol/r'
=== added file 'mysql-test/suite/vcol/r/rpl_vcol.result'
--- a/mysql-test/suite/vcol/r/rpl_vcol.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/rpl_vcol.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,25 @@
+SET @@session.storage_engine = 'InnoDB';
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int, b int as (a+1));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a+1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	2
+2	3
+select * from t1;
+a	b
+1	2
+2	3
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_archive.result'
--- a/mysql-test/suite/vcol/r/vcol_archive.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_archive.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,7 @@
+SET @@session.storage_engine = 'archive';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+create table t1 (a int);
+alter table t1 add column b int as (a+1);
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_blackhole.result'
--- a/mysql-test/suite/vcol/r/vcol_blackhole.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_blackhole.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,7 @@
+SET @@session.storage_engine = 'blackhole';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+create table t1 (a int);
+alter table t1 add column b int as (a+1);
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,243 @@
+SET @@session.storage_engine = 'InnoDB';
+# RAND()
+create table t1 (b double as (rand()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# LOAD_FILE()
+create table t1 (a varchar(64), b varchar(1024) as (load_file(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# CURDATE()
+create table t1 (a datetime as (curdate()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_DATE(), CURRENT_DATE
+create table t1 (a datetime as (current_date));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a datetime as (current_date()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_TIME(), CURRENT_TIME
+create table t1 (a datetime as (current_time));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a datetime as (current_time()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP
+create table t1 (a datetime as (current_timestamp()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a datetime as (current_timestamp));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURTIME()
+create table t1 (a datetime as (curtime()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# LOCALTIME(), LOCALTIME
+create table t1 (a datetime, b varchar(10) as (localtime()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+create table t1 (a datetime, b varchar(10) as (localtime));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6)
+create table t1 (a datetime, b varchar(10) as (localtimestamp()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+create table t1 (a datetime, b varchar(10) as (localtimestamp));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# NOW()
+create table t1 (a datetime, b varchar(10) as (now()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# SYSDATE()
+create table t1 (a int, b varchar(10) as (sysdate()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UNIX_TIMESTAMP()
+create table t1 (a datetime, b datetime as (unix_timestamp()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UTC_DATE()
+create table t1 (a datetime, b datetime as (utc_date()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UTC_TIME()
+create table t1 (a datetime, b datetime as (utc_time()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UTC_TIMESTAMP()
+create table t1 (a datetime, b datetime as (utc_timestamp()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# MATCH()
+# BENCHMARK()
+create table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# CONNECTION_ID()
+create table t1 (a int as (connection_id()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_USER(), CURRENT_USER
+create table t1 (a varchar(32) as (current_user()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a varchar(32) as (current_user));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# DATABASE()
+create table t1 (a varchar(1024), b varchar(1024) as (database()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# FOUND_ROWS()
+create table t1 (a varchar(1024), b varchar(1024) as (found_rows()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# GET_LOCK()
+create table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# IS_FREE_LOCK()
+create table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# IS_USED_LOCK()
+create table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# LAST_INSERT_ID()
+create table t1 (a int as (last_insert_id()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# MASTER_POS_WAIT()
+create table t1 (a varchar(32), b int as (master_pos_wait(a,0,2)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# NAME_CONST()
+create table t1 (a varchar(32) as (name_const('test',1)));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# RELEASE_LOCK()
+create table t1 (a varchar(32), b int as (release_lock(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# ROW_COUNT()
+create table t1 (a int as (row_count()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# SCHEMA()
+create table t1 (a varchar(32) as (schema()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# SESSION_USER()
+create table t1 (a varchar(32) as (session_user()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# SLEEP()
+create table t1 (a int, b int as (sleep(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# SYSTEM_USER()
+create table t1 (a varchar(32) as (system_user()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# USER()
+create table t1 (a varchar(1024), b varchar(1024) as (user()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UUID_SHORT()
+create table t1 (a varchar(1024) as (uuid_short()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# UUID()
+create table t1 (a varchar(1024) as (uuid()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# VALUES()
+create table t1 (a varchar(1024), b varchar(1024) as (values(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VERSION()
+create table t1 (a varchar(1024), b varchar(1024) as (version()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# ENCRYPT()
+create table t1 (a varchar(1024), b varchar(1024) as (encrypt(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# Stored procedures
+create procedure p1()
+begin
+select current_user();
+end //
+create function f1()
+returns int
+begin
+return 1;
+end //
+create table t1 (a int as (p1()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a int as (f1()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+drop procedure p1;
+drop function f1;
+# Unknown functions
+create table t1 (a int as (f1()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+#
+# GROUP BY FUNCTIONS
+#
+# AVG()
+create table t1 (a int, b int as (avg(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# BIT_AND()
+create table t1 (a int, b int as (bit_and(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# BIT_OR()
+create table t1 (a int, b int as (bit_or(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# BIT_XOR()
+create table t1 (a int, b int as (bit_xor(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# COUNT(DISTINCT)
+create table t1 (a int, b int as (count(distinct a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# COUNT()
+create table t1 (a int, b int as (count(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# GROUP_CONCAT()
+create table t1 (a varchar(32), b int as (group_concat(a,'')));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# MAX()
+create table t1 (a int, b int as (max(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# MIN()
+create table t1 (a int, b int as (min(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STD()
+create table t1 (a int, b int as (std(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STDDEV_POP()
+create table t1 (a int, b int as (stddev_pop(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STDDEV_SAMP()
+create table t1 (a int, b int as (stddev_samp(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STDDEV()
+create table t1 (a int, b int as (stddev(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# SUM()
+create table t1 (a int, b int as (sum(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VAR_POP()
+create table t1 (a int, b int as (var_pop(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VAR_SAMP()
+create table t1 (a int, b int as (var_samp(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VARIANCE()
+create table t1 (a int, b int as (variance(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+#
+# XML FUNCTIONS
+#
+# ExtractValue()
+create table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]')));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UpdateXML()
+create table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>')));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+#
+# Sub-selects
+#
+create table t1 (a int);
+create table t2 (a int, b int as (select count(*) from t1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select count(*) from t1))' at line 1
+drop table t1;
+create table t1 (a int, b int as ((select 1)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+create table t1 (a int, b int as (a+(select 1)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+#
+# SP functions
+#
+drop function if exists sub1;
+create function sub1(i int) returns int deterministic
+return i+1;
+select sub1(1);
+sub1(1)
+2
+create table t1 (a int, b int as (a+sub3(1)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+drop function sub1;
+#
+# Long expression
+create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')));
+drop table t1;
+create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')));
+ERROR HY000: String 'concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long for VIRTUAL COLUMN EXPRESSION (should be no longer than 252)
+#
+# Constant expression
+create table t1 (a int as (PI()));
+ERROR HY000: Constant expression in computed column function is not allowed.

=== added file 'mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,245 @@
+SET @@session.storage_engine = 'MyISAM';
+# RAND()
+create table t1 (b double as (rand()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# LOAD_FILE()
+create table t1 (a varchar(64), b varchar(1024) as (load_file(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# CURDATE()
+create table t1 (a datetime as (curdate()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_DATE(), CURRENT_DATE
+create table t1 (a datetime as (current_date));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a datetime as (current_date()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_TIME(), CURRENT_TIME
+create table t1 (a datetime as (current_time));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a datetime as (current_time()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP
+create table t1 (a datetime as (current_timestamp()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a datetime as (current_timestamp));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURTIME()
+create table t1 (a datetime as (curtime()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# LOCALTIME(), LOCALTIME
+create table t1 (a datetime, b varchar(10) as (localtime()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+create table t1 (a datetime, b varchar(10) as (localtime));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6)
+create table t1 (a datetime, b varchar(10) as (localtimestamp()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+create table t1 (a datetime, b varchar(10) as (localtimestamp));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# NOW()
+create table t1 (a datetime, b varchar(10) as (now()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# SYSDATE()
+create table t1 (a int, b varchar(10) as (sysdate()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UNIX_TIMESTAMP()
+create table t1 (a datetime, b datetime as (unix_timestamp()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UTC_DATE()
+create table t1 (a datetime, b datetime as (utc_date()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UTC_TIME()
+create table t1 (a datetime, b datetime as (utc_time()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UTC_TIMESTAMP()
+create table t1 (a datetime, b datetime as (utc_timestamp()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# MATCH()
+create table t1 (a varchar(32), b bool as (match a against ('sample text')));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# BENCHMARK()
+create table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# CONNECTION_ID()
+create table t1 (a int as (connection_id()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# CURRENT_USER(), CURRENT_USER
+create table t1 (a varchar(32) as (current_user()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a varchar(32) as (current_user));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# DATABASE()
+create table t1 (a varchar(1024), b varchar(1024) as (database()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# FOUND_ROWS()
+create table t1 (a varchar(1024), b varchar(1024) as (found_rows()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# GET_LOCK()
+create table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# IS_FREE_LOCK()
+create table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# IS_USED_LOCK()
+create table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# LAST_INSERT_ID()
+create table t1 (a int as (last_insert_id()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# MASTER_POS_WAIT()
+create table t1 (a varchar(32), b int as (master_pos_wait(a,0,2)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# NAME_CONST()
+create table t1 (a varchar(32) as (name_const('test',1)));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# RELEASE_LOCK()
+create table t1 (a varchar(32), b int as (release_lock(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# ROW_COUNT()
+create table t1 (a int as (row_count()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# SCHEMA()
+create table t1 (a varchar(32) as (schema()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# SESSION_USER()
+create table t1 (a varchar(32) as (session_user()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# SLEEP()
+create table t1 (a int, b int as (sleep(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# SYSTEM_USER()
+create table t1 (a varchar(32) as (system_user()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# USER()
+create table t1 (a varchar(1024), b varchar(1024) as (user()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UUID_SHORT()
+create table t1 (a varchar(1024) as (uuid_short()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# UUID()
+create table t1 (a varchar(1024) as (uuid()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+# VALUES()
+create table t1 (a varchar(1024), b varchar(1024) as (values(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VERSION()
+create table t1 (a varchar(1024), b varchar(1024) as (version()));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# ENCRYPT()
+create table t1 (a varchar(1024), b varchar(1024) as (encrypt(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# Stored procedures
+create procedure p1()
+begin
+select current_user();
+end //
+create function f1()
+returns int
+begin
+return 1;
+end //
+create table t1 (a int as (p1()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+create table t1 (a int as (f1()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+drop procedure p1;
+drop function f1;
+# Unknown functions
+create table t1 (a int as (f1()));
+ERROR HY000: Function or expression is not allowed for column 'a'.
+#
+# GROUP BY FUNCTIONS
+#
+# AVG()
+create table t1 (a int, b int as (avg(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# BIT_AND()
+create table t1 (a int, b int as (bit_and(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# BIT_OR()
+create table t1 (a int, b int as (bit_or(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# BIT_XOR()
+create table t1 (a int, b int as (bit_xor(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# COUNT(DISTINCT)
+create table t1 (a int, b int as (count(distinct a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# COUNT()
+create table t1 (a int, b int as (count(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# GROUP_CONCAT()
+create table t1 (a varchar(32), b int as (group_concat(a,'')));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# MAX()
+create table t1 (a int, b int as (max(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# MIN()
+create table t1 (a int, b int as (min(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STD()
+create table t1 (a int, b int as (std(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STDDEV_POP()
+create table t1 (a int, b int as (stddev_pop(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STDDEV_SAMP()
+create table t1 (a int, b int as (stddev_samp(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# STDDEV()
+create table t1 (a int, b int as (stddev(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# SUM()
+create table t1 (a int, b int as (sum(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VAR_POP()
+create table t1 (a int, b int as (var_pop(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VAR_SAMP()
+create table t1 (a int, b int as (var_samp(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# VARIANCE()
+create table t1 (a int, b int as (variance(a)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+#
+# XML FUNCTIONS
+#
+# ExtractValue()
+create table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]')));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+# UpdateXML()
+create table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>')));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+#
+# Sub-selects
+#
+create table t1 (a int);
+create table t2 (a int, b int as (select count(*) from t1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select count(*) from t1))' at line 1
+drop table t1;
+create table t1 (a int, b int as ((select 1)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+create table t1 (a int, b int as (a+(select 1)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+#
+# SP functions
+#
+drop function if exists sub1;
+create function sub1(i int) returns int deterministic
+return i+1;
+select sub1(1);
+sub1(1)
+2
+create table t1 (a int, b int as (a+sub3(1)));
+ERROR HY000: Function or expression is not allowed for column 'b'.
+drop function sub1;
+#
+# Long expression
+create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')));
+drop table t1;
+create table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')));
+ERROR HY000: String 'concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long for VIRTUAL COLUMN EXPRESSION (should be no longer than 252)
+#
+# Constant expression
+create table t1 (a int as (PI()));
+ERROR HY000: Constant expression in computed column function is not allowed.

=== added file 'mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,146 @@
+SET @@session.storage_engine = 'InnoDB';
+#
+# Section 1. Wrong column definition options
+#            - NOT NULL
+#            - NULL
+#            - DEFAULT <value>
+#            - AUTO_INCREMENT
+#            - [PRIMARY] KEY
+# NOT NULL
+create table t1 (a int, b int as (a+1) not null);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) not null;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null' at line 1
+drop table t1;
+# NULL  
+create table t1 (a int, b int as (a+1) null);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) null;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null' at line 1
+drop table t1;
+# DEFAULT
+create table t1 (a int, b int as (a+1) default 0);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) default 0;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0' at line 1
+drop table t1;
+# AUTO_INCREMENT
+create table t1 (a int, b int as (a+1) AUTO_INCREMENT);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) AUTO_INCREMENT;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT' at line 1
+drop table t1;
+# [PRIMARY] KEY
+create table t1 (a int, b int as (a+1) key);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key)' at line 1
+create table t1 (a int, b int as (a+1) primary key);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) key;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key' at line 1
+alter table t1 add column b int as (a+1) primary key;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key' at line 1
+drop table t1;
+# Section 2. Other column definition options
+#            - COMMENT
+#            - REFERENCES (only syntax testing here)
+#            - STORED (only systax testing here)
+create table t1 (a int, b int as (a % 2) comment 'my comment');
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) comment 'my comment';
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+insert into t1 (a) values (1);
+select * from t1;
+a	b
+1	1
+insert into t1 values (2,default);
+select a,b from t1;
+a	b
+1	1
+2	0
+create table t2 like t1;
+show create table t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+insert into t2 (a) values (1);
+select * from t2;
+a	b
+1	1
+insert into t2 values (2,default);
+select a,b from t2;
+a	b
+1	1
+2	0
+drop table t2;
+drop table t1;
+create table t1 (a int, b int as (a % 2) persistent);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) PERSISTENT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+insert into t1 (a) values (1);
+select * from t1;
+a	b
+1	1
+insert into t1 values (2,default);
+select a,b from t1;
+a	b
+1	1
+2	0
+drop table t1;
+create table t2 (a int);
+create table t1 (a int, b int as (a % 2) persistent references t2(a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) PERSISTENT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) persistent references t2(a);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'references t2(a)' at line 1
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,146 @@
+SET @@session.storage_engine = 'MyISAM';
+#
+# Section 1. Wrong column definition options
+#            - NOT NULL
+#            - NULL
+#            - DEFAULT <value>
+#            - AUTO_INCREMENT
+#            - [PRIMARY] KEY
+# NOT NULL
+create table t1 (a int, b int as (a+1) not null);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) not null;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'not null' at line 1
+drop table t1;
+# NULL  
+create table t1 (a int, b int as (a+1) null);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) null;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null' at line 1
+drop table t1;
+# DEFAULT
+create table t1 (a int, b int as (a+1) default 0);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) default 0;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default 0' at line 1
+drop table t1;
+# AUTO_INCREMENT
+create table t1 (a int, b int as (a+1) AUTO_INCREMENT);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) AUTO_INCREMENT;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AUTO_INCREMENT' at line 1
+drop table t1;
+# [PRIMARY] KEY
+create table t1 (a int, b int as (a+1) key);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key)' at line 1
+create table t1 (a int, b int as (a+1) primary key);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key)' at line 1
+create table t1 (a int);
+alter table t1 add column b int as (a+1) key;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key' at line 1
+alter table t1 add column b int as (a+1) primary key;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'primary key' at line 1
+drop table t1;
+# Section 2. Other column definition options
+#            - COMMENT
+#            - REFERENCES (only syntax testing here)
+#            - STORED (only systax testing here)
+create table t1 (a int, b int as (a % 2) comment 'my comment');
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) comment 'my comment';
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+insert into t1 (a) values (1);
+select * from t1;
+a	b
+1	1
+insert into t1 values (2,default);
+select a,b from t1;
+a	b
+1	1
+2	0
+create table t2 like t1;
+show create table t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t2;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+insert into t2 (a) values (1);
+select * from t2;
+a	b
+1	1
+insert into t2 values (2,default);
+select a,b from t2;
+a	b
+1	1
+2	0
+drop table t2;
+drop table t1;
+create table t1 (a int, b int as (a % 2) persistent);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) PERSISTENT
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES		NULL	VIRTUAL
+insert into t1 (a) values (1);
+select * from t1;
+a	b
+1	1
+insert into t1 values (2,default);
+select a,b from t1;
+a	b
+1	1
+2	0
+drop table t1;
+create table t2 (a int);
+create table t1 (a int, b int as (a % 2) persistent references t2(a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) PERSISTENT
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) persistent references t2(a);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'references t2(a)' at line 1
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_csv.result'
--- a/mysql-test/suite/vcol/r/vcol_csv.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_csv.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,7 @@
+SET @@session.storage_engine = 'CSV';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+create table t1 (a int not null);
+alter table t1 add column b int as (a+1);
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_handler_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_handler_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_handler_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,76 @@
+SET @@session.storage_engine = 'InnoDB';
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent,
+d char(1),
+index (a),
+index (c));
+insert into t1 (a,d) values (4,'a'), (2,'b'), (1,'c'), (3,'d');
+select * from t1;
+a	b	c	d
+4	-4	-4	a
+2	-2	-2	b
+1	-1	-1	c
+3	-3	-3	d
+# HANDLER tbl_name OPEN
+handler t1 open;
+# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...)
+handler t1 read a > (2);
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE non-vcol_field=expr
+handler t1 read a > (2) where d='c';
+a	b	c	d
+# HANDLER tbl_name READ vcol_index_name = (value1,value2,...)
+handler t1 read c = (-2);
+a	b	c	d
+2	-2	-2	b
+# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) WHERE non-vcol_field=expr
+handler t1 read c = (-2) where d='c';
+a	b	c	d
+# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE vcol_field=expr
+handler t1 read a > (2) where b=-3 && c=-3;
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ vcol_index_name <= (value1,value2,...)
+handler t1 read c <= (-2);
+a	b	c	d
+2	-2	-2	b
+# HANDLER tbl_name READ vcol_index_name > (value1,value2,...) WHERE vcol_field=expr
+handler t1 read c <= (-2) where b=-3;
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ vcol_index_name FIRST
+handler t1 read c first;
+a	b	c	d
+4	-4	-4	a
+# HANDLER tbl_name READ vcol_index_name NEXT
+handler t1 read c next;
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ vcol_index_name PREV
+handler t1 read c prev;
+a	b	c	d
+4	-4	-4	a
+# HANDLER tbl_name READ vcol_index_name LAST
+handler t1 read c last;
+a	b	c	d
+1	-1	-1	c
+# HANDLER tbl_name READ FIRST where non-vcol=expr
+handler t1 read FIRST where a >= 2;
+a	b	c	d
+4	-4	-4	a
+# HANDLER tbl_name READ FIRST where vcol=expr
+handler t1 read FIRST where b >= -2;
+a	b	c	d
+2	-2	-2	b
+# HANDLER tbl_name READ NEXT where non-vcol=expr
+handler t1 read NEXT where d='c';
+a	b	c	d
+1	-1	-1	c
+# HANDLER tbl_name READ NEXT where vcol=expr
+handler t1 read NEXT where b<=-4;
+a	b	c	d
+# HANDLER tbl_name CLOSE
+handler t1 close;
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_handler_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_handler_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_handler_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,76 @@
+SET @@session.storage_engine = 'MyISAM';
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent,
+d char(1),
+index (a),
+index (c));
+insert into t1 (a,d) values (4,'a'), (2,'b'), (1,'c'), (3,'d');
+select * from t1;
+a	b	c	d
+4	-4	-4	a
+2	-2	-2	b
+1	-1	-1	c
+3	-3	-3	d
+# HANDLER tbl_name OPEN
+handler t1 open;
+# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...)
+handler t1 read a > (2);
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE non-vcol_field=expr
+handler t1 read a > (2) where d='c';
+a	b	c	d
+# HANDLER tbl_name READ vcol_index_name = (value1,value2,...)
+handler t1 read c = (-2);
+a	b	c	d
+2	-2	-2	b
+# HANDLER tbl_name READ vcol_index_name = (value1,value2,...) WHERE non-vcol_field=expr
+handler t1 read c = (-2) where d='c';
+a	b	c	d
+# HANDLER tbl_name READ non-vcol_index_name > (value1,value2,...) WHERE vcol_field=expr
+handler t1 read a > (2) where b=-3 && c=-3;
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ vcol_index_name <= (value1,value2,...)
+handler t1 read c <= (-2);
+a	b	c	d
+2	-2	-2	b
+# HANDLER tbl_name READ vcol_index_name > (value1,value2,...) WHERE vcol_field=expr
+handler t1 read c <= (-2) where b=-3;
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ vcol_index_name FIRST
+handler t1 read c first;
+a	b	c	d
+4	-4	-4	a
+# HANDLER tbl_name READ vcol_index_name NEXT
+handler t1 read c next;
+a	b	c	d
+3	-3	-3	d
+# HANDLER tbl_name READ vcol_index_name PREV
+handler t1 read c prev;
+a	b	c	d
+4	-4	-4	a
+# HANDLER tbl_name READ vcol_index_name LAST
+handler t1 read c last;
+a	b	c	d
+1	-1	-1	c
+# HANDLER tbl_name READ FIRST where non-vcol=expr
+handler t1 read FIRST where a >= 2;
+a	b	c	d
+4	-4	-4	a
+# HANDLER tbl_name READ FIRST where vcol=expr
+handler t1 read FIRST where b >= -2;
+a	b	c	d
+2	-2	-2	b
+# HANDLER tbl_name READ NEXT where non-vcol=expr
+handler t1 read NEXT where d='c';
+a	b	c	d
+1	-1	-1	c
+# HANDLER tbl_name READ NEXT where vcol=expr
+handler t1 read NEXT where b<=-4;
+a	b	c	d
+# HANDLER tbl_name CLOSE
+handler t1 close;
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,427 @@
+SET @@session.storage_engine = 'InnoDB';
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent);
+set sql_warnings = 1;
+#
+# *** INSERT ***
+#
+# INSERT INTO tbl_name VALUES... DEFAULT is specified against vcols
+insert into t1 values (1,default,default);
+select * from t1;
+a	b	c
+1	-1	-1
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name VALUES... NULL is specified against vcols
+insert into t1 values (1,null,null);
+select * from t1;
+a	b	c
+1	-1	-1
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols
+insert into t1 values (1,2,3);
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't1' ignored.
+Warning	1645	The value specified for computed column 'c' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<non_vcol_list>) VALUES...
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<normal+vcols>) VALUES... DEFAULT is specified 
+# against vcols
+insert into t1 (a,b) values (1,default), (2,default);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<normal+vcols>) VALUES... NULL is specified against vcols
+insert into t1 (a,b) values (1,null), (2,null);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<normal+vcols>) VALUES... a non-NULL value is specified 
+# against vcols
+insert into t1 (a,b) values (1,3), (2,4);
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't1' ignored.
+Warning	1645	The value specified for computed column 'b' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+drop table t1;
+# Table with UNIQUE non-vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE 
+# KEY UPDATE <non_vcol>=expr, <vcol>=expr
+create table t1 (a int unique, 
+b int as (-a),
+c int as (-a) persistent);
+insert into t1 values (1,default,default);
+insert into t1 values (1,default,default) 
+on duplicate key update a=2, b=default;
+select a,b,c from t1;
+a	b	c
+2	-2	-2
+delete from t1 where b in (1,2);
+select * from t1;
+a	b	c
+2	-2	-2
+drop table t1;
+# Table with UNIQUE vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE 
+# KEY UPDATE <non_vcol>=expr, <vcol>=expr
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent unique);
+insert into t1 values (1,default,default);
+insert into t1 values (1,default,default) 
+on duplicate key update a=2, b=default;
+select a,b,c from t1;
+a	b	c
+2	-2	-2
+# CREATE new_table ... LIKE old_table
+# INSERT INTO new_table SELECT * from old_table
+create table t2 like t1;
+insert into t2 select * from t1;
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't2' ignored.
+Warning	1645	The value specified for computed column 'c' in table 't2' ignored.
+select * from t1;
+a	b	c
+2	-2	-2
+drop table t2;
+# CREATE new_table ... LIKE old_table INSERT INTO new_table (<non-vcols>, <vcols>) 
+# SELECT <non-vcols>, <vcols> from old_table
+insert into t1 values (1,default,default);
+select * from t1;
+a	b	c
+2	-2	-2
+1	-1	-1
+create table t2 like t1;
+insert into t2 (a,b) select a,b from t1;
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't2' ignored.
+Warning	1645	The value specified for computed column 'b' in table 't2' ignored.
+select * from t2;
+a	b	c
+2	-2	-2
+1	-1	-1
+drop table t2;
+drop table t1;
+#
+# *** UPDATE ***
+#
+# UPDATE tbl_name SET non-vcol=expr WHERE non-vcol=expr
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent);
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where a=2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# UPDATE tbl_name SET vcol=expr WHERE non-vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set c=3 where a=2;
+Warnings:
+Warning	1645	The value specified for computed column 'c' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where b=-2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# UPDATE tbl_name SET vcol=expr WHERE vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set c=3 where b=-2;
+Warnings:
+Warning	1645	The value specified for computed column 'c' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+drop table t1;
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=const
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent unique);
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where c=-2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where c between -3 and -2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# No INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where b between -3 and -2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr 
+# WHERE vcol=between const1 and const2 ORDER BY vcol
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+update t1 set a=6 where c between -1 and 0
+order by c;
+select * from t1;
+a	b	c
+6	-6	-6
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1 where c between -6 and 0;
+select * from t1;
+a	b	c
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr 
+# WHERE vcol=between const1 and const2 ORDER BY vcol LIMIT 2
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+update t1 set a=6 where c between -1 and 0
+order by c limit 2;
+select * from t1;
+a	b	c
+6	-6	-6
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1 where c between -2 and 0 order by c;
+select * from t1;
+a	b	c
+6	-6	-6
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1;
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr
+# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+update t1 set a=6 where (c between -2 and 0) and (b=-1);
+select * from t1;
+a	b	c
+6	-6	-6
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1;
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr
+# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3
+# ORDER BY indexed vcol
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+update t1 set a=6 where (c between -2 and 0) and (b=-1) order by c;
+select * from t1;
+a	b	c
+6	-6	-6
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1;
+drop table t1;
+#
+# Verify ON UPDATE/DELETE actions of FOREIGN KEYs
+create table t2 (a int primary key, name varchar(10));
+create table t1 (a int primary key, b int as (a % 10) persistent);
+insert into t2 values (1, 'value1'), (2,'value2'), (3,'value3');
+insert into t1 (a) values (1),(2),(3);
+select * from t1;
+a	b
+1	1
+2	2
+3	3
+select * from t2;
+a	name
+1	value1
+2	value2
+3	value3
+select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+a	b	name
+1	1	value1
+2	2	value2
+3	3	value3
+#  - ON UPDATE RESTRICT
+alter table t1 add foreign key (b) references t2(a) on update restrict;
+insert into t1 (a) values (4);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t2` (`a`))
+update t2 set a=4 where a=3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t2` (`a`))
+select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+a	b	name
+1	1	value1
+2	2	value2
+3	3	value3
+alter table t1 drop foreign key t1_ibfk_1;
+#  - ON DELETE RESTRICT
+alter table t1 add foreign key (b) references t2(a) on delete restrict;
+delete from t2 where a=3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t2` (`a`))
+select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+a	b	name
+1	1	value1
+2	2	value2
+3	3	value3
+select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a);
+a	b	name
+1	1	value1
+2	2	value2
+3	3	value3
+alter table t1 drop foreign key t1_ibfk_1;
+#  - ON DELETE CASCADE
+alter table t1 add foreign key (b) references t2(a) on delete cascade;
+delete from t2 where a=3;
+select t1.a, t1.b, t2.name from t1,t2 where t1.b=t2.a;
+a	b	name
+1	1	value1
+2	2	value2
+select t1.a, t1.b, t2.name from t1 left outer join t2 on (t1.b=t2.a);
+a	b	name
+1	1	value1
+2	2	value2
+alter table t1 drop foreign key t1_ibfk_1;
+drop table t1;
+drop table t2;
+#
+# *** REPLACE ***
+#
+# UNIQUE INDEX on vcol
+# REPLACE tbl_name (non-vcols) VALUES (non-vcols);
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent unique,
+d varchar(16));
+insert into t1 (a,d) values (1,'a'), (2,'b');
+select * from t1;
+a	b	c	d
+1	-1	-1	a
+2	-2	-2	b
+replace t1 (a,d) values (1,'c');
+select * from t1;
+a	b	c	d
+1	-1	-1	c
+2	-2	-2	b
+delete from t1;
+select * from t1;
+a	b	c	d
+set sql_warnings = 0;
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,365 @@
+SET @@session.storage_engine = 'MyISAM';
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent);
+set sql_warnings = 1;
+#
+# *** INSERT ***
+#
+# INSERT INTO tbl_name VALUES... DEFAULT is specified against vcols
+insert into t1 values (1,default,default);
+select * from t1;
+a	b	c
+1	-1	-1
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name VALUES... NULL is specified against vcols
+insert into t1 values (1,null,null);
+select * from t1;
+a	b	c
+1	-1	-1
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols
+insert into t1 values (1,2,3);
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't1' ignored.
+Warning	1645	The value specified for computed column 'c' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<non_vcol_list>) VALUES...
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<normal+vcols>) VALUES... DEFAULT is specified 
+# against vcols
+insert into t1 (a,b) values (1,default), (2,default);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<normal+vcols>) VALUES... NULL is specified against vcols
+insert into t1 (a,b) values (1,null), (2,null);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# INSERT INTO tbl_name (<normal+vcols>) VALUES... a non-NULL value is specified 
+# against vcols
+insert into t1 (a,b) values (1,3), (2,4);
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't1' ignored.
+Warning	1645	The value specified for computed column 'b' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+drop table t1;
+# Table with UNIQUE non-vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE 
+# KEY UPDATE <non_vcol>=expr, <vcol>=expr
+create table t1 (a int unique, 
+b int as (-a),
+c int as (-a) persistent);
+insert into t1 values (1,default,default);
+insert into t1 values (1,default,default) 
+on duplicate key update a=2, b=default;
+select a,b,c from t1;
+a	b	c
+2	-2	-2
+delete from t1 where b in (1,2);
+select * from t1;
+a	b	c
+2	-2	-2
+drop table t1;
+# Table with UNIQUE vcol field. INSERT INTO tbl_name VALUES... ON DUPLICATE 
+# KEY UPDATE <non_vcol>=expr, <vcol>=expr
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent unique);
+insert into t1 values (1,default,default);
+insert into t1 values (1,default,default) 
+on duplicate key update a=2, b=default;
+select a,b,c from t1;
+a	b	c
+2	-2	-2
+# CREATE new_table ... LIKE old_table
+# INSERT INTO new_table SELECT * from old_table
+create table t2 like t1;
+insert into t2 select * from t1;
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't2' ignored.
+Warning	1645	The value specified for computed column 'c' in table 't2' ignored.
+select * from t1;
+a	b	c
+2	-2	-2
+drop table t2;
+# CREATE new_table ... LIKE old_table INSERT INTO new_table (<non-vcols>, <vcols>) 
+# SELECT <non-vcols>, <vcols> from old_table
+insert into t1 values (1,default,default);
+select * from t1;
+a	b	c
+2	-2	-2
+1	-1	-1
+create table t2 like t1;
+insert into t2 (a,b) select a,b from t1;
+Warnings:
+Warning	1645	The value specified for computed column 'b' in table 't2' ignored.
+Warning	1645	The value specified for computed column 'b' in table 't2' ignored.
+select * from t2;
+a	b	c
+2	-2	-2
+1	-1	-1
+drop table t2;
+drop table t1;
+#
+# *** UPDATE ***
+#
+# UPDATE tbl_name SET non-vcol=expr WHERE non-vcol=expr
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent);
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where a=2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# UPDATE tbl_name SET vcol=expr WHERE non-vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set c=3 where a=2;
+Warnings:
+Warning	1645	The value specified for computed column 'c' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where b=-2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# UPDATE tbl_name SET vcol=expr WHERE vcol=expr
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set c=3 where b=-2;
+Warnings:
+Warning	1645	The value specified for computed column 'c' in table 't1' ignored.
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+delete from t1;
+select * from t1;
+a	b	c
+drop table t1;
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=const
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent unique);
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where c=-2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where c between -3 and -2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# No INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr WHERE vcol=between const1 and const2
+insert into t1 (a) values (1), (2);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+update t1 set a=3 where b between -3 and -2;
+select * from t1;
+a	b	c
+1	-1	-1
+3	-3	-3
+delete from t1;
+select * from t1;
+a	b	c
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr 
+# WHERE vcol=between const1 and const2 ORDER BY vcol
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+update t1 set a=6 where c between -1 and 0
+order by c;
+select * from t1;
+a	b	c
+6	-6	-6
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1 where c between -6 and 0;
+select * from t1;
+a	b	c
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr 
+# WHERE vcol=between const1 and const2 ORDER BY vcol LIMIT 2
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+5	-5	-5
+4	-4	-4
+3	-3	-3
+2	-2	-2
+1	-1	-1
+update t1 set a=6 where c between -1 and 0
+order by c limit 2;
+select * from t1;
+a	b	c
+5	-5	-5
+4	-4	-4
+3	-3	-3
+2	-2	-2
+6	-6	-6
+delete from t1 where c between -2 and 0 order by c;
+select * from t1;
+a	b	c
+5	-5	-5
+4	-4	-4
+3	-3	-3
+6	-6	-6
+delete from t1;
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr
+# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+update t1 set a=6 where (c between -2 and 0) and (b=-1);
+select * from t1;
+a	b	c
+6	-6	-6
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1;
+# INDEX created on vcol 
+# UPDATE tbl_name SET non-vcol=expr
+# WHERE indexed vcol=between const1 and const2 and non-indexed vcol=const3
+# ORDER BY indexed vcol
+insert into t1 (a) values (1), (2), (3), (4), (5);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+update t1 set a=6 where (c between -2 and 0) and (b=-1) order by c;
+select * from t1;
+a	b	c
+6	-6	-6
+2	-2	-2
+3	-3	-3
+4	-4	-4
+5	-5	-5
+delete from t1;
+drop table t1;
+#
+# *** REPLACE ***
+#
+# UNIQUE INDEX on vcol
+# REPLACE tbl_name (non-vcols) VALUES (non-vcols);
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent unique,
+d varchar(16));
+insert into t1 (a,d) values (1,'a'), (2,'b');
+select * from t1;
+a	b	c	d
+1	-1	-1	a
+2	-2	-2	b
+replace t1 (a,d) values (1,'c');
+select * from t1;
+a	b	c	d
+1	-1	-1	c
+2	-2	-2	b
+delete from t1;
+select * from t1;
+a	b	c	d
+set sql_warnings = 0;
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_keys_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_keys_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,151 @@
+SET @@session.storage_engine = 'InnoDB';
+#            - UNIQUE KEY
+#            - INDEX
+#            - FULLTEXT INDEX
+#            - SPATIAL INDEX (not supported)
+#            - FOREIGN INDEX (partially supported)
+#            - CHECK (allowed but not used)
+# UNIQUE
+create table t1 (a int, b int as (a*2) unique);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2) persistent unique);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  UNIQUE KEY `b` (`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES	UNI	NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2), unique key (b));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2) persistent, unique (b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  UNIQUE KEY `b` (`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES	UNI	NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2));
+alter table t1 add unique key (b);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add unique key (b);
+drop table t1;
+# Testing data manipulation operations involving UNIQUE keys 
+# on virtual columns can be found in:
+#  - vcol_ins_upd.inc
+#  - vcol_select.inc
+# 
+# INDEX
+create table t1 (a int, b int as (a*2), index (b));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2), index (a,b));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2) persistent, index (b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  KEY `b` (`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES	MUL	NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent, index (a,b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  KEY `a` (`a`,`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES	MUL	NULL	
+b	int(11)	YES		NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2));
+alter table t1 add index (b);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+alter table t1 add index (a,b);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add index (b);
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add index (a,b);
+create table t2 like t1;
+drop table t2;
+drop table t1;
+# Testing data manipulation operations involving INDEX
+# on virtual columns can be found in:
+#  - vcol_select.inc
+#
+# TODO: FULLTEXT INDEX
+# SPATIAL INDEX
+# FOREIGN KEY
+# Rejected FK options.
+create table t1 (a int, b int as (a+1) persistent,
+foreign key (b) references t2(a) on update set null);
+ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column.
+create table t1 (a int, b int as (a+1) persistent,
+foreign key (b) references t2(a) on update cascade);
+ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column.
+create table t1 (a int, b int as (a+1) persistent,
+foreign key (b) references t2(a) on delete set null);
+ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column.
+create table t1 (a int, b int as (a+1) persistent);
+alter table t1 add foreign key (b) references t2(a) on update set null;
+ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column.
+alter table t1 add foreign key (b) references t2(a) on update cascade;
+ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column.
+alter table t1 add foreign key (b) references t2(a) on delete set null;
+ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column.
+drop table t1;
+create table t1 (a int, b int as (a+1),
+foreign key (b) references t2(a));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a+1));
+alter table t1 add foreign key (b) references t2(a);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+drop table t1;
+# Allowed FK options.
+create table t2 (a int primary key, b char(5));
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on update restrict);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on update no action);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on delete restrict);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on delete cascade);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on delete no action);
+drop table t1;
+
+# Testing data manipulation operations involving FOREIGN KEY 
+# on virtual columns can be found in:
+#  - vcol_ins_upd.inc
+#  - vcol_select.inc
+#
+# TODO: CHECK

=== added file 'mysql-test/suite/vcol/r/vcol_keys_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_keys_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,158 @@
+SET @@session.storage_engine = 'MyISAM';
+#            - UNIQUE KEY
+#            - INDEX
+#            - FULLTEXT INDEX
+#            - SPATIAL INDEX (not supported)
+#            - FOREIGN INDEX (partially supported)
+#            - CHECK (allowed but not used)
+# UNIQUE
+create table t1 (a int, b int as (a*2) unique);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2) persistent unique);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  UNIQUE KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES	UNI	NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2), unique key (b));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2) persistent, unique (b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  UNIQUE KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES	UNI	NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2));
+alter table t1 add unique key (b);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add unique key (b);
+drop table t1;
+# Testing data manipulation operations involving UNIQUE keys 
+# on virtual columns can be found in:
+#  - vcol_ins_upd.inc
+#  - vcol_select.inc
+# 
+# INDEX
+create table t1 (a int, b int as (a*2), index (b));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2), index (a,b));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a*2) persistent, index (b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	int(11)	YES	MUL	NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent, index (a,b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a*2) PERSISTENT,
+  KEY `a` (`a`,`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+describe t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES	MUL	NULL	
+b	int(11)	YES		NULL	VIRTUAL
+drop table t1;
+create table t1 (a int, b int as (a*2));
+alter table t1 add index (b);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+alter table t1 add index (a,b);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add index (b);
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent);
+alter table t1 add index (a,b);
+create table t2 like t1;
+drop table t2;
+drop table t1;
+# Testing data manipulation operations involving INDEX
+# on virtual columns can be found in:
+#  - vcol_select.inc
+#
+# TODO: FULLTEXT INDEX
+# SPATIAL INDEX
+# Error "All parts of a SPATIAL index must be NOT NULL"
+create table t1 (a int, b int as (a+1) persistent, spatial index (b));
+ERROR 42000: All parts of a SPATIAL index must be NOT NULL
+create table t1 (a int, b int as (a+1) persistent);
+alter table t1 add spatial index (b);
+ERROR 42000: All parts of a SPATIAL index must be NOT NULL
+drop table t1;
+# FOREIGN KEY
+# Rejected FK options.
+create table t1 (a int, b int as (a+1) persistent,
+foreign key (b) references t2(a) on update set null);
+ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column.
+create table t1 (a int, b int as (a+1) persistent,
+foreign key (b) references t2(a) on update cascade);
+ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column.
+create table t1 (a int, b int as (a+1) persistent,
+foreign key (b) references t2(a) on delete set null);
+ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column.
+create table t1 (a int, b int as (a+1) persistent);
+alter table t1 add foreign key (b) references t2(a) on update set null;
+ERROR HY000: Cannot define foreign key with ON UPDATE SET NULL clause on a computed column.
+alter table t1 add foreign key (b) references t2(a) on update cascade;
+ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a computed column.
+alter table t1 add foreign key (b) references t2(a) on delete set null;
+ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column.
+drop table t1;
+create table t1 (a int, b int as (a+1),
+foreign key (b) references t2(a));
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+create table t1 (a int, b int as (a+1));
+alter table t1 add foreign key (b) references t2(a);
+ERROR HY000: Key/Index cannot be defined on a non-stored computed column.
+drop table t1;
+# Allowed FK options.
+create table t2 (a int primary key, b char(5));
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on update restrict);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on update no action);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on delete restrict);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on delete cascade);
+drop table t1;
+create table t1 (a int, b int as (a % 10) persistent,
+foreign key (b) references t2(a) on delete no action);
+drop table t1;
+
+# Testing data manipulation operations involving FOREIGN KEY 
+# on virtual columns can be found in:
+#  - vcol_ins_upd.inc
+#  - vcol_select.inc
+#
+# TODO: CHECK

=== added file 'mysql-test/suite/vcol/r/vcol_memory.result'
--- a/mysql-test/suite/vcol/r/vcol_memory.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_memory.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,7 @@
+SET @@session.storage_engine = 'memory';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+create table t1 (a int);
+alter table t1 add column b int as (a+1);
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_merge.result'
--- a/mysql-test/suite/vcol/r/vcol_merge.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_merge.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,8 @@
+drop table if exists t1, t2, t3;
+create table t1 (a int, b int as (a % 10));
+create table t2 (a int, b int as (a % 10));
+insert into t1 values (1,default);
+insert into t2 values (2,default);
+create table t3 (a int, b int as (a % 10)) engine=MERGE UNION=(t1,t2);
+ERROR HY000: 'Specified storage engine' is not yet supported for computed columns.
+drop table t1,t2;

=== added file 'mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,242 @@
+SET @@session.storage_engine = 'InnoDB';
+# Case 1. All non-stored columns.
+# This scenario is currently impossible due to the fact that virtual columns
+# with a constant expression are not allowed.
+# Case 2. CREATE
+#  - Column1: "real"
+#  - Column 2: virtual non-stored
+create table t1 (a int, b int as (-a));
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	-1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	-1
+2	-2
+drop table t1;
+# Case 3. CREATE
+#  - Column1: "real"
+#  - Column 2: virtual stored
+create table t1 (a int, b int as (-a) persistent);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	-1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	-1
+2	-2
+drop table t1;
+# Case 4. CREATE
+#  - Column1: virtual non-stored
+#  - Column2: "real"
+create table t1 (a int as (-b), b int);
+insert into t1 values (default,1);
+select * from t1;
+a	b
+-1	1
+insert into t1 values (default,2);
+select * from t1;
+a	b
+-1	1
+-2	2
+drop table t1;
+# Case 5. CREATE
+#  - Column1: virtual stored
+#  - Column2: "real"
+create table t1 (a int as (-b) persistent, b int);
+insert into t1 values (default,1);
+select * from t1;
+a	b
+-1	1
+insert into t1 values (default,2);
+select * from t1;
+a	b
+-1	1
+-2	2
+drop table t1;
+# Case 6. CREATE
+#  - Column1: "real"
+#  - Column2: virtual non-stored
+#  - Column3: virtual stored
+create table t1 (a int, b int as (-a), c int as (-a) persistent);
+insert into t1 values (1,default,default);
+select * from t1;
+a	b	c
+1	-1	-1
+insert into t1 values (2,default,default);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+drop table t1;
+# Case 7. ALTER. Modify virtual stored -> virtual non-stored
+create table t1 (a int, b int as (a % 2) persistent);
+alter table t1 modify b int as (a % 2);
+ERROR HY000: 'Changing the STORED status' is not yet supported for computed columns.
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) PERSISTENT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+# Case 8. ALTER. Modify virtual non-stored -> virtual stored
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) persistent;
+ERROR HY000: 'Changing the STORED status' is not yet supported for computed columns.
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+# Case 9. CREATE LIKE
+#  - Column1: "real"
+#  - Column2: virtual non-stored
+#  - Column3: virtual stored
+create table t1 (a int, b int as (-a), c int as (-a) persistent);
+create table t2 like t1;
+insert into t2 values (1,default,default);
+select * from t2;
+a	b	c
+1	-1	-1
+insert into t2 values (2,default,default);
+select * from t2;
+a	b	c
+1	-1	-1
+2	-2	-2
+drop table t2;
+drop table t1;
+# Case 10. ALTER. Dropping a virtual non-stored column.
+#  - Column1: virtual non-stored
+#  - Column2: "real"
+create table t1 (a int as (-b), b int, c varchar(5));
+insert into t1 values (default,1,'v1');
+insert into t1 values (default,2,'v2');
+select * from t1;
+a	b	c
+-1	1	v1
+-2	2	v2
+alter table t1 drop column a;
+select * from t1;
+b	c
+1	v1
+2	v2
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `b` int(11) DEFAULT NULL,
+  `c` varchar(5) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+# Case 11. ALTER. Dropping a virtual stored column.
+#  - Column1: virtual stored
+#  - Column2: "real"
+create table t1 (a int as (-b) persistent, b int, c char(5));
+insert into t1 values (default,1,'v1');
+insert into t1 values (default,2,'v2');
+select * from t1;
+a	b	c
+-1	1	v1
+-2	2	v2
+alter table t1 drop column a;
+select * from t1;
+b	c
+1	v1
+2	v2
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `b` int(11) DEFAULT NULL,
+  `c` char(5) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+# Case 12. ALTER. Adding a new virtual non-stored column.
+create table t1 (a int, b datetime);
+insert into t1 values (1,'2008-09-04');
+insert into t1 values (2,'2008-09-05');
+select * from t1;
+a	b
+1	2008-09-04 00:00:00
+2	2008-09-05 00:00:00
+alter table t1 add column c int as (dayofyear(b)) after a;
+select * from t1;
+a	c	b
+1	248	2008-09-04 00:00:00
+2	249	2008-09-05 00:00:00
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `c` int(11) AS (dayofyear(b)) VIRTUAL,
+  `b` datetime DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+# Case 13. ALTER. Adding a new virtual stored column.
+create table t1 (a int, b datetime);
+insert into t1 values (1,'2008-09-04');
+insert into t1 values (2,'2008-09-05');
+select * from t1;
+a	b
+1	2008-09-04 00:00:00
+2	2008-09-05 00:00:00
+alter table t1 add column c int as (dayofyear(b)) persistent after a;
+select * from t1;
+a	c	b
+1	248	2008-09-04 00:00:00
+2	249	2008-09-05 00:00:00
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `c` int(11) AS (dayofyear(b)) PERSISTENT,
+  `b` datetime DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+# Case 14. ALTER. Changing the expression of a virtual stored column.
+create table t1 (a int, b datetime, c int as (week(b)) persistent);
+insert into t1 values (1,'2008-09-04',default);
+insert into t1 values (2,'2008-09-05',default);
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	35
+2	2008-09-05 00:00:00	35
+alter table t1 change column c c int as (week(b,1)) persistent;
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	36
+2	2008-09-05 00:00:00	36
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` datetime DEFAULT NULL,
+  `c` int(11) AS (week(b,1)) PERSISTENT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+# Case 15. ALTER. Changing the expression of a virtual non-stored column.
+create table t1 (a int, b datetime, c int as (week(b)));
+insert into t1 values (1,'2008-09-04',default);
+insert into t1 values (2,'2008-09-05',default);
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	35
+2	2008-09-05 00:00:00	35
+alter table t1 change column c c int as (week(b,1));
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	36
+2	2008-09-05 00:00:00	36
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` datetime DEFAULT NULL,
+  `c` int(11) AS (week(b,1)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,242 @@
+SET @@session.storage_engine = 'MyISAM';
+# Case 1. All non-stored columns.
+# This scenario is currently impossible due to the fact that virtual columns
+# with a constant expression are not allowed.
+# Case 2. CREATE
+#  - Column1: "real"
+#  - Column 2: virtual non-stored
+create table t1 (a int, b int as (-a));
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	-1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	-1
+2	-2
+drop table t1;
+# Case 3. CREATE
+#  - Column1: "real"
+#  - Column 2: virtual stored
+create table t1 (a int, b int as (-a) persistent);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	-1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	-1
+2	-2
+drop table t1;
+# Case 4. CREATE
+#  - Column1: virtual non-stored
+#  - Column2: "real"
+create table t1 (a int as (-b), b int);
+insert into t1 values (default,1);
+select * from t1;
+a	b
+-1	1
+insert into t1 values (default,2);
+select * from t1;
+a	b
+-1	1
+-2	2
+drop table t1;
+# Case 5. CREATE
+#  - Column1: virtual stored
+#  - Column2: "real"
+create table t1 (a int as (-b) persistent, b int);
+insert into t1 values (default,1);
+select * from t1;
+a	b
+-1	1
+insert into t1 values (default,2);
+select * from t1;
+a	b
+-1	1
+-2	2
+drop table t1;
+# Case 6. CREATE
+#  - Column1: "real"
+#  - Column2: virtual non-stored
+#  - Column3: virtual stored
+create table t1 (a int, b int as (-a), c int as (-a) persistent);
+insert into t1 values (1,default,default);
+select * from t1;
+a	b	c
+1	-1	-1
+insert into t1 values (2,default,default);
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+drop table t1;
+# Case 7. ALTER. Modify virtual stored -> virtual non-stored
+create table t1 (a int, b int as (a % 2) persistent);
+alter table t1 modify b int as (a % 2);
+ERROR HY000: 'Changing the STORED status' is not yet supported for computed columns.
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) PERSISTENT
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+# Case 8. ALTER. Modify virtual non-stored -> virtual stored
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) persistent;
+ERROR HY000: 'Changing the STORED status' is not yet supported for computed columns.
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+# Case 9. CREATE LIKE
+#  - Column1: "real"
+#  - Column2: virtual non-stored
+#  - Column3: virtual stored
+create table t1 (a int, b int as (-a), c int as (-a) persistent);
+create table t2 like t1;
+insert into t2 values (1,default,default);
+select * from t2;
+a	b	c
+1	-1	-1
+insert into t2 values (2,default,default);
+select * from t2;
+a	b	c
+1	-1	-1
+2	-2	-2
+drop table t2;
+drop table t1;
+# Case 10. ALTER. Dropping a virtual non-stored column.
+#  - Column1: virtual non-stored
+#  - Column2: "real"
+create table t1 (a int as (-b), b int, c varchar(5));
+insert into t1 values (default,1,'v1');
+insert into t1 values (default,2,'v2');
+select * from t1;
+a	b	c
+-1	1	v1
+-2	2	v2
+alter table t1 drop column a;
+select * from t1;
+b	c
+1	v1
+2	v2
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `b` int(11) DEFAULT NULL,
+  `c` varchar(5) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+# Case 11. ALTER. Dropping a virtual stored column.
+#  - Column1: virtual stored
+#  - Column2: "real"
+create table t1 (a int as (-b) persistent, b int, c char(5));
+insert into t1 values (default,1,'v1');
+insert into t1 values (default,2,'v2');
+select * from t1;
+a	b	c
+-1	1	v1
+-2	2	v2
+alter table t1 drop column a;
+select * from t1;
+b	c
+1	v1
+2	v2
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `b` int(11) DEFAULT NULL,
+  `c` char(5) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+# Case 12. ALTER. Adding a new virtual non-stored column.
+create table t1 (a int, b datetime);
+insert into t1 values (1,'2008-09-04');
+insert into t1 values (2,'2008-09-05');
+select * from t1;
+a	b
+1	2008-09-04 00:00:00
+2	2008-09-05 00:00:00
+alter table t1 add column c int as (dayofyear(b)) after a;
+select * from t1;
+a	c	b
+1	248	2008-09-04 00:00:00
+2	249	2008-09-05 00:00:00
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `c` int(11) AS (dayofyear(b)) VIRTUAL,
+  `b` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+# Case 13. ALTER. Adding a new virtual stored column.
+create table t1 (a int, b datetime);
+insert into t1 values (1,'2008-09-04');
+insert into t1 values (2,'2008-09-05');
+select * from t1;
+a	b
+1	2008-09-04 00:00:00
+2	2008-09-05 00:00:00
+alter table t1 add column c int as (dayofyear(b)) persistent after a;
+select * from t1;
+a	c	b
+1	248	2008-09-04 00:00:00
+2	249	2008-09-05 00:00:00
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `c` int(11) AS (dayofyear(b)) PERSISTENT,
+  `b` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+# Case 14. ALTER. Changing the expression of a virtual stored column.
+create table t1 (a int, b datetime, c int as (week(b)) persistent);
+insert into t1 values (1,'2008-09-04',default);
+insert into t1 values (2,'2008-09-05',default);
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	35
+2	2008-09-05 00:00:00	35
+alter table t1 change column c c int as (week(b,1)) persistent;
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	36
+2	2008-09-05 00:00:00	36
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` datetime DEFAULT NULL,
+  `c` int(11) AS (week(b,1)) PERSISTENT
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+# Case 15. ALTER. Changing the expression of a virtual non-stored column.
+create table t1 (a int, b datetime, c int as (week(b)));
+insert into t1 values (1,'2008-09-04',default);
+insert into t1 values (2,'2008-09-05',default);
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	35
+2	2008-09-05 00:00:00	35
+alter table t1 change column c c int as (week(b,1));
+select * from t1;
+a	b	c
+1	2008-09-04 00:00:00	36
+2	2008-09-05 00:00:00	36
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` datetime DEFAULT NULL,
+  `c` int(11) AS (week(b,1)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_partition_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_partition_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_partition_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,58 @@
+SET @@session.storage_engine = 'InnoDB';
+drop table if exists t1;
+# Case 1. Partitioning by RANGE based on a non-stored virtual column.
+CREATE TABLE t1 (
+a DATE NOT NULL,
+b int as (year(a))
+)
+PARTITION BY RANGE( b ) (
+PARTITION p0 VALUES LESS THAN (2006),
+PARTITION p2 VALUES LESS THAN (2008)
+);
+insert into t1 values ('2006-01-01',default);
+insert into t1 values ('2007-01-01',default);
+insert into t1 values ('2005-01-01',default);
+select * from t1;
+a	b
+2005-01-01	2005
+2006-01-01	2006
+2007-01-01	2007
+# Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+select * from t1;
+a	b
+2005-01-01	2004
+2006-01-01	2005
+2007-01-01	2006
+drop table t1;
+# Case 2. Partitioning by LIST based on a stored virtual column.
+CREATE TABLE t1 (a int, b int as (a % 3 ) persistent)
+PARTITION BY LIST (a+1)
+(PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2));
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	1
+select * from t1;
+a	b
+1	1
+drop table t1;
+# Case 3. Partitioning by HASH based on a non-stored virtual column.
+CREATE TABLE t1 (
+a DATE NOT NULL,
+b int as (year(a))
+)
+PARTITION BY HASH( b % 3 ) PARTITIONS 3;
+insert into t1 values ('2005-01-01',default);
+insert into t1 values ('2006-01-01',default);
+select * from t1;
+a	b
+2005-01-01	2005
+2006-01-01	2006
+# Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+select * from t1;
+a	b
+2005-01-01	2004
+2006-01-01	2005
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_partition_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_partition_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_partition_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,75 @@
+SET @@session.storage_engine = 'MyISAM';
+drop table if exists t1;
+# Case 1. Partitioning by RANGE based on a non-stored virtual column.
+CREATE TABLE t1 (
+a DATE NOT NULL,
+b int as (year(a))
+)
+PARTITION BY RANGE( b ) (
+PARTITION p0 VALUES LESS THAN (2006),
+PARTITION p2 VALUES LESS THAN (2008)
+);
+insert into t1 values ('2006-01-01',default);
+insert into t1 values ('2007-01-01',default);
+insert into t1 values ('2005-01-01',default);
+select * from t1;
+a	b
+2005-01-01	2005
+2006-01-01	2006
+2007-01-01	2007
+# Check how data is physically partitioned.
+7	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p0.MYD
+14	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p2.MYD
+# Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+select * from t1;
+a	b
+2005-01-01	2004
+2006-01-01	2005
+2007-01-01	2006
+# Check how data is physically partitioned.
+14	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p0.MYD
+7	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p2.MYD
+drop table t1;
+# Case 2. Partitioning by LIST based on a stored virtual column.
+CREATE TABLE t1 (a int, b int as (a % 3 ) persistent)
+PARTITION BY LIST (a+1)
+(PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2));
+insert into t1 values (1,default);
+# Check how data is physically partitioned.
+0	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p1.MYD
+9	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p2.MYD
+select * from t1;
+a	b
+1	1
+select * from t1;
+a	b
+1	1
+drop table t1;
+# Case 3. Partitioning by HASH based on a non-stored virtual column.
+CREATE TABLE t1 (
+a DATE NOT NULL,
+b int as (year(a))
+)
+PARTITION BY HASH( b % 3 ) PARTITIONS 3;
+insert into t1 values ('2005-01-01',default);
+insert into t1 values ('2006-01-01',default);
+select * from t1;
+a	b
+2005-01-01	2005
+2006-01-01	2006
+# Check how data is physically partitioned.
+0	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p0.MYD
+7	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p1.MYD
+7	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p2.MYD
+# Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+select * from t1;
+a	b
+2005-01-01	2004
+2006-01-01	2005
+# Check how data is physically partitioned.
+7	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p0.MYD
+7	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p1.MYD
+0	MYSQLTEST_VARDIR/mysqld.1/data/test/t1#P#p2.MYD
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_select_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_select_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,264 @@
+SET @@session.storage_engine = 'InnoDB';
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent,
+index (c));
+insert into t1 (a) values (2), (1), (1), (3), (NULL);
+create table t2 like t1;
+insert into t2 (a) values (1);
+create table t3 (a int primary key, 
+b int as (-a),
+c int as (-a) persistent unique);
+insert into t3 (a) values (2),(1),(3);
+# select_type=SIMPLE, type=system
+select * from t2;
+a	b	c
+1	-1	-1
+explain select * from t2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1	
+select * from t2 where c=-1;
+a	b	c
+1	-1	-1
+explain select * from t2 where c=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	ref	c	c	5	const	1	Using where
+# select_type=SIMPLE, type=ALL
+select * from t1 where b=-1;
+a	b	c
+1	-1	-1
+1	-1	-1
+explain select * from t1 where b=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using where
+# select_type=SIMPLE, type=const
+select * from t3 where a=1;
+a	b	c
+1	-1	-1
+explain select * from t3 where a=1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	const	PRIMARY	PRIMARY	4	const	1	
+# select_type=SIMPLE, type=range
+select * from t3 where c>=-1;
+a	b	c
+1	-1	-1
+explain select * from t3 where c>=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where
+# select_type=SIMPLE, type=ref
+select * from t1,t3 where t1.c=t3.c and t3.c=-1;
+a	b	c	a	b	c
+1	-1	-1	1	-1	-1
+1	-1	-1	1	-1	-1
+explain select * from t1,t3 where t1.c=t3.c and t3.c=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	const	c	c	5	const	1	
+1	SIMPLE	t1	ref	c	c	5	const	2	Using where
+# select_type=PRIMARY, type=index,ALL
+select * from t1 where b in (select c from t3);
+a	b	c
+2	-2	-2
+1	-1	-1
+1	-1	-1
+3	-3	-3
+explain select * from t1 where b in (select c from t3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	5	Using where
+2	DEPENDENT SUBQUERY	t3	index_subquery	c	c	5	func	1	Using index; Using where
+# select_type=PRIMARY, type=range,ref
+select * from t1 where c in (select c from t3 where c between -2 and -1);
+a	b	c
+2	-2	-2
+1	-1	-1
+1	-1	-1
+explain select * from t1 where c in (select c from t3 where c between -2 and -1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	5	Using where
+2	DEPENDENT SUBQUERY	t3	index_subquery	c	c	5	func	1	Using index; Using where
+# select_type=UNION, type=system
+# select_type=UNION RESULT, type=<union1,2>
+select * from t1 union select * from t2;
+a	b	c
+2	-2	-2
+1	-1	-1
+3	-3	-3
+NULL	NULL	NULL
+explain select * from t1 union select * from t2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	5	
+2	UNION	t2	ALL	NULL	NULL	NULL	NULL	1	
+NULL	UNION RESULT	<union1,2>	ALL	NULL	NULL	NULL	NULL	NULL	
+# select_type=DERIVED, type=system
+select * from (select a,b,c from t1) as t11;
+a	b	c
+2	-2	-2
+1	-1	-1
+1	-1	-1
+3	-3	-3
+NULL	NULL	NULL
+explain select * from (select a,b,c from t1) as t11;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	5	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	5	
+###
+### Using aggregate functions with/without DISTINCT
+###
+# SELECT COUNT(*) FROM tbl_name
+select count(*) from t1;
+count(*)
+5
+explain select count(*) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	c	5	NULL	5	Using index
+# SELECT COUNT(DISTINCT <non-vcol>) FROM tbl_name
+select count(distinct a) from t1;
+count(distinct a)
+3
+explain select count(distinct a) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	
+# SELECT COUNT(DISTINCT <non-stored vcol>) FROM tbl_name
+select count(distinct b) from t1;
+count(distinct b)
+3
+explain select count(distinct b) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	
+# SELECT COUNT(DISTINCT <stored vcol>) FROM tbl_name
+select count(distinct c) from t1;
+count(distinct c)
+3
+explain select count(distinct c) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	c	5	NULL	5	Using index
+###
+### filesort & range-based utils
+###
+# SELECT * FROM tbl_name WHERE <vcol expr>
+select * from t3 where c >= -2;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c >= -2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where
+# SELECT * FROM tbl_name WHERE <non-vcol expr>
+select * from t3 where a between 1 and 2;
+a	b	c
+1	-1	-1
+2	-2	-2
+explain select * from t3 where a between 1 and 2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	PRIMARY	PRIMARY	4	NULL	1	Using where
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr>
+select * from t3 where b between -2 and -1;
+a	b	c
+1	-1	-1
+2	-2	-2
+explain select * from t3 where b between -2 and -1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	Using where
+# SELECT * FROM tbl_name WHERE <indexed vcol expr>
+select * from t3 where c between -2 and -1;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c between -2 and -1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where
+# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <non-indexed vcol>
+select * from t3 where a between 1 and 2 order by b;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where a between 1 and 2 order by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	PRIMARY	PRIMARY	4	NULL	1	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol>
+select * from t3 where a between 1 and 2 order by c;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where a between 1 and 2 order by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	PRIMARY	PRIMARY	4	NULL	1	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol>
+select * from t3 where b between -2 and -1 order by a;
+a	b	c
+1	-1	-1
+2	-2	-2
+explain select * from t3 where b between -2 and -1 order by a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	index	NULL	PRIMARY	4	NULL	3	Using where
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol>
+select * from t3 where b between -2 and -1 order by b;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where b between -2 and -1 order by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-indexed vcol>
+select * from t3 where c between -2 and -1 order by b;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c between -2 and -1 order by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol>
+select * from t3 where b between -2 and -1 order by c;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where b between -2 and -1 order by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <indexed vcol>
+select * from t3 where c between -2 and -1 order by c;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c between -2 and -1 order by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where
+# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
+select sum(b) from t1 group by b;
+sum(b)
+NULL
+-3
+-2
+-2
+explain select sum(b) from t1 group by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using temporary; Using filesort
+# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <indexed vcol>
+select sum(c) from t1 group by c;
+sum(c)
+NULL
+-3
+-2
+-2
+explain select sum(c) from t1 group by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	c	5	NULL	5	Using index
+# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <indexed vcol>
+select sum(b) from t1 group by c;
+sum(b)
+NULL
+-3
+-2
+-2
+explain select sum(b) from t1 group by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	c	5	NULL	5	
+# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
+select sum(c) from t1 group by b;
+sum(c)
+NULL
+-3
+-2
+-2
+explain select sum(c) from t1 group by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using temporary; Using filesort

=== added file 'mysql-test/suite/vcol/r/vcol_select_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_select_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,264 @@
+SET @@session.storage_engine = 'MyISAM';
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent,
+index (c));
+insert into t1 (a) values (2), (1), (1), (3), (NULL);
+create table t2 like t1;
+insert into t2 (a) values (1);
+create table t3 (a int primary key, 
+b int as (-a),
+c int as (-a) persistent unique);
+insert into t3 (a) values (2),(1),(3);
+# select_type=SIMPLE, type=system
+select * from t2;
+a	b	c
+1	-1	-1
+explain select * from t2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	system	NULL	NULL	NULL	NULL	1	
+select * from t2 where c=-1;
+a	b	c
+1	-1	-1
+explain select * from t2 where c=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	system	c	NULL	NULL	NULL	1	
+# select_type=SIMPLE, type=ALL
+select * from t1 where b=-1;
+a	b	c
+1	-1	-1
+1	-1	-1
+explain select * from t1 where b=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using where
+# select_type=SIMPLE, type=const
+select * from t3 where a=1;
+a	b	c
+1	-1	-1
+explain select * from t3 where a=1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	const	PRIMARY	PRIMARY	4	const	1	
+# select_type=SIMPLE, type=range
+select * from t3 where c>=-1;
+a	b	c
+1	-1	-1
+explain select * from t3 where c>=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	2	Using where
+# select_type=SIMPLE, type=ref
+select * from t1,t3 where t1.c=t3.c and t3.c=-1;
+a	b	c	a	b	c
+1	-1	-1	1	-1	-1
+1	-1	-1	1	-1	-1
+explain select * from t1,t3 where t1.c=t3.c and t3.c=-1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	const	c	c	5	const	1	
+1	SIMPLE	t1	ref	c	c	5	const	2	Using where
+# select_type=PRIMARY, type=index,ALL
+select * from t1 where b in (select c from t3);
+a	b	c
+2	-2	-2
+1	-1	-1
+1	-1	-1
+3	-3	-3
+explain select * from t1 where b in (select c from t3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	5	Using where
+2	DEPENDENT SUBQUERY	t3	index_subquery	c	c	5	func	2	Using index; Using where
+# select_type=PRIMARY, type=range,ref
+select * from t1 where c in (select c from t3 where c between -2 and -1);
+a	b	c
+2	-2	-2
+1	-1	-1
+1	-1	-1
+explain select * from t1 where c in (select c from t3 where c between -2 and -1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	5	Using where
+2	DEPENDENT SUBQUERY	t3	index_subquery	c	c	5	func	2	Using index; Using where
+# select_type=UNION, type=system
+# select_type=UNION RESULT, type=<union1,2>
+select * from t1 union select * from t2;
+a	b	c
+2	-2	-2
+1	-1	-1
+3	-3	-3
+NULL	NULL	NULL
+explain select * from t1 union select * from t2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	5	
+2	UNION	t2	system	NULL	NULL	NULL	NULL	1	
+NULL	UNION RESULT	<union1,2>	ALL	NULL	NULL	NULL	NULL	NULL	
+# select_type=DERIVED, type=system
+select * from (select a,b,c from t1) as t11;
+a	b	c
+2	-2	-2
+1	-1	-1
+1	-1	-1
+3	-3	-3
+NULL	NULL	NULL
+explain select * from (select a,b,c from t1) as t11;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	5	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	5	
+###
+### Using aggregate functions with/without DISTINCT
+###
+# SELECT COUNT(*) FROM tbl_name
+select count(*) from t1;
+count(*)
+5
+explain select count(*) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Select tables optimized away
+# SELECT COUNT(DISTINCT <non-vcol>) FROM tbl_name
+select count(distinct a) from t1;
+count(distinct a)
+3
+explain select count(distinct a) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	
+# SELECT COUNT(DISTINCT <non-stored vcol>) FROM tbl_name
+select count(distinct b) from t1;
+count(distinct b)
+3
+explain select count(distinct b) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	
+# SELECT COUNT(DISTINCT <stored vcol>) FROM tbl_name
+select count(distinct c) from t1;
+count(distinct c)
+3
+explain select count(distinct c) from t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	c	5	NULL	5	Using index
+###
+### filesort & range-based utils
+###
+# SELECT * FROM tbl_name WHERE <vcol expr>
+select * from t3 where c >= -2;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c >= -2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	2	Using where
+# SELECT * FROM tbl_name WHERE <non-vcol expr>
+select * from t3 where a between 1 and 2;
+a	b	c
+1	-1	-1
+2	-2	-2
+explain select * from t3 where a between 1 and 2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	PRIMARY	PRIMARY	4	NULL	1	Using where
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr>
+select * from t3 where b between -2 and -1;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where b between -2 and -1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	Using where
+# SELECT * FROM tbl_name WHERE <indexed vcol expr>
+select * from t3 where c between -2 and -1;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c between -2 and -1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where
+# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol>
+select * from t3 where a between 1 and 2 order by c;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where a between 1 and 2 order by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	PRIMARY	PRIMARY	4	NULL	1	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol>
+select * from t3 where b between -2 and -1 order by a;
+a	b	c
+1	-1	-1
+2	-2	-2
+explain select * from t3 where b between -2 and -1 order by a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-vcol>
+select * from t3 where c between -2 and -1 order by a;
+a	b	c
+1	-1	-1
+2	-2	-2
+explain select * from t3 where c between -2 and -1 order by a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol>
+select * from t3 where b between -2 and -1 order by b;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where b between -2 and -1 order by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <non-indexed vcol>
+select * from t3 where c between -2 and -1 order by b;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c between -2 and -1 order by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol>
+select * from t3 where b between -2 and -1 order by c;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where b between -2 and -1 order by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using filesort
+# SELECT * FROM tbl_name WHERE <indexed vcol expr> ORDER BY <indexed vcol>
+select * from t3 where c between -2 and -1 order by c;
+a	b	c
+2	-2	-2
+1	-1	-1
+explain select * from t3 where c between -2 and -1 order by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	range	c	c	5	NULL	1	Using where
+# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
+select sum(b) from t1 group by b;
+sum(b)
+NULL
+-3
+-2
+-2
+explain select sum(b) from t1 group by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using temporary; Using filesort
+# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <indexed vcol>
+select sum(c) from t1 group by c;
+sum(c)
+NULL
+-3
+-2
+-2
+explain select sum(c) from t1 group by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	c	5	NULL	5	Using index
+# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <indexed vcol>
+select sum(b) from t1 group by c;
+sum(b)
+NULL
+-3
+-2
+-2
+explain select sum(b) from t1 group by c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using temporary; Using filesort
+# SELECT sum(<indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
+select sum(c) from t1 group by b;
+sum(c)
+NULL
+-3
+-2
+-2
+explain select sum(c) from t1 group by b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using temporary; Using filesort

=== added file 'mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,2942 @@
+SET @@session.storage_engine = 'InnoDB';
+#
+# NUMERIC FUNCTIONS
+#
+# ABS()
+set sql_warnings = 1;
+create table t1 (a int, b int as (abs(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (abs(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-1, default);
+select * from t1;
+a	b
+-1	1
+drop table t1;
+set sql_warnings = 0;
+# ACOS()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(acos(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(acos(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1, default);
+insert into t1 values (1.0001,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+1	0
+1.0001	NULL
+0	1.570796
+drop table t1;
+set sql_warnings = 0;
+# ASIN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(asin(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(asin(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (0.2, default);
+insert into t1 values (1.0001,default);
+select * from t1;
+a	b
+0.2	0.201358
+1.0001	NULL
+drop table t1;
+set sql_warnings = 0;
+#ATAN
+set sql_warnings = 1;
+create table t1 (a double, b double, c double as (format(atan(a,b),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` double AS (format(atan(a,b),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-2,2,default);
+insert into t1 values (format(PI(),6),0,default);
+select * from t1;
+a	b	c
+-2	2	-0.785398
+3.141593	0	1.570796
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a double, c double as (format(atan(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `c` double AS (format(atan(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-2,default);
+insert into t1 values (format(PI(),6),default);
+select * from t1;
+a	c
+-2	-1.107149
+3.141593	1.262627
+drop table t1;
+set sql_warnings = 0;
+# ATAN2
+set sql_warnings = 1;
+create table t1 (a double, b double, c double as (format(atan2(a,b),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` double AS (format(atan2(a,b),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-2,2,default);
+insert into t1 values (format(PI(),6),0,default);
+select * from t1;
+a	b	c
+-2	2	-0.785398
+3.141593	0	1.570796
+drop table t1;
+set sql_warnings = 0;
+# CEIL()
+set sql_warnings = 1;
+create table t1 (a double, b int as (ceil(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` int(11) AS (ceil(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1.23,default);
+insert into t1 values (-1.23,default);
+select * from t1;
+a	b
+1.23	2
+-1.23	-1
+drop table t1;
+set sql_warnings = 0;
+# CONV()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b int, c int, d varchar(10) as (conv(a,b,c)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` varchar(10) AS (conv(a,b,c)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('a',16,2,default);
+insert into t1 values ('6e',18,8,default);
+insert into t1 values (-17,10,-18,default);
+insert into t1 values (10+'10'+'10'+0xa,10,10,default);
+select * from t1;
+a	b	c	d
+a	16	2	1010
+6e	18	8	172
+-17	10	-18	-H
+40	10	10	40
+drop table t1;
+set sql_warnings = 0;
+# COS()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(cos(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(cos(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (format(PI(),6),default);
+select * from t1;
+a	b
+3.141593	-1
+drop table t1;
+set sql_warnings = 0;
+# COT()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(cot(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(cot(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+12	-1.572673
+0	NULL
+drop table t1;
+set sql_warnings = 0;
+# CRC32()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (crc32(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (crc32(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+insert into t1 values ('mysql',default);
+select * from t1;
+a	b
+MySQL	3259397556
+mysql	2501908538
+drop table t1;
+set sql_warnings = 0;
+# DEGREES()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(degrees(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(degrees(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (format(PI(),6),default);
+insert into t1 values (format(PI()/2,6),default);
+select * from t1;
+a	b
+3.141593	180.00002
+1.570796	89.999981
+drop table t1;
+set sql_warnings = 0;
+# /
+set sql_warnings = 1;
+create table t1 (a double, b double as (a/2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (a/2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+2	1
+drop table t1;
+set sql_warnings = 0;
+# EXP()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(exp(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(exp(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (-2,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+2	7.389056
+-2	0.135335
+0	1
+drop table t1;
+set sql_warnings = 0;
+# FLOOR()
+set sql_warnings = 1;
+create table t1 (a double, b long as (floor(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` mediumtext AS (floor(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1.23,default);
+insert into t1 values (-1.23,default);
+select * from t1;
+a	b
+1.23	1
+-1.23	-2
+drop table t1;
+set sql_warnings = 0;
+# LN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(ln(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(ln(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (-2,default);
+select * from t1;
+a	b
+2	0.693147
+-2	NULL
+drop table t1;
+set sql_warnings = 0;
+# LOG()
+set sql_warnings = 1;
+create table t1 (a double, b double, c double as (format(log(a,b),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` double AS (format(log(a,b),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2,65536,default);
+insert into t1 values (10,100,default);
+insert into t1 values (1,100,default);
+select * from t1;
+a	b	c
+2	65536	16
+10	100	2
+1	100	NULL
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(log(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(log(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (-2,default);
+select * from t1;
+a	b
+2	0.693147
+-2	NULL
+drop table t1;
+set sql_warnings = 0;
+# LOG2()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(log2(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(log2(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (65536,default);
+insert into t1 values (-100,default);
+select * from t1;
+a	b
+65536	16
+-100	NULL
+drop table t1;
+set sql_warnings = 0;
+# LOG10()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(log10(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(log10(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (100,default);
+insert into t1 values (-100,default);
+select * from t1;
+a	b
+2	0.30103
+100	2
+-100	NULL
+drop table t1;
+set sql_warnings = 0;
+# -
+set sql_warnings = 1;
+create table t1 (a double, b double as (a-1));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (a-1) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+2	1
+drop table t1;
+set sql_warnings = 0;
+# MOD()
+set sql_warnings = 1;
+create table t1 (a int, b int as (mod(a,10)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (mod(a,10)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (11,default);
+select * from t1;
+a	b
+1	1
+11	1
+drop table t1;
+set sql_warnings = 0;
+# %
+set sql_warnings = 1;
+create table t1 (a int, b int as (a % 10));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 10) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (11,default);
+select * from t1;
+a	b
+1	1
+11	1
+drop table t1;
+set sql_warnings = 0;
+# OCT()
+set sql_warnings = 1;
+create table t1 (a double, b varchar(10) as (oct(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` varchar(10) AS (oct(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+select * from t1;
+a	b
+12	14
+drop table t1;
+set sql_warnings = 0;
+# PI()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(PI()*a*a,6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(PI()*a*a,6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	3.141593
+drop table t1;
+set sql_warnings = 0;
+# +
+set sql_warnings = 1;
+create table t1 (a int, b int as (a+1));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a+1) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	2
+drop table t1;
+set sql_warnings = 0;
+# POW, POWER
+set sql_warnings = 1;
+create table t1 (a int, b int as (pow(a,2)), c int as (power(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (pow(a,2)) VIRTUAL,
+  `c` int(11) AS (power(a,2)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default,default);
+insert into t1 values (2,default,default);
+select * from t1;
+a	b	c
+1	1	1
+2	4	4
+drop table t1;
+set sql_warnings = 0;
+# RADIANS()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(radians(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(radians(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (90,default);
+select * from t1;
+a	b
+90	1.570796
+drop table t1;
+set sql_warnings = 0;
+# ROUND()
+set sql_warnings = 1;
+create table t1 (a double, b int as (round(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` int(11) AS (round(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-1.23,default);
+insert into t1 values (-1.58,default);
+insert into t1 values (1.58,default);
+select * from t1;
+a	b
+-1.23	-1
+-1.58	-2
+1.58	2
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a double, b double, c int as (round(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` int(11) AS (round(a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1.298,1,default);
+insert into t1 values (1.298,0,default);
+insert into t1 values (23.298,-1,default);
+select * from t1;
+a	b	c
+1.298	1	1
+1.298	0	1
+23.298	-1	20
+drop table t1;
+set sql_warnings = 0;
+# SIGN()
+set sql_warnings = 1;
+create table t1 (a double, b int as (sign(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` int(11) AS (sign(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-32,default);
+insert into t1 values (0,default);
+insert into t1 values (234,default);
+select * from t1;
+a	b
+-32	-1
+0	0
+234	1
+drop table t1;
+set sql_warnings = 0;
+# SIN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(sin(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(sin(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (format(PI()/2,6),default);
+select * from t1;
+a	b
+1.570796	1
+drop table t1;
+set sql_warnings = 0;
+# SQRT()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(sqrt(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(sqrt(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (4,default);
+insert into t1 values (20,default);
+insert into t1 values (-16,default);
+select * from t1;
+a	b
+4	2
+20	4.472136
+-16	NULL
+drop table t1;
+set sql_warnings = 0;
+# TAN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(tan(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(tan(a),6)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (format(PI(),6),default);
+insert into t1 values (format(PI()+1,6),default);
+select * from t1;
+a	b
+3.141593	0
+4.141593	1.557409
+drop table t1;
+set sql_warnings = 0;
+# *
+set sql_warnings = 1;
+create table t1 (a double, b double as (a*3));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (a*3) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (0,default);
+insert into t1 values (1,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+0	0
+1	3
+2	6
+drop table t1;
+set sql_warnings = 0;
+# TRUNCATE()
+set sql_warnings = 1;
+create table t1 (a double, b double as (truncate(a,4)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (truncate(a,4)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1.223,default);
+insert into t1 values (1.999,default);
+insert into t1 values (1.999,default);
+insert into t1 values (122,default);
+select * from t1;
+a	b
+1.223	1.223
+1.999	1.999
+1.999	1.999
+122	122
+drop table t1;
+set sql_warnings = 0;
+# Unary -
+set sql_warnings = 1;
+create table t1 (a double, b double as (-a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (-a) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (-1,default);
+select * from t1;
+a	b
+1	-1
+-1	1
+drop table t1;
+set sql_warnings = 0;
+#
+# STRING FUNCTIONS
+#
+# ASCII()
+set sql_warnings = 1;
+create table t1 (a char(2), b int as (ascii(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` char(2) DEFAULT NULL,
+  `b` int(11) AS (ascii(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2',default);
+insert into t1 values (2,default);
+insert into t1 values ('dx',default);
+select * from t1;
+a	b
+2	50
+2	50
+dx	100
+drop table t1;
+set sql_warnings = 0;
+# BIN()
+set sql_warnings = 1;
+create table t1 (a int, b varchar(10) as (bin(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` varchar(10) AS (bin(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+select * from t1;
+a	b
+12	1100
+drop table t1;
+set sql_warnings = 0;
+# BIT_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (bit_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (bit_length(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	32
+drop table t1;
+set sql_warnings = 0;
+# CHAR_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (char_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (char_length(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# CHAR()
+set sql_warnings = 1;
+create table t1 (a int, b int, c varbinary(10) as (char(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` varbinary(10) AS (char(a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (77,121,default);
+select * from t1;
+a	b	c
+77	121	My
+drop table t1;
+set sql_warnings = 0;
+# CHARACTER_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (character_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (character_length(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# CONCAT_WS()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat_ws(',',a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(20) AS (concat_ws(',',a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('value1','value2',default);
+select * from t1;
+a	b	c
+value1	value2	value1,value2
+drop table t1;
+set sql_warnings = 0;
+# CONCAT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat(a,',',b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(20) AS (concat(a,',',b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('value1','value2',default);
+select * from t1;
+a	b	c
+value1	value2	value1,value2
+drop table t1;
+set sql_warnings = 0;
+# ELT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int, d varchar(10) as (elt(c,a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` varchar(10) AS (elt(c,a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('value1','value2',1,default);
+insert into t1 values ('value1','value2',2,default);
+select * from t1;
+a	b	c	d
+value1	value2	1	value1
+value1	value2	2	value2
+drop table t1;
+set sql_warnings = 0;
+# EXPORT_SET()
+set sql_warnings = 1;
+create table t1 (a int, b varchar(10) as (export_set(a,'1','0','',10)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` varchar(10) AS (export_set(a,'1','0','',10)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (6,default);
+select * from t1;
+a	b
+6	0110000000
+drop table t1;
+set sql_warnings = 0;
+# FIELD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int as (field('aa',a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) AS (field('aa',a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('aa','bb',default);
+insert into t1 values ('bb','aa',default);
+select * from t1;
+a	b	c
+aa	bb	1
+bb	aa	2
+drop table t1;
+set sql_warnings = 0;
+# FIND_IN_SET()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int as (find_in_set(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) AS (find_in_set(a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('aa','aa,bb,cc',default);
+insert into t1 values ('aa','bb,aa,cc',default);
+select * from t1;
+a	b	c
+aa	aa,bb,cc	1
+aa	bb,aa,cc	2
+drop table t1;
+set sql_warnings = 0;
+# FORMAT()
+set sql_warnings = 1;
+create table t1 (a double, b varchar(20) as (format(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` varchar(20) AS (format(a,2)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (12332.123456,default);
+select * from t1;
+a	b
+12332.123456	12,332.12
+drop table t1;
+set sql_warnings = 0;
+# HEX()
+set sql_warnings = 1;
+create table t1 (a int, b varchar(10) as (hex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` varchar(10) AS (hex(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (17,default);
+select * from t1;
+a	b
+17	11
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (hex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (hex(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	616263
+drop table t1;
+set sql_warnings = 0;
+# INSERT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(20) as (insert(a,length(a),length(b),b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(20) AS (insert(a,length(a),length(b),b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('start,','end',default);
+select * from t1;
+a	b	c
+start,	end	startend
+drop table t1;
+set sql_warnings = 0;
+# INSTR()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int as (instr(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) AS (instr(a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar,','bar',default);
+insert into t1 values ('xbar,','foobar',default);
+select * from t1;
+a	b	c
+foobarbar,	bar	4
+xbar,	foobar	0
+drop table t1;
+set sql_warnings = 0;
+# LCASE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (lcase(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (lcase(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	mysql
+drop table t1;
+set sql_warnings = 0;
+# LEFT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(5) as (left(a,5)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(5) AS (left(a,5)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	fooba
+drop table t1;
+set sql_warnings = 0;
+# LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b int as (length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` int(11) AS (length(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# LIKE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a like 'H%o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a like 'H%o') VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+Hello	1
+MySQL	0
+drop table t1;
+set sql_warnings = 0;
+# LOCATE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (locate('bar',a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (locate('bar',a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	4
+drop table t1;
+set sql_warnings = 0;
+# LOWER()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (lower(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (lower(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	mysql
+drop table t1;
+set sql_warnings = 0;
+# LPAD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (lpad(a,4,' ')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (lpad(a,4,' ')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+insert into t1 values ('M',default);
+select * from t1;
+a	b
+MySQL	MySQ
+M	   M
+drop table t1;
+set sql_warnings = 0;
+# LTRIM()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (ltrim(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (ltrim(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('  MySQL',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+  MySQL	MySQL
+MySQL	MySQL
+drop table t1;
+set sql_warnings = 0;
+# MAKE_SET()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int, d varchar(30) as (make_set(c,a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` varchar(30) AS (make_set(c,a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',1,default);
+insert into t1 values ('a','b',3,default);
+select * from t1;
+a	b	c	d
+a	b	1	a
+a	b	3	a,b
+drop table t1;
+set sql_warnings = 0;
+# MID()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (mid(a,1,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (mid(a,1,2)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	fo
+drop table t1;
+set sql_warnings = 0;
+# NOT LIKE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a not like 'H%o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a not like 'H%o') VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+Hello	0
+MySQL	1
+drop table t1;
+set sql_warnings = 0;
+# NOT REGEXP
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a not regexp 'H.+o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a not regexp 'H.+o') VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('hello',default);
+select * from t1;
+a	b
+Hello	0
+hello	0
+drop table t1;
+set sql_warnings = 0;
+# OCTET_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b int as (octet_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` int(11) AS (octet_length(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# ORD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (ord(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (ord(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2',default);
+select * from t1;
+a	b
+2	50
+drop table t1;
+set sql_warnings = 0;
+# POSITION()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (position('bar' in a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (position('bar' in a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	4
+drop table t1;
+set sql_warnings = 0;
+# QUOTE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (quote(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (quote(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Don\'t',default);
+select * from t1;
+a	b
+Don't	'Don\'t'
+drop table t1;
+set sql_warnings = 0;
+# REGEXP()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a regexp 'H.+o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a regexp 'H.+o') VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('hello',default);
+select * from t1;
+a	b
+Hello	1
+hello	1
+drop table t1;
+set sql_warnings = 0;
+# REPEAT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(30) as (repeat(a,3)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(30) AS (repeat(a,3)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MySQLMySQLMySQL
+drop table t1;
+set sql_warnings = 0;
+# REPLACE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(30) as (replace(a,'aa','bb')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(30) AS (replace(a,'aa','bb')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('maa',default);
+select * from t1;
+a	b
+maa	mbb
+drop table t1;
+set sql_warnings = 0;
+# REVERSE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(30) as (reverse(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(30) AS (reverse(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('maa',default);
+select * from t1;
+a	b
+maa	aam
+drop table t1;
+set sql_warnings = 0;
+# RIGHT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (right(a,4)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (right(a,4)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	rbar
+drop table t1;
+set sql_warnings = 0;
+# RLIKE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a rlike 'H.+o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a rlike 'H.+o') VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+Hello	1
+MySQL	0
+drop table t1;
+set sql_warnings = 0;
+# RPAD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (rpad(a,4,'??')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (rpad(a,4,'??')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('He',default);
+select * from t1;
+a	b
+He	He??
+drop table t1;
+set sql_warnings = 0;
+# RTRIM();
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (rtrim(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (rtrim(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello  ',default);
+select * from t1;
+a	b
+Hello  	Hello
+drop table t1;
+set sql_warnings = 0;
+# SOUNDEX()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(20) as (soundex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(20) AS (soundex(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+select * from t1;
+a	b
+Hello	H400
+drop table t1;
+set sql_warnings = 0;
+# SOUNDS LIKE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a sounds like b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a sounds like b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello','Hello',default);
+insert into t1 values ('Hello','MySQL',default);
+insert into t1 values ('Hello','hello',default);
+select * from t1;
+a	b	c
+Hello	Hello	1
+Hello	MySQL	0
+Hello	hello	1
+drop table t1;
+set sql_warnings = 0;
+# SPACE()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (concat(a,space(5))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (concat(a,space(5))) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello', default);
+select * from t1;
+a	b
+Hello	Hello     
+drop table t1;
+set sql_warnings = 0;
+# STRCMP()
+set sql_warnings = 1;
+create table t1 (a varchar(9), b varchar(9), c tinyint(1) as (strcmp(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(9) DEFAULT NULL,
+  `b` varchar(9) DEFAULT NULL,
+  `c` tinyint(1) AS (strcmp(a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello','Hello', default);
+insert into t1 values ('Hello','Hello1', default);
+select * from t1;
+a	b	c
+Hello	Hello	0
+Hello	Hello1	-1
+drop table t1;
+set sql_warnings = 0;
+# SUBSTR()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (substr(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (substr(a,2)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+select * from t1;
+a	b
+Hello	ello
+drop table t1;
+set sql_warnings = 0;
+# SUBSTRING_INDEX()
+set sql_warnings = 1;
+create table t1 (a varchar(15), b varchar(10) as (substring_index(a,'.',2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(15) DEFAULT NULL,
+  `b` varchar(10) AS (substring_index(a,'.',2)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('www.mysql.com',default);
+select * from t1;
+a	b
+www.mysql.com	www.mysql
+drop table t1;
+set sql_warnings = 0;
+# SUBSTRING()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (substring(a from 2 for 2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (substring(a from 2 for 2)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+select * from t1;
+a	b
+Hello	el
+drop table t1;
+set sql_warnings = 0;
+# TRIM()
+set sql_warnings = 1;
+create table t1 (a varchar(15), b varchar(10) as (trim(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(15) DEFAULT NULL,
+  `b` varchar(10) AS (trim(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (' aa ',default);
+select * from t1;
+a	b
+ aa 	aa
+drop table t1;
+set sql_warnings = 0;
+# UCASE()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (ucase(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (ucase(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MYSQL
+drop table t1;
+set sql_warnings = 0;
+# UNHEX()
+set sql_warnings = 1;
+create table t1 (a varchar(15), b varchar(10) as (unhex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(15) DEFAULT NULL,
+  `b` varchar(10) AS (unhex(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('4D7953514C',default);
+select * from t1;
+a	b
+4D7953514C	MySQL
+drop table t1;
+set sql_warnings = 0;
+# UPPER()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (upper(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (upper(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MYSQL
+drop table t1;
+set sql_warnings = 0;
+#
+# CONTROL FLOW FUNCTIONS
+#
+# CASE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(16) as (case a when NULL then 'asd' when 'b' then 'B' else a end));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(16) AS (case a when NULL then 'asd' when 'b' then 'B' else a end) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (NULL,default);
+insert into t1 values ('b',default);
+insert into t1 values ('c',default);
+select * from t1;
+a	b
+NULL	NULL
+b	B
+c	c
+drop table t1;
+set sql_warnings = 0;
+# IF
+set sql_warnings = 1;
+create table t1 (a int, b int, c int as (if(a=1,a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) AS (if(a=1,a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,2,default);
+insert into t1 values (3,4,default);
+select * from t1;
+a	b	c
+1	2	1
+3	4	4
+drop table t1;
+set sql_warnings = 0;
+# IFNULL
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(10) as (ifnull(a,'DEFAULT')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(10) AS (ifnull(a,'DEFAULT')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (NULL,'adf',default);
+insert into t1 values ('a','adf',default);
+select * from t1;
+a	b	c
+NULL	adf	DEFAULT
+a	adf	a
+drop table t1;
+set sql_warnings = 0;
+# NULLIF
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (nullif(a,'DEFAULT')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (nullif(a,'DEFAULT')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('DEFAULT',default);
+insert into t1 values ('a',default);
+select * from t1;
+a	b
+DEFAULT	NULL
+a	a
+drop table t1;
+set sql_warnings = 0;
+#
+# OPERATORS
+#
+# AND, && 
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a>0 && a<2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a>0 && a<2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-1,default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+-1	0
+1	1
+drop table t1;
+set sql_warnings = 0;
+# BETWEEN ... AND ... 
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a between 0 and 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a between 0 and 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-1,default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+-1	0
+1	1
+drop table t1;
+set sql_warnings = 0;
+# BINARY
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varbinary(10) as (binary a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varbinary(10) AS (binary a) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('11',default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+11	11
+1	1
+drop table t1;
+set sql_warnings = 0;
+# &
+set sql_warnings = 1;
+create table t1 (a int, b int as (a & 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a & 5) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+1	1
+0	0
+drop table t1;
+set sql_warnings = 0;
+# ~
+set sql_warnings = 1;
+create table t1 (a int, b int as (~a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (~a) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+Warnings:
+Warning	1264	Out of range value for column 'b' at row 1
+select * from t1;
+a	b
+1	2147483647
+drop table t1;
+set sql_warnings = 0;
+# |
+set sql_warnings = 1;
+create table t1 (a int, b int as (a | 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a | 5) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (0,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	5
+0	5
+2	7
+drop table t1;
+set sql_warnings = 0;
+# ^
+set sql_warnings = 1;
+create table t1 (a int, b int as (a ^ 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a ^ 5) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (0,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	4
+0	5
+2	7
+drop table t1;
+set sql_warnings = 0;
+# DIV
+set sql_warnings = 1;
+create table t1 (a int, b int as (a div 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a div 5) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (7,default);
+select * from t1;
+a	b
+1	0
+7	1
+drop table t1;
+set sql_warnings = 0;
+# <=>
+set sql_warnings = 1;
+create table t1 (a int, b int, c bool as (a <=> b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` tinyint(1) AS (a <=> b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,1,default);
+insert into t1 values (NULL,NULL,default);
+insert into t1 values (1,NULL,default);
+select * from t1;
+a	b	c
+1	1	1
+NULL	NULL	1
+1	NULL	0
+drop table t1;
+set sql_warnings = 0;
+# =
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a=b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a=b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',default);
+insert into t1 values ('a','a',default);
+select * from t1;
+a	b	c
+a	b	0
+a	a	1
+drop table t1;
+set sql_warnings = 0;
+# >=
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a >= b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a >= b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',default);
+insert into t1 values ('a','a',default);
+select * from t1;
+a	b	c
+a	b	0
+a	a	1
+drop table t1;
+set sql_warnings = 0;
+# >
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a > b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a > b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',default);
+insert into t1 values ('a','a',default);
+select * from t1;
+a	b	c
+a	b	0
+a	a	0
+drop table t1;
+set sql_warnings = 0;
+# IS NOT NULL
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a is not null));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a is not null) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (NULL,default);
+select * from t1;
+a	b
+1	1
+NULL	0
+drop table t1;
+set sql_warnings = 0;
+# IS NULL
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a is null));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a is null) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (NULL,default);
+select * from t1;
+a	b
+1	0
+NULL	1
+drop table t1;
+set sql_warnings = 0;
+# <<
+set sql_warnings = 1;
+create table t1 (a int, b int as (a << 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a << 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (3,default);
+select * from t1;
+a	b
+1	4
+3	12
+drop table t1;
+set sql_warnings = 0;
+# <=
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a <= b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a <= b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	0
+b	b	1
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# <
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a < b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a < b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	0
+b	b	0
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# NOT BETWEEN ... AND ...
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a not between 0 and 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a not between 0 and 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (-1,default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+-1	1
+1	0
+drop table t1;
+set sql_warnings = 0;
+# <>
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a <> b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a <> b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	1
+b	b	0
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# !=
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a != b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a != b) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	1
+b	b	0
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# ||, OR
+set sql_warnings = 1;
+create table t1 (a int, b int as (a>5 || a<3));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a>5 || a<3) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (4,default);
+select * from t1;
+a	b
+1	1
+4	0
+drop table t1;
+set sql_warnings = 0;
+# >>
+set sql_warnings = 1;
+create table t1 (a int, b int as (a >> 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a >> 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (8,default);
+insert into t1 values (3,default);
+select * from t1;
+a	b
+8	2
+3	0
+drop table t1;
+set sql_warnings = 0;
+# XOR
+set sql_warnings = 1;
+create table t1 (a int, b int as (a xor 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a xor 5) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (0,default);
+insert into t1 values (1,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+0	1
+1	0
+2	0
+drop table t1;
+set sql_warnings = 0;
+#
+# DATE AND TIME FUNCTIONS
+#
+# ADDDATE()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (adddate(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (adddate(a,interval 1 month)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-09-30 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# ADDTIME()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (addtime(a,'02:00:00')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (addtime(a,'02:00:00')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-08-31 02:00:00
+drop table t1;
+set sql_warnings = 0;
+# CONVERT_TZ()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (convert_tz(a,'MET','UTC')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (convert_tz(a,'MET','UTC')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-08-30 22:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATE_ADD()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (date_add(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (date_add(a,interval 1 month)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-09-30 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATE_FORMAT()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(64) as (date_format(a,'%W %M %D')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(64) AS (date_format(a,'%W %M %D')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	Sunday August 31st
+drop table t1;
+set sql_warnings = 0;
+# DATE_SUB()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (date_sub(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (date_sub(a,interval 1 month)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-07-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATE()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (date(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (date(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31 02:00:00',default);
+select * from t1;
+a	b
+2008-08-31 02:00:00	2008-08-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATEDIFF()
+set sql_warnings = 1;
+create table t1 (a datetime, b long as (datediff(a,'2000-01-01')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` mediumtext AS (datediff(a,'2000-01-01')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	3165
+drop table t1;
+set sql_warnings = 0;
+# DAY()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (day(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (day(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	31
+drop table t1;
+set sql_warnings = 0;
+# DAYNAME()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(10) as (dayname(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(10) AS (dayname(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	Sunday
+drop table t1;
+set sql_warnings = 0;
+# DAYOFMONTH()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (dayofmonth(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (dayofmonth(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	31
+drop table t1;
+set sql_warnings = 0;
+# DAYOFWEEK()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (dayofweek(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (dayofweek(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	1
+drop table t1;
+set sql_warnings = 0;
+# DAYOFYEAR()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (dayofyear(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (dayofyear(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	244
+drop table t1;
+set sql_warnings = 0;
+# EXTRACT
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (extract(year from a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (extract(year from a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008
+drop table t1;
+set sql_warnings = 0;
+# FROM_DAYS()
+set sql_warnings = 1;
+create table t1 (a long, b datetime as (from_days(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` mediumtext,
+  `b` datetime AS (from_days(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (730669,default);
+select * from t1;
+a	b
+730669	2000-07-03 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# FROM_UNIXTIME()
+set sql_warnings = 1;
+create table t1 (a long, b datetime as (from_unixtime(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` mediumtext,
+  `b` datetime AS (from_unixtime(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1196440219,default);
+select * from t1;
+a	b
+1196440219	2007-11-30 19:30:19
+drop table t1;
+set sql_warnings = 0;
+# GET_FORMAT()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(32) as (date_format(a,get_format(DATE,'EUR'))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(32) AS (date_format(a,get_format(DATE,'EUR'))) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	31.08.2008
+drop table t1;
+set sql_warnings = 0;
+# HOUR()
+set sql_warnings = 1;
+create table t1 (a time, b long as (hour(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` time DEFAULT NULL,
+  `b` mediumtext AS (hour(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('10:05:03',default);
+select * from t1;
+a	b
+10:05:03	10
+drop table t1;
+set sql_warnings = 0;
+# LAST_DAY()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (last_day(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (last_day(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2003-02-05',default);
+insert into t1 values ('2003-02-32',default);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+select * from t1;
+a	b
+2003-02-05 00:00:00	2003-02-28 00:00:00
+0000-00-00 00:00:00	NULL
+drop table t1;
+set sql_warnings = 0;
+# MAKEDATE()
+set sql_warnings = 1;
+create table t1 (a int, b datetime as (makedate(a,1)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` datetime AS (makedate(a,1)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2001,default);
+select * from t1;
+a	b
+2001	2001-01-01 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# MAKETIME()
+set sql_warnings = 1;
+create table t1 (a int, b time as (maketime(a,1,3)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` time AS (maketime(a,1,3)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+select * from t1;
+a	b
+12	12:01:03
+drop table t1;
+set sql_warnings = 0;
+# MICROSECOND()
+set sql_warnings = 1;
+create table t1 (a datetime, b long as (microsecond(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` mediumtext AS (microsecond(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 12:00:00.123456',default);
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 12:00:00	0
+2009-12-31 23:59:59	0
+drop table t1;
+set sql_warnings = 0;
+# MINUTE()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (minute(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (minute(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 23:59:59	59
+drop table t1;
+set sql_warnings = 0;
+# MONTH()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (month(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (month(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 23:59:59	12
+drop table t1;
+set sql_warnings = 0;
+# MONTHNAME()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(16) as (monthname(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(16) AS (monthname(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 23:59:59	December
+drop table t1;
+set sql_warnings = 0;
+# PERIOD_ADD()
+set sql_warnings = 1;
+create table t1 (a int, b int as (period_add(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (period_add(a,2)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (200801,default);
+select * from t1;
+a	b
+200801	200803
+drop table t1;
+set sql_warnings = 0;
+# PERIOD_DIFF()
+set sql_warnings = 1;
+create table t1 (a int, b int, c int as (period_diff(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) AS (period_diff(a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (200802,200703,default);
+select * from t1;
+a	b	c
+200802	200703	11
+drop table t1;
+set sql_warnings = 0;
+# QUARTER()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (quarter(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (quarter(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	3
+drop table t1;
+set sql_warnings = 0;
+# SEC_TO_TIME()
+set sql_warnings = 1;
+create table t1 (a long, b time as (sec_to_time(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` mediumtext,
+  `b` time AS (sec_to_time(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (2378,default);
+select * from t1;
+a	b
+2378	00:39:38
+drop table t1;
+set sql_warnings = 0;
+# SECOND()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (second(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (second(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('10:05:03',default);
+select * from t1;
+a	b
+2010-05-03 00:00:00	0
+drop table t1;
+set sql_warnings = 0;
+# STR_TO_DATE()
+set sql_warnings = 1;
+create table t1 (a varchar(64), b datetime as (str_to_date(a,'%m/%d/%Y')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(64) DEFAULT NULL,
+  `b` datetime AS (str_to_date(a,'%m/%d/%Y')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('04/30/2004',default);
+select * from t1;
+a	b
+04/30/2004	2004-04-30 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# SUBDATE()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (subdate(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (subdate(a,interval 1 month)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-07-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# SUBTIME()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (subtime(a,'02:00:00')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (subtime(a,'02:00:00')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-08-30 22:00:00
+drop table t1;
+set sql_warnings = 0;
+# TIME_FORMAT()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(32) as (time_format(a,'%r')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(32) AS (time_format(a,'%r')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31 02:03:04',default);
+select * from t1;
+a	b
+2008-08-31 02:03:04	02:03:04 AM
+drop table t1;
+set sql_warnings = 0;
+# TIME_TO_SEC()
+set sql_warnings = 1;
+create table t1 (a time, b long as (time_to_sec(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` time DEFAULT NULL,
+  `b` mediumtext AS (time_to_sec(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('22:23:00',default);
+select * from t1;
+a	b
+22:23:00	80580
+drop table t1;
+set sql_warnings = 0;
+# TIME()
+set sql_warnings = 1;
+create table t1 (a datetime, b time as (time(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` time AS (time(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31 02:03:04',default);
+select * from t1;
+a	b
+2008-08-31 02:03:04	02:03:04
+drop table t1;
+set sql_warnings = 0;
+# TIMEDIFF()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime, c long as (timediff(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime DEFAULT NULL,
+  `c` mediumtext AS (timediff(a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',default);
+select * from t1;
+a	b	c
+2008-12-31 23:59:59	2008-12-30 01:01:01	46:58:58
+drop table t1;
+set sql_warnings = 0;
+# TIMESTAMP()
+set sql_warnings = 1;
+create table t1 (a datetime, b timestamp as (timestamp(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` timestamp AS (timestamp(a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-12-31',default);
+select * from t1;
+a	b
+2008-12-31 00:00:00	2008-12-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# TIMESTAMPADD()
+set sql_warnings = 1;
+create table t1 (a datetime, b timestamp as (timestampadd(minute,1,a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` timestamp AS (timestampadd(minute,1,a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2003-01-02',default);
+select * from t1;
+a	b
+2003-01-02 00:00:00	2003-01-02 00:01:00
+drop table t1;
+set sql_warnings = 0;
+# TIMESTAMPDIFF()
+set sql_warnings = 1;
+create table t1 (a timestamp, b timestamp, c long as (timestampdiff(MONTH, a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `b` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `c` mediumtext AS (timestampdiff(MONTH, a,b)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2003-02-01','2003-05-01',default);
+select * from t1;
+a	b	c
+2003-02-01 00:00:00	2003-05-01 00:00:00	3
+drop table t1;
+set sql_warnings = 0;
+# TO_DAYS()
+set sql_warnings = 1;
+create table t1 (a datetime, b long as (to_days(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` mediumtext AS (to_days(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2007-10-07',default);
+select * from t1;
+a	b
+2007-10-07 00:00:00	733321
+drop table t1;
+set sql_warnings = 0;
+# WEEK()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (week(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (week(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	35
+drop table t1;
+set sql_warnings = 0;
+# WEEKDAY()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (weekday(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (weekday(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	0
+drop table t1;
+set sql_warnings = 0;
+# WEEKOFYEAR()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (weekofyear(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (weekofyear(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	36
+drop table t1;
+set sql_warnings = 0;
+# YEAR()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (year(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (year(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	2008
+drop table t1;
+set sql_warnings = 0;
+# YEARWEEK()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (yearweek(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (yearweek(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	200835
+drop table t1;
+set sql_warnings = 0;
+#
+# FULL TEXT SEARCH FUNCTIONS
+#
+# None.
+#
+# CAST FUNCTIONS AND OPERATORS
+#
+# CAST()
+set sql_warnings = 1;
+create table t1 (a int, b long as (cast(a as unsigned)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` mediumtext AS (cast(a as unsigned)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (-1,default);
+select * from t1;
+a	b
+1	1
+-1	18446744073709551615
+drop table t1;
+set sql_warnings = 0;
+# Convert()
+set sql_warnings = 1;
+create table t1 (a int, b long as (convert(a,unsigned)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` mediumtext AS (convert(a,unsigned)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (-1,default);
+select * from t1;
+a	b
+1	1
+-1	18446744073709551615
+drop table t1;
+set sql_warnings = 0;
+#
+# XML FUNCTIONS
+#
+# None.
+#
+# OTHER FUNCTIONS
+#
+# AES_DECRYPT(), AES_ENCRYPT()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (aes_encrypt(aes_decrypt(a,'adf'),'adf')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (aes_encrypt(aes_decrypt(a,'adf'),'adf')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	NULL
+drop table t1;
+set sql_warnings = 0;
+# BIT_COUNT()
+set sql_warnings = 1;
+create table t1 (a int, b int as (bit_count(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (bit_count(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (5,default);
+select * from t1;
+a	b
+5	2
+drop table t1;
+set sql_warnings = 0;
+# CHARSET()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (charset(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (charset(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	latin1
+drop table t1;
+set sql_warnings = 0;
+# COERCIBILITY()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b int as (coercibility(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` int(11) AS (coercibility(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	2
+drop table t1;
+set sql_warnings = 0;
+# COLLATION()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (collation(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (collation(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	latin1_swedish_ci
+drop table t1;
+set sql_warnings = 0;
+# COMPRESS(), UNCOMPRESS()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (uncompress(compress(a))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (uncompress(compress(a))) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MySQL
+drop table t1;
+set sql_warnings = 0;
+# ENCODE(), DECODE()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (decode(encode(a,'abc'),'abc')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (decode(encode(a,'abc'),'abc')) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MySQL
+drop table t1;
+set sql_warnings = 0;
+# DEFAULT()
+set sql_warnings = 1;
+create table t1 (a varchar(1024) default 'aaa', b varchar(1024) as (ifnull(a,default(a))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT 'aaa',
+  `b` varchar(1024) AS (ifnull(a,default(a))) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('any value',default);
+select * from t1;
+a	b
+any value	any value
+drop table t1;
+set sql_warnings = 0;
+# INET_ATON(), INET_NTOA()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (inet_ntoa(inet_aton(a))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (inet_ntoa(inet_aton(a))) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('127.0.0.1',default);
+select * from t1;
+a	b
+127.0.0.1	127.0.0.1
+drop table t1;
+set sql_warnings = 0;
+# MD5()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varbinary(32) as (md5(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varbinary(32) AS (md5(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('testing',default);
+select * from t1;
+a	b
+testing	ae2b1fca515949e5d54fb22b8ed95575
+drop table t1;
+set sql_warnings = 0;
+# OLD_PASSWORD()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (old_password(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (old_password(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('badpwd',default);
+select * from t1;
+a	b
+badpwd	7f84554057dd964b
+drop table t1;
+set sql_warnings = 0;
+# PASSWORD()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (password(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (password(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('badpwd',default);
+select * from t1;
+a	b
+badpwd	*AAB3E285149C0135D51A520E1940DD3263DC008C
+drop table t1;
+set sql_warnings = 0;
+# SHA1()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (sha1(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (sha1(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	a9993e364706816aba3e25717850c26c9cd0d89d
+drop table t1;
+set sql_warnings = 0;
+# SHA()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (sha(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (sha(a)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	a9993e364706816aba3e25717850c26c9cd0d89d
+drop table t1;
+set sql_warnings = 0;
+# UNCOMPRESSED_LENGTH()
+set sql_warnings = 1;
+create table t1 (a char, b varchar(1024) as (uncompressed_length(compress(repeat(a,30)))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` char(1) DEFAULT NULL,
+  `b` varchar(1024) AS (uncompressed_length(compress(repeat(a,30)))) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values ('a',default);
+select * from t1;
+a	b
+a	30
+drop table t1;
+set sql_warnings = 0;

=== added file 'mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,2942 @@
+SET @@session.storage_engine = 'MyISAM';
+#
+# NUMERIC FUNCTIONS
+#
+# ABS()
+set sql_warnings = 1;
+create table t1 (a int, b int as (abs(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (abs(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-1, default);
+select * from t1;
+a	b
+-1	1
+drop table t1;
+set sql_warnings = 0;
+# ACOS()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(acos(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(acos(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1, default);
+insert into t1 values (1.0001,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+1	0
+1.0001	NULL
+0	1.570796
+drop table t1;
+set sql_warnings = 0;
+# ASIN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(asin(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(asin(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (0.2, default);
+insert into t1 values (1.0001,default);
+select * from t1;
+a	b
+0.2	0.201358
+1.0001	NULL
+drop table t1;
+set sql_warnings = 0;
+#ATAN
+set sql_warnings = 1;
+create table t1 (a double, b double, c double as (format(atan(a,b),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` double AS (format(atan(a,b),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-2,2,default);
+insert into t1 values (format(PI(),6),0,default);
+select * from t1;
+a	b	c
+-2	2	-0.785398
+3.141593	0	1.570796
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a double, c double as (format(atan(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `c` double AS (format(atan(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-2,default);
+insert into t1 values (format(PI(),6),default);
+select * from t1;
+a	c
+-2	-1.107149
+3.141593	1.262627
+drop table t1;
+set sql_warnings = 0;
+# ATAN2
+set sql_warnings = 1;
+create table t1 (a double, b double, c double as (format(atan2(a,b),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` double AS (format(atan2(a,b),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-2,2,default);
+insert into t1 values (format(PI(),6),0,default);
+select * from t1;
+a	b	c
+-2	2	-0.785398
+3.141593	0	1.570796
+drop table t1;
+set sql_warnings = 0;
+# CEIL()
+set sql_warnings = 1;
+create table t1 (a double, b int as (ceil(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` int(11) AS (ceil(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1.23,default);
+insert into t1 values (-1.23,default);
+select * from t1;
+a	b
+1.23	2
+-1.23	-1
+drop table t1;
+set sql_warnings = 0;
+# CONV()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b int, c int, d varchar(10) as (conv(a,b,c)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` varchar(10) AS (conv(a,b,c)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('a',16,2,default);
+insert into t1 values ('6e',18,8,default);
+insert into t1 values (-17,10,-18,default);
+insert into t1 values (10+'10'+'10'+0xa,10,10,default);
+select * from t1;
+a	b	c	d
+a	16	2	1010
+6e	18	8	172
+-17	10	-18	-H
+40	10	10	40
+drop table t1;
+set sql_warnings = 0;
+# COS()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(cos(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(cos(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (format(PI(),6),default);
+select * from t1;
+a	b
+3.141593	-1
+drop table t1;
+set sql_warnings = 0;
+# COT()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(cot(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(cot(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+12	-1.572673
+0	NULL
+drop table t1;
+set sql_warnings = 0;
+# CRC32()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (crc32(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (crc32(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+insert into t1 values ('mysql',default);
+select * from t1;
+a	b
+MySQL	3259397556
+mysql	2501908538
+drop table t1;
+set sql_warnings = 0;
+# DEGREES()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(degrees(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(degrees(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (format(PI(),6),default);
+insert into t1 values (format(PI()/2,6),default);
+select * from t1;
+a	b
+3.141593	180.00002
+1.570796	89.999981
+drop table t1;
+set sql_warnings = 0;
+# /
+set sql_warnings = 1;
+create table t1 (a double, b double as (a/2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (a/2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+2	1
+drop table t1;
+set sql_warnings = 0;
+# EXP()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(exp(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(exp(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (-2,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+2	7.389056
+-2	0.135335
+0	1
+drop table t1;
+set sql_warnings = 0;
+# FLOOR()
+set sql_warnings = 1;
+create table t1 (a double, b long as (floor(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` mediumtext AS (floor(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1.23,default);
+insert into t1 values (-1.23,default);
+select * from t1;
+a	b
+1.23	1
+-1.23	-2
+drop table t1;
+set sql_warnings = 0;
+# LN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(ln(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(ln(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (-2,default);
+select * from t1;
+a	b
+2	0.693147
+-2	NULL
+drop table t1;
+set sql_warnings = 0;
+# LOG()
+set sql_warnings = 1;
+create table t1 (a double, b double, c double as (format(log(a,b),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` double AS (format(log(a,b),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2,65536,default);
+insert into t1 values (10,100,default);
+insert into t1 values (1,100,default);
+select * from t1;
+a	b	c
+2	65536	16
+10	100	2
+1	100	NULL
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(log(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(log(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (-2,default);
+select * from t1;
+a	b
+2	0.693147
+-2	NULL
+drop table t1;
+set sql_warnings = 0;
+# LOG2()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(log2(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(log2(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (65536,default);
+insert into t1 values (-100,default);
+select * from t1;
+a	b
+65536	16
+-100	NULL
+drop table t1;
+set sql_warnings = 0;
+# LOG10()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(log10(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(log10(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+insert into t1 values (100,default);
+insert into t1 values (-100,default);
+select * from t1;
+a	b
+2	0.30103
+100	2
+-100	NULL
+drop table t1;
+set sql_warnings = 0;
+# -
+set sql_warnings = 1;
+create table t1 (a double, b double as (a-1));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (a-1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2,default);
+select * from t1;
+a	b
+2	1
+drop table t1;
+set sql_warnings = 0;
+# MOD()
+set sql_warnings = 1;
+create table t1 (a int, b int as (mod(a,10)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (mod(a,10)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (11,default);
+select * from t1;
+a	b
+1	1
+11	1
+drop table t1;
+set sql_warnings = 0;
+# %
+set sql_warnings = 1;
+create table t1 (a int, b int as (a % 10));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a % 10) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (11,default);
+select * from t1;
+a	b
+1	1
+11	1
+drop table t1;
+set sql_warnings = 0;
+# OCT()
+set sql_warnings = 1;
+create table t1 (a double, b varchar(10) as (oct(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` varchar(10) AS (oct(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+select * from t1;
+a	b
+12	14
+drop table t1;
+set sql_warnings = 0;
+# PI()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(PI()*a*a,6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(PI()*a*a,6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	3.141593
+drop table t1;
+set sql_warnings = 0;
+# +
+set sql_warnings = 1;
+create table t1 (a int, b int as (a+1));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a+1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+select * from t1;
+a	b
+1	2
+drop table t1;
+set sql_warnings = 0;
+# POW, POWER
+set sql_warnings = 1;
+create table t1 (a int, b int as (pow(a,2)), c int as (power(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (pow(a,2)) VIRTUAL,
+  `c` int(11) AS (power(a,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default,default);
+insert into t1 values (2,default,default);
+select * from t1;
+a	b	c
+1	1	1
+2	4	4
+drop table t1;
+set sql_warnings = 0;
+# RADIANS()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(radians(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(radians(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (90,default);
+select * from t1;
+a	b
+90	1.570796
+drop table t1;
+set sql_warnings = 0;
+# ROUND()
+set sql_warnings = 1;
+create table t1 (a double, b int as (round(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` int(11) AS (round(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-1.23,default);
+insert into t1 values (-1.58,default);
+insert into t1 values (1.58,default);
+select * from t1;
+a	b
+-1.23	-1
+-1.58	-2
+1.58	2
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a double, b double, c int as (round(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double DEFAULT NULL,
+  `c` int(11) AS (round(a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1.298,1,default);
+insert into t1 values (1.298,0,default);
+insert into t1 values (23.298,-1,default);
+select * from t1;
+a	b	c
+1.298	1	1
+1.298	0	1
+23.298	-1	20
+drop table t1;
+set sql_warnings = 0;
+# SIGN()
+set sql_warnings = 1;
+create table t1 (a double, b int as (sign(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` int(11) AS (sign(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-32,default);
+insert into t1 values (0,default);
+insert into t1 values (234,default);
+select * from t1;
+a	b
+-32	-1
+0	0
+234	1
+drop table t1;
+set sql_warnings = 0;
+# SIN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(sin(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(sin(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (format(PI()/2,6),default);
+select * from t1;
+a	b
+1.570796	1
+drop table t1;
+set sql_warnings = 0;
+# SQRT()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(sqrt(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(sqrt(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (4,default);
+insert into t1 values (20,default);
+insert into t1 values (-16,default);
+select * from t1;
+a	b
+4	2
+20	4.472136
+-16	NULL
+drop table t1;
+set sql_warnings = 0;
+# TAN()
+set sql_warnings = 1;
+create table t1 (a double, b double as (format(tan(a),6)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (format(tan(a),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (format(PI(),6),default);
+insert into t1 values (format(PI()+1,6),default);
+select * from t1;
+a	b
+3.141593	0
+4.141593	1.557409
+drop table t1;
+set sql_warnings = 0;
+# *
+set sql_warnings = 1;
+create table t1 (a double, b double as (a*3));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (a*3) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (0,default);
+insert into t1 values (1,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+0	0
+1	3
+2	6
+drop table t1;
+set sql_warnings = 0;
+# TRUNCATE()
+set sql_warnings = 1;
+create table t1 (a double, b double as (truncate(a,4)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (truncate(a,4)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1.223,default);
+insert into t1 values (1.999,default);
+insert into t1 values (1.999,default);
+insert into t1 values (122,default);
+select * from t1;
+a	b
+1.223	1.223
+1.999	1.999
+1.999	1.999
+122	122
+drop table t1;
+set sql_warnings = 0;
+# Unary -
+set sql_warnings = 1;
+create table t1 (a double, b double as (-a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` double AS (-a) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (-1,default);
+select * from t1;
+a	b
+1	-1
+-1	1
+drop table t1;
+set sql_warnings = 0;
+#
+# STRING FUNCTIONS
+#
+# ASCII()
+set sql_warnings = 1;
+create table t1 (a char(2), b int as (ascii(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` char(2) DEFAULT NULL,
+  `b` int(11) AS (ascii(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2',default);
+insert into t1 values (2,default);
+insert into t1 values ('dx',default);
+select * from t1;
+a	b
+2	50
+2	50
+dx	100
+drop table t1;
+set sql_warnings = 0;
+# BIN()
+set sql_warnings = 1;
+create table t1 (a int, b varchar(10) as (bin(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` varchar(10) AS (bin(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+select * from t1;
+a	b
+12	1100
+drop table t1;
+set sql_warnings = 0;
+# BIT_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (bit_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (bit_length(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	32
+drop table t1;
+set sql_warnings = 0;
+# CHAR_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (char_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (char_length(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# CHAR()
+set sql_warnings = 1;
+create table t1 (a int, b int, c varbinary(10) as (char(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` varbinary(10) AS (char(a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (77,121,default);
+select * from t1;
+a	b	c
+77	121	My
+drop table t1;
+set sql_warnings = 0;
+# CHARACTER_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (character_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (character_length(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# CONCAT_WS()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat_ws(',',a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(20) AS (concat_ws(',',a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('value1','value2',default);
+select * from t1;
+a	b	c
+value1	value2	value1,value2
+drop table t1;
+set sql_warnings = 0;
+# CONCAT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(20) as (concat(a,',',b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(20) AS (concat(a,',',b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('value1','value2',default);
+select * from t1;
+a	b	c
+value1	value2	value1,value2
+drop table t1;
+set sql_warnings = 0;
+# ELT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int, d varchar(10) as (elt(c,a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` varchar(10) AS (elt(c,a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('value1','value2',1,default);
+insert into t1 values ('value1','value2',2,default);
+select * from t1;
+a	b	c	d
+value1	value2	1	value1
+value1	value2	2	value2
+drop table t1;
+set sql_warnings = 0;
+# EXPORT_SET()
+set sql_warnings = 1;
+create table t1 (a int, b varchar(10) as (export_set(a,'1','0','',10)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` varchar(10) AS (export_set(a,'1','0','',10)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (6,default);
+select * from t1;
+a	b
+6	0110000000
+drop table t1;
+set sql_warnings = 0;
+# FIELD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int as (field('aa',a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) AS (field('aa',a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('aa','bb',default);
+insert into t1 values ('bb','aa',default);
+select * from t1;
+a	b	c
+aa	bb	1
+bb	aa	2
+drop table t1;
+set sql_warnings = 0;
+# FIND_IN_SET()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int as (find_in_set(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) AS (find_in_set(a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('aa','aa,bb,cc',default);
+insert into t1 values ('aa','bb,aa,cc',default);
+select * from t1;
+a	b	c
+aa	aa,bb,cc	1
+aa	bb,aa,cc	2
+drop table t1;
+set sql_warnings = 0;
+# FORMAT()
+set sql_warnings = 1;
+create table t1 (a double, b varchar(20) as (format(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` double DEFAULT NULL,
+  `b` varchar(20) AS (format(a,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (12332.123456,default);
+select * from t1;
+a	b
+12332.123456	12,332.12
+drop table t1;
+set sql_warnings = 0;
+# HEX()
+set sql_warnings = 1;
+create table t1 (a int, b varchar(10) as (hex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` varchar(10) AS (hex(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (17,default);
+select * from t1;
+a	b
+17	11
+drop table t1;
+set sql_warnings = 0;
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (hex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (hex(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	616263
+drop table t1;
+set sql_warnings = 0;
+# INSERT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(20) as (insert(a,length(a),length(b),b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(20) AS (insert(a,length(a),length(b),b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('start,','end',default);
+select * from t1;
+a	b	c
+start,	end	startend
+drop table t1;
+set sql_warnings = 0;
+# INSTR()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int as (instr(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) AS (instr(a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar,','bar',default);
+insert into t1 values ('xbar,','foobar',default);
+select * from t1;
+a	b	c
+foobarbar,	bar	4
+xbar,	foobar	0
+drop table t1;
+set sql_warnings = 0;
+# LCASE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (lcase(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (lcase(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	mysql
+drop table t1;
+set sql_warnings = 0;
+# LEFT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(5) as (left(a,5)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(5) AS (left(a,5)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	fooba
+drop table t1;
+set sql_warnings = 0;
+# LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b int as (length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` int(11) AS (length(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# LIKE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a like 'H%o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a like 'H%o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+Hello	1
+MySQL	0
+drop table t1;
+set sql_warnings = 0;
+# LOCATE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (locate('bar',a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (locate('bar',a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	4
+drop table t1;
+set sql_warnings = 0;
+# LOWER()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (lower(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (lower(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	mysql
+drop table t1;
+set sql_warnings = 0;
+# LPAD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (lpad(a,4,' ')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (lpad(a,4,' ')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+insert into t1 values ('M',default);
+select * from t1;
+a	b
+MySQL	MySQ
+M	   M
+drop table t1;
+set sql_warnings = 0;
+# LTRIM()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (ltrim(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (ltrim(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('  MySQL',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+  MySQL	MySQL
+MySQL	MySQL
+drop table t1;
+set sql_warnings = 0;
+# MAKE_SET()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c int, d varchar(30) as (make_set(c,a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` varchar(30) AS (make_set(c,a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',1,default);
+insert into t1 values ('a','b',3,default);
+select * from t1;
+a	b	c	d
+a	b	1	a
+a	b	3	a,b
+drop table t1;
+set sql_warnings = 0;
+# MID()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (mid(a,1,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (mid(a,1,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	fo
+drop table t1;
+set sql_warnings = 0;
+# NOT LIKE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a not like 'H%o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a not like 'H%o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+Hello	0
+MySQL	1
+drop table t1;
+set sql_warnings = 0;
+# NOT REGEXP
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a not regexp 'H.+o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a not regexp 'H.+o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('hello',default);
+select * from t1;
+a	b
+Hello	0
+hello	0
+drop table t1;
+set sql_warnings = 0;
+# OCTET_LENGTH()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b int as (octet_length(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` int(11) AS (octet_length(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('text',default);
+select * from t1;
+a	b
+text	4
+drop table t1;
+set sql_warnings = 0;
+# ORD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b long as (ord(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` mediumtext AS (ord(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2',default);
+select * from t1;
+a	b
+2	50
+drop table t1;
+set sql_warnings = 0;
+# POSITION()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (position('bar' in a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (position('bar' in a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	4
+drop table t1;
+set sql_warnings = 0;
+# QUOTE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (quote(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (quote(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Don\'t',default);
+select * from t1;
+a	b
+Don't	'Don\'t'
+drop table t1;
+set sql_warnings = 0;
+# REGEXP()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a regexp 'H.+o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a regexp 'H.+o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('hello',default);
+select * from t1;
+a	b
+Hello	1
+hello	1
+drop table t1;
+set sql_warnings = 0;
+# REPEAT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(30) as (repeat(a,3)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(30) AS (repeat(a,3)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MySQLMySQLMySQL
+drop table t1;
+set sql_warnings = 0;
+# REPLACE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(30) as (replace(a,'aa','bb')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(30) AS (replace(a,'aa','bb')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('maa',default);
+select * from t1;
+a	b
+maa	mbb
+drop table t1;
+set sql_warnings = 0;
+# REVERSE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(30) as (reverse(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(30) AS (reverse(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('maa',default);
+select * from t1;
+a	b
+maa	aam
+drop table t1;
+set sql_warnings = 0;
+# RIGHT()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (right(a,4)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (right(a,4)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('foobarbar',default);
+select * from t1;
+a	b
+foobarbar	rbar
+drop table t1;
+set sql_warnings = 0;
+# RLIKE()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b bool as (a rlike 'H.+o'));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` tinyint(1) AS (a rlike 'H.+o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+Hello	1
+MySQL	0
+drop table t1;
+set sql_warnings = 0;
+# RPAD()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (rpad(a,4,'??')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (rpad(a,4,'??')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('He',default);
+select * from t1;
+a	b
+He	He??
+drop table t1;
+set sql_warnings = 0;
+# RTRIM();
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (rtrim(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (rtrim(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello  ',default);
+select * from t1;
+a	b
+Hello  	Hello
+drop table t1;
+set sql_warnings = 0;
+# SOUNDEX()
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(20) as (soundex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(20) AS (soundex(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+select * from t1;
+a	b
+Hello	H400
+drop table t1;
+set sql_warnings = 0;
+# SOUNDS LIKE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a sounds like b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a sounds like b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello','Hello',default);
+insert into t1 values ('Hello','MySQL',default);
+insert into t1 values ('Hello','hello',default);
+select * from t1;
+a	b	c
+Hello	Hello	1
+Hello	MySQL	0
+Hello	hello	1
+drop table t1;
+set sql_warnings = 0;
+# SPACE()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (concat(a,space(5))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (concat(a,space(5))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello', default);
+select * from t1;
+a	b
+Hello	Hello     
+drop table t1;
+set sql_warnings = 0;
+# STRCMP()
+set sql_warnings = 1;
+create table t1 (a varchar(9), b varchar(9), c tinyint(1) as (strcmp(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(9) DEFAULT NULL,
+  `b` varchar(9) DEFAULT NULL,
+  `c` tinyint(1) AS (strcmp(a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello','Hello', default);
+insert into t1 values ('Hello','Hello1', default);
+select * from t1;
+a	b	c
+Hello	Hello	0
+Hello	Hello1	-1
+drop table t1;
+set sql_warnings = 0;
+# SUBSTR()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (substr(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (substr(a,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+select * from t1;
+a	b
+Hello	ello
+drop table t1;
+set sql_warnings = 0;
+# SUBSTRING_INDEX()
+set sql_warnings = 1;
+create table t1 (a varchar(15), b varchar(10) as (substring_index(a,'.',2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(15) DEFAULT NULL,
+  `b` varchar(10) AS (substring_index(a,'.',2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('www.mysql.com',default);
+select * from t1;
+a	b
+www.mysql.com	www.mysql
+drop table t1;
+set sql_warnings = 0;
+# SUBSTRING()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (substring(a from 2 for 2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (substring(a from 2 for 2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('Hello',default);
+select * from t1;
+a	b
+Hello	el
+drop table t1;
+set sql_warnings = 0;
+# TRIM()
+set sql_warnings = 1;
+create table t1 (a varchar(15), b varchar(10) as (trim(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(15) DEFAULT NULL,
+  `b` varchar(10) AS (trim(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (' aa ',default);
+select * from t1;
+a	b
+ aa 	aa
+drop table t1;
+set sql_warnings = 0;
+# UCASE()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (ucase(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (ucase(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MYSQL
+drop table t1;
+set sql_warnings = 0;
+# UNHEX()
+set sql_warnings = 1;
+create table t1 (a varchar(15), b varchar(10) as (unhex(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(15) DEFAULT NULL,
+  `b` varchar(10) AS (unhex(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('4D7953514C',default);
+select * from t1;
+a	b
+4D7953514C	MySQL
+drop table t1;
+set sql_warnings = 0;
+# UPPER()
+set sql_warnings = 1;
+create table t1 (a varchar(5), b varchar(10) as (upper(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(5) DEFAULT NULL,
+  `b` varchar(10) AS (upper(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MYSQL
+drop table t1;
+set sql_warnings = 0;
+#
+# CONTROL FLOW FUNCTIONS
+#
+# CASE
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(16) as (case a when NULL then 'asd' when 'b' then 'B' else a end));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(16) AS (case a when NULL then 'asd' when 'b' then 'B' else a end) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (NULL,default);
+insert into t1 values ('b',default);
+insert into t1 values ('c',default);
+select * from t1;
+a	b
+NULL	NULL
+b	B
+c	c
+drop table t1;
+set sql_warnings = 0;
+# IF
+set sql_warnings = 1;
+create table t1 (a int, b int, c int as (if(a=1,a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) AS (if(a=1,a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,2,default);
+insert into t1 values (3,4,default);
+select * from t1;
+a	b	c
+1	2	1
+3	4	4
+drop table t1;
+set sql_warnings = 0;
+# IFNULL
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c varchar(10) as (ifnull(a,'DEFAULT')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` varchar(10) AS (ifnull(a,'DEFAULT')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (NULL,'adf',default);
+insert into t1 values ('a','adf',default);
+select * from t1;
+a	b	c
+NULL	adf	DEFAULT
+a	adf	a
+drop table t1;
+set sql_warnings = 0;
+# NULLIF
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10) as (nullif(a,'DEFAULT')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) AS (nullif(a,'DEFAULT')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('DEFAULT',default);
+insert into t1 values ('a',default);
+select * from t1;
+a	b
+DEFAULT	NULL
+a	a
+drop table t1;
+set sql_warnings = 0;
+#
+# OPERATORS
+#
+# AND, && 
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a>0 && a<2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a>0 && a<2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-1,default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+-1	0
+1	1
+drop table t1;
+set sql_warnings = 0;
+# BETWEEN ... AND ... 
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a between 0 and 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-1,default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+-1	0
+1	1
+drop table t1;
+set sql_warnings = 0;
+# BINARY
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varbinary(10) as (binary a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varbinary(10) AS (binary a) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('11',default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+11	11
+1	1
+drop table t1;
+set sql_warnings = 0;
+# &
+set sql_warnings = 1;
+create table t1 (a int, b int as (a & 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a & 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (0,default);
+select * from t1;
+a	b
+1	1
+0	0
+drop table t1;
+set sql_warnings = 0;
+# ~
+set sql_warnings = 1;
+create table t1 (a int, b int as (~a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (~a) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+Warnings:
+Warning	1264	Out of range value for column 'b' at row 1
+select * from t1;
+a	b
+1	2147483647
+drop table t1;
+set sql_warnings = 0;
+# |
+set sql_warnings = 1;
+create table t1 (a int, b int as (a | 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a | 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (0,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	5
+0	5
+2	7
+drop table t1;
+set sql_warnings = 0;
+# ^
+set sql_warnings = 1;
+create table t1 (a int, b int as (a ^ 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a ^ 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (0,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+1	4
+0	5
+2	7
+drop table t1;
+set sql_warnings = 0;
+# DIV
+set sql_warnings = 1;
+create table t1 (a int, b int as (a div 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a div 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (7,default);
+select * from t1;
+a	b
+1	0
+7	1
+drop table t1;
+set sql_warnings = 0;
+# <=>
+set sql_warnings = 1;
+create table t1 (a int, b int, c bool as (a <=> b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` tinyint(1) AS (a <=> b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,1,default);
+insert into t1 values (NULL,NULL,default);
+insert into t1 values (1,NULL,default);
+select * from t1;
+a	b	c
+1	1	1
+NULL	NULL	1
+1	NULL	0
+drop table t1;
+set sql_warnings = 0;
+# =
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a=b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a=b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',default);
+insert into t1 values ('a','a',default);
+select * from t1;
+a	b	c
+a	b	0
+a	a	1
+drop table t1;
+set sql_warnings = 0;
+# >=
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a >= b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a >= b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',default);
+insert into t1 values ('a','a',default);
+select * from t1;
+a	b	c
+a	b	0
+a	a	1
+drop table t1;
+set sql_warnings = 0;
+# >
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a > b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a > b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('a','b',default);
+insert into t1 values ('a','a',default);
+select * from t1;
+a	b	c
+a	b	0
+a	a	0
+drop table t1;
+set sql_warnings = 0;
+# IS NOT NULL
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a is not null));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a is not null) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (NULL,default);
+select * from t1;
+a	b
+1	1
+NULL	0
+drop table t1;
+set sql_warnings = 0;
+# IS NULL
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a is null));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a is null) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (NULL,default);
+select * from t1;
+a	b
+1	0
+NULL	1
+drop table t1;
+set sql_warnings = 0;
+# <<
+set sql_warnings = 1;
+create table t1 (a int, b int as (a << 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a << 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (3,default);
+select * from t1;
+a	b
+1	4
+3	12
+drop table t1;
+set sql_warnings = 0;
+# <=
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a <= b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a <= b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	0
+b	b	1
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# <
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a < b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a < b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	0
+b	b	0
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# NOT BETWEEN ... AND ...
+set sql_warnings = 1;
+create table t1 (a int, b bool as (a not between 0 and 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` tinyint(1) AS (a not between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (-1,default);
+insert into t1 values (1,default);
+select * from t1;
+a	b
+-1	1
+1	0
+drop table t1;
+set sql_warnings = 0;
+# <>
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a <> b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a <> b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	1
+b	b	0
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# !=
+set sql_warnings = 1;
+create table t1 (a varchar(10), b varchar(10), c bool as (a != b));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(10) DEFAULT NULL,
+  `b` varchar(10) DEFAULT NULL,
+  `c` tinyint(1) AS (a != b) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('b','a',default);
+insert into t1 values ('b','b',default);
+insert into t1 values ('b','c',default);
+select * from t1;
+a	b	c
+b	a	1
+b	b	0
+b	c	1
+drop table t1;
+set sql_warnings = 0;
+# ||, OR
+set sql_warnings = 1;
+create table t1 (a int, b int as (a>5 || a<3));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a>5 || a<3) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (4,default);
+select * from t1;
+a	b
+1	1
+4	0
+drop table t1;
+set sql_warnings = 0;
+# >>
+set sql_warnings = 1;
+create table t1 (a int, b int as (a >> 2));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a >> 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (8,default);
+insert into t1 values (3,default);
+select * from t1;
+a	b
+8	2
+3	0
+drop table t1;
+set sql_warnings = 0;
+# XOR
+set sql_warnings = 1;
+create table t1 (a int, b int as (a xor 5));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a xor 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (0,default);
+insert into t1 values (1,default);
+insert into t1 values (2,default);
+select * from t1;
+a	b
+0	1
+1	0
+2	0
+drop table t1;
+set sql_warnings = 0;
+#
+# DATE AND TIME FUNCTIONS
+#
+# ADDDATE()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (adddate(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (adddate(a,interval 1 month)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-09-30 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# ADDTIME()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (addtime(a,'02:00:00')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (addtime(a,'02:00:00')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-08-31 02:00:00
+drop table t1;
+set sql_warnings = 0;
+# CONVERT_TZ()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (convert_tz(a,'MET','UTC')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (convert_tz(a,'MET','UTC')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-08-30 22:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATE_ADD()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (date_add(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (date_add(a,interval 1 month)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-09-30 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATE_FORMAT()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(64) as (date_format(a,'%W %M %D')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(64) AS (date_format(a,'%W %M %D')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	Sunday August 31st
+drop table t1;
+set sql_warnings = 0;
+# DATE_SUB()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (date_sub(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (date_sub(a,interval 1 month)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-07-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATE()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (date(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (date(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31 02:00:00',default);
+select * from t1;
+a	b
+2008-08-31 02:00:00	2008-08-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# DATEDIFF()
+set sql_warnings = 1;
+create table t1 (a datetime, b long as (datediff(a,'2000-01-01')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` mediumtext AS (datediff(a,'2000-01-01')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	3165
+drop table t1;
+set sql_warnings = 0;
+# DAY()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (day(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (day(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	31
+drop table t1;
+set sql_warnings = 0;
+# DAYNAME()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(10) as (dayname(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(10) AS (dayname(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	Sunday
+drop table t1;
+set sql_warnings = 0;
+# DAYOFMONTH()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (dayofmonth(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (dayofmonth(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	31
+drop table t1;
+set sql_warnings = 0;
+# DAYOFWEEK()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (dayofweek(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (dayofweek(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	1
+drop table t1;
+set sql_warnings = 0;
+# DAYOFYEAR()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (dayofyear(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (dayofyear(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	244
+drop table t1;
+set sql_warnings = 0;
+# EXTRACT
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (extract(year from a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (extract(year from a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008
+drop table t1;
+set sql_warnings = 0;
+# FROM_DAYS()
+set sql_warnings = 1;
+create table t1 (a long, b datetime as (from_days(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` mediumtext,
+  `b` datetime AS (from_days(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (730669,default);
+select * from t1;
+a	b
+730669	2000-07-03 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# FROM_UNIXTIME()
+set sql_warnings = 1;
+create table t1 (a long, b datetime as (from_unixtime(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` mediumtext,
+  `b` datetime AS (from_unixtime(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1196440219,default);
+select * from t1;
+a	b
+1196440219	2007-11-30 19:30:19
+drop table t1;
+set sql_warnings = 0;
+# GET_FORMAT()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(32) as (date_format(a,get_format(DATE,'EUR'))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(32) AS (date_format(a,get_format(DATE,'EUR'))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	31.08.2008
+drop table t1;
+set sql_warnings = 0;
+# HOUR()
+set sql_warnings = 1;
+create table t1 (a time, b long as (hour(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` time DEFAULT NULL,
+  `b` mediumtext AS (hour(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('10:05:03',default);
+select * from t1;
+a	b
+10:05:03	10
+drop table t1;
+set sql_warnings = 0;
+# LAST_DAY()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (last_day(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (last_day(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2003-02-05',default);
+insert into t1 values ('2003-02-32',default);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+select * from t1;
+a	b
+2003-02-05 00:00:00	2003-02-28 00:00:00
+0000-00-00 00:00:00	NULL
+drop table t1;
+set sql_warnings = 0;
+# MAKEDATE()
+set sql_warnings = 1;
+create table t1 (a int, b datetime as (makedate(a,1)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` datetime AS (makedate(a,1)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2001,default);
+select * from t1;
+a	b
+2001	2001-01-01 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# MAKETIME()
+set sql_warnings = 1;
+create table t1 (a int, b time as (maketime(a,1,3)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` time AS (maketime(a,1,3)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (12,default);
+select * from t1;
+a	b
+12	12:01:03
+drop table t1;
+set sql_warnings = 0;
+# MICROSECOND()
+set sql_warnings = 1;
+create table t1 (a datetime, b long as (microsecond(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` mediumtext AS (microsecond(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 12:00:00.123456',default);
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 12:00:00	0
+2009-12-31 23:59:59	0
+drop table t1;
+set sql_warnings = 0;
+# MINUTE()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (minute(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (minute(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 23:59:59	59
+drop table t1;
+set sql_warnings = 0;
+# MONTH()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (month(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (month(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 23:59:59	12
+drop table t1;
+set sql_warnings = 0;
+# MONTHNAME()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(16) as (monthname(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(16) AS (monthname(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2009-12-31 23:59:59.000010',default);
+select * from t1;
+a	b
+2009-12-31 23:59:59	December
+drop table t1;
+set sql_warnings = 0;
+# PERIOD_ADD()
+set sql_warnings = 1;
+create table t1 (a int, b int as (period_add(a,2)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (period_add(a,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (200801,default);
+select * from t1;
+a	b
+200801	200803
+drop table t1;
+set sql_warnings = 0;
+# PERIOD_DIFF()
+set sql_warnings = 1;
+create table t1 (a int, b int, c int as (period_diff(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) AS (period_diff(a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (200802,200703,default);
+select * from t1;
+a	b	c
+200802	200703	11
+drop table t1;
+set sql_warnings = 0;
+# QUARTER()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (quarter(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (quarter(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	3
+drop table t1;
+set sql_warnings = 0;
+# SEC_TO_TIME()
+set sql_warnings = 1;
+create table t1 (a long, b time as (sec_to_time(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` mediumtext,
+  `b` time AS (sec_to_time(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (2378,default);
+select * from t1;
+a	b
+2378	00:39:38
+drop table t1;
+set sql_warnings = 0;
+# SECOND()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (second(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (second(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('10:05:03',default);
+select * from t1;
+a	b
+2010-05-03 00:00:00	0
+drop table t1;
+set sql_warnings = 0;
+# STR_TO_DATE()
+set sql_warnings = 1;
+create table t1 (a varchar(64), b datetime as (str_to_date(a,'%m/%d/%Y')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(64) DEFAULT NULL,
+  `b` datetime AS (str_to_date(a,'%m/%d/%Y')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('04/30/2004',default);
+select * from t1;
+a	b
+04/30/2004	2004-04-30 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# SUBDATE()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (subdate(a,interval 1 month)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (subdate(a,interval 1 month)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-07-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# SUBTIME()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime as (subtime(a,'02:00:00')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime AS (subtime(a,'02:00:00')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31',default);
+select * from t1;
+a	b
+2008-08-31 00:00:00	2008-08-30 22:00:00
+drop table t1;
+set sql_warnings = 0;
+# TIME_FORMAT()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(32) as (time_format(a,'%r')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` varchar(32) AS (time_format(a,'%r')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31 02:03:04',default);
+select * from t1;
+a	b
+2008-08-31 02:03:04	02:03:04 AM
+drop table t1;
+set sql_warnings = 0;
+# TIME_TO_SEC()
+set sql_warnings = 1;
+create table t1 (a time, b long as (time_to_sec(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` time DEFAULT NULL,
+  `b` mediumtext AS (time_to_sec(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('22:23:00',default);
+select * from t1;
+a	b
+22:23:00	80580
+drop table t1;
+set sql_warnings = 0;
+# TIME()
+set sql_warnings = 1;
+create table t1 (a datetime, b time as (time(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` time AS (time(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-08-31 02:03:04',default);
+select * from t1;
+a	b
+2008-08-31 02:03:04	02:03:04
+drop table t1;
+set sql_warnings = 0;
+# TIMEDIFF()
+set sql_warnings = 1;
+create table t1 (a datetime, b datetime, c long as (timediff(a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` datetime DEFAULT NULL,
+  `c` mediumtext AS (timediff(a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',default);
+select * from t1;
+a	b	c
+2008-12-31 23:59:59	2008-12-30 01:01:01	46:58:58
+drop table t1;
+set sql_warnings = 0;
+# TIMESTAMP()
+set sql_warnings = 1;
+create table t1 (a datetime, b timestamp as (timestamp(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` timestamp AS (timestamp(a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-12-31',default);
+select * from t1;
+a	b
+2008-12-31 00:00:00	2008-12-31 00:00:00
+drop table t1;
+set sql_warnings = 0;
+# TIMESTAMPADD()
+set sql_warnings = 1;
+create table t1 (a datetime, b timestamp as (timestampadd(minute,1,a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` timestamp AS (timestampadd(minute,1,a)) VIRTUAL NULL ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2003-01-02',default);
+select * from t1;
+a	b
+2003-01-02 00:00:00	2003-01-02 00:01:00
+drop table t1;
+set sql_warnings = 0;
+# TIMESTAMPDIFF()
+set sql_warnings = 1;
+create table t1 (a timestamp, b timestamp, c long as (timestampdiff(MONTH, a,b)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `b` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `c` mediumtext AS (timestampdiff(MONTH, a,b)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2003-02-01','2003-05-01',default);
+select * from t1;
+a	b	c
+2003-02-01 00:00:00	2003-05-01 00:00:00	3
+drop table t1;
+set sql_warnings = 0;
+# TO_DAYS()
+set sql_warnings = 1;
+create table t1 (a datetime, b long as (to_days(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` mediumtext AS (to_days(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2007-10-07',default);
+select * from t1;
+a	b
+2007-10-07 00:00:00	733321
+drop table t1;
+set sql_warnings = 0;
+# WEEK()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (week(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (week(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	35
+drop table t1;
+set sql_warnings = 0;
+# WEEKDAY()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (weekday(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (weekday(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	0
+drop table t1;
+set sql_warnings = 0;
+# WEEKOFYEAR()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (weekofyear(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (weekofyear(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	36
+drop table t1;
+set sql_warnings = 0;
+# YEAR()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (year(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (year(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	2008
+drop table t1;
+set sql_warnings = 0;
+# YEARWEEK()
+set sql_warnings = 1;
+create table t1 (a datetime, b int as (yearweek(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` datetime DEFAULT NULL,
+  `b` int(11) AS (yearweek(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('2008-09-01',default);
+select * from t1;
+a	b
+2008-09-01 00:00:00	200835
+drop table t1;
+set sql_warnings = 0;
+#
+# FULL TEXT SEARCH FUNCTIONS
+#
+# None.
+#
+# CAST FUNCTIONS AND OPERATORS
+#
+# CAST()
+set sql_warnings = 1;
+create table t1 (a int, b long as (cast(a as unsigned)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` mediumtext AS (cast(a as unsigned)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (-1,default);
+select * from t1;
+a	b
+1	1
+-1	18446744073709551615
+drop table t1;
+set sql_warnings = 0;
+# Convert()
+set sql_warnings = 1;
+create table t1 (a int, b long as (convert(a,unsigned)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` mediumtext AS (convert(a,unsigned)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (1,default);
+insert into t1 values (-1,default);
+select * from t1;
+a	b
+1	1
+-1	18446744073709551615
+drop table t1;
+set sql_warnings = 0;
+#
+# XML FUNCTIONS
+#
+# None.
+#
+# OTHER FUNCTIONS
+#
+# AES_DECRYPT(), AES_ENCRYPT()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (aes_encrypt(aes_decrypt(a,'adf'),'adf')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (aes_encrypt(aes_decrypt(a,'adf'),'adf')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	NULL
+drop table t1;
+set sql_warnings = 0;
+# BIT_COUNT()
+set sql_warnings = 1;
+create table t1 (a int, b int as (bit_count(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (bit_count(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values (5,default);
+select * from t1;
+a	b
+5	2
+drop table t1;
+set sql_warnings = 0;
+# CHARSET()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (charset(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (charset(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	latin1
+drop table t1;
+set sql_warnings = 0;
+# COERCIBILITY()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b int as (coercibility(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` int(11) AS (coercibility(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	2
+drop table t1;
+set sql_warnings = 0;
+# COLLATION()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (collation(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (collation(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	latin1_swedish_ci
+drop table t1;
+set sql_warnings = 0;
+# COMPRESS(), UNCOMPRESS()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (uncompress(compress(a))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (uncompress(compress(a))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MySQL
+drop table t1;
+set sql_warnings = 0;
+# ENCODE(), DECODE()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (decode(encode(a,'abc'),'abc')));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (decode(encode(a,'abc'),'abc')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('MySQL',default);
+select * from t1;
+a	b
+MySQL	MySQL
+drop table t1;
+set sql_warnings = 0;
+# DEFAULT()
+set sql_warnings = 1;
+create table t1 (a varchar(1024) default 'aaa', b varchar(1024) as (ifnull(a,default(a))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT 'aaa',
+  `b` varchar(1024) AS (ifnull(a,default(a))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('any value',default);
+select * from t1;
+a	b
+any value	any value
+drop table t1;
+set sql_warnings = 0;
+# INET_ATON(), INET_NTOA()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (inet_ntoa(inet_aton(a))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (inet_ntoa(inet_aton(a))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('127.0.0.1',default);
+select * from t1;
+a	b
+127.0.0.1	127.0.0.1
+drop table t1;
+set sql_warnings = 0;
+# MD5()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varbinary(32) as (md5(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varbinary(32) AS (md5(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('testing',default);
+select * from t1;
+a	b
+testing	ae2b1fca515949e5d54fb22b8ed95575
+drop table t1;
+set sql_warnings = 0;
+# OLD_PASSWORD()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (old_password(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (old_password(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('badpwd',default);
+select * from t1;
+a	b
+badpwd	7f84554057dd964b
+drop table t1;
+set sql_warnings = 0;
+# PASSWORD()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (password(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (password(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('badpwd',default);
+select * from t1;
+a	b
+badpwd	*AAB3E285149C0135D51A520E1940DD3263DC008C
+drop table t1;
+set sql_warnings = 0;
+# SHA1()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (sha1(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (sha1(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	a9993e364706816aba3e25717850c26c9cd0d89d
+drop table t1;
+set sql_warnings = 0;
+# SHA()
+set sql_warnings = 1;
+create table t1 (a varchar(1024), b varchar(1024) as (sha(a)));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(1024) DEFAULT NULL,
+  `b` varchar(1024) AS (sha(a)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('abc',default);
+select * from t1;
+a	b
+abc	a9993e364706816aba3e25717850c26c9cd0d89d
+drop table t1;
+set sql_warnings = 0;
+# UNCOMPRESSED_LENGTH()
+set sql_warnings = 1;
+create table t1 (a char, b varchar(1024) as (uncompressed_length(compress(repeat(a,30)))));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` char(1) DEFAULT NULL,
+  `b` varchar(1024) AS (uncompressed_length(compress(repeat(a,30)))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('a',default);
+select * from t1;
+a	b
+a	30
+drop table t1;
+set sql_warnings = 0;

=== added file 'mysql-test/suite/vcol/r/vcol_syntax.result'
--- a/mysql-test/suite/vcol/r/vcol_syntax.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_syntax.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,52 @@
+drop table if exists t1;
+set @OLD_SQL_MODE=@@SESSION.SQL_MODE;
+create table t1 (a int, b int generated always  as (a+1));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a+1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int, b int as (a+1) virtual);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a+1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int, b int generated always  as (a+1) persistent);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) AS (a+1) PERSISTENT
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+set session sql_mode='ORACLE';
+create table t1 (a int, b int as (a+1));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE "t1" (
+  "a" int(11) DEFAULT NULL,
+  "b" int(11) AS (a+1) VIRTUAL
+)
+drop table t1;
+create table t1 (a int, b int generated always as (a+1) virtual);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE "t1" (
+  "a" int(11) DEFAULT NULL,
+  "b" int(11) AS (a+1) VIRTUAL
+)
+drop table t1;
+create table t1 (a int, b int as (a+1) persistent);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE "t1" (
+  "a" int(11) DEFAULT NULL,
+  "b" int(11) AS (a+1) PERSISTENT
+)
+drop table t1;
+set session sql_mode=@OLD_SQL_MODE;

=== added file 'mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,87 @@
+SET @@session.storage_engine = 'InnoDB';
+create table t1 (a int, 
+b int as (a/10),
+c int as (a/10) persistent);
+create table t2 (a timestamp);
+create trigger trg1 before insert on t1 for each row
+begin
+if (new.b < 10) then
+set new.a:= 100;
+set new.b:= 9;
+set new.c:= 9;
+end if;
+if (new.c > 50) then
+set new.a:= 500; 
+end if;
+end|
+create trigger trg2 after insert on t1 for each row
+begin
+if (new.b >= 60) then
+insert into t2 values (now()); 
+end if;
+end|
+create function f1()
+returns int
+begin
+declare sum1 int default '0';
+declare cur1 cursor for select sum(b) from t1;
+open cur1;
+fetch cur1 into sum1;
+close cur1;
+return sum1;
+end|
+set sql_warnings = 1;
+insert into t1 (a) values (200);
+select * from t1;
+a	b	c
+200	20	20
+select * from t2;
+a
+insert into t1 (a) values (10);
+select * from t1;
+a	b	c
+200	20	20
+100	10	10
+select * from t2;
+a
+insert into t1 (a) values (600);
+select * from t1;
+a	b	c
+200	20	20
+100	10	10
+500	50	50
+select * from t2;
+a
+select f1();
+f1()
+80
+set sql_warnings = 0;
+drop trigger trg1;
+drop trigger trg2;
+drop table t2;
+create procedure p1()
+begin
+declare i int default '0';
+create table t2 like t1;
+insert into t2 (a) values (100), (200);
+begin
+declare cur1 cursor for select sum(c) from t2;
+open cur1;
+fetch cur1 into i;
+close cur1;
+if (i=30) then
+insert into t1 values (300,default,default);
+end if;
+end;
+end|
+delete from t1;
+call p1();
+select * from t2;
+a	b	c
+100	10	10
+200	20	20
+select * from t1;
+a	b	c
+300	30	30
+drop table t1,t2;
+drop procedure p1;

=== added file 'mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,87 @@
+SET @@session.storage_engine = 'MyISAM';
+create table t1 (a int, 
+b int as (a/10),
+c int as (a/10) persistent);
+create table t2 (a timestamp);
+create trigger trg1 before insert on t1 for each row
+begin
+if (new.b < 10) then
+set new.a:= 100;
+set new.b:= 9;
+set new.c:= 9;
+end if;
+if (new.c > 50) then
+set new.a:= 500; 
+end if;
+end|
+create trigger trg2 after insert on t1 for each row
+begin
+if (new.b >= 60) then
+insert into t2 values (now()); 
+end if;
+end|
+create function f1()
+returns int
+begin
+declare sum1 int default '0';
+declare cur1 cursor for select sum(b) from t1;
+open cur1;
+fetch cur1 into sum1;
+close cur1;
+return sum1;
+end|
+set sql_warnings = 1;
+insert into t1 (a) values (200);
+select * from t1;
+a	b	c
+200	20	20
+select * from t2;
+a
+insert into t1 (a) values (10);
+select * from t1;
+a	b	c
+200	20	20
+100	10	10
+select * from t2;
+a
+insert into t1 (a) values (600);
+select * from t1;
+a	b	c
+200	20	20
+100	10	10
+500	50	50
+select * from t2;
+a
+select f1();
+f1()
+80
+set sql_warnings = 0;
+drop trigger trg1;
+drop trigger trg2;
+drop table t2;
+create procedure p1()
+begin
+declare i int default '0';
+create table t2 like t1;
+insert into t2 (a) values (100), (200);
+begin
+declare cur1 cursor for select sum(c) from t2;
+open cur1;
+fetch cur1 into i;
+close cur1;
+if (i=30) then
+insert into t1 values (300,default,default);
+end if;
+end;
+end|
+delete from t1;
+call p1();
+select * from t2;
+a	b	c
+100	10	10
+200	20	20
+select * from t1;
+a	b	c
+300	30	30
+drop table t1,t2;
+drop procedure p1;

=== added file 'mysql-test/suite/vcol/r/vcol_view_innodb.result'
--- a/mysql-test/suite/vcol/r/vcol_view_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,276 @@
+SET @@session.storage_engine = 'InnoDB';
+create table t1 (a int not null,
+b int as (-a), 
+c int as (-a) persistent);
+insert into t1 (a) values (1), (1), (2), (2), (3);
+create view v1 (d,e) as select abs(b), abs(c) from t1;
+select d,e from v1;
+d	e
+1	1
+1	1
+2	2
+2	2
+3	3
+select is_updatable from information_schema.views where table_name='v1';
+is_updatable
+NO
+explain extended select d,e from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	100.00	
+Warnings:
+Note	1003	select abs(`test`.`t1`.`b`) AS `d`,abs(`test`.`t1`.`c`) AS `e` from `test`.`t1`
+create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1;
+show create view v2;
+View	Create View	character_set_client	collation_connection
+v2	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select abs(`t1`.`b`) AS `d`,abs(`t1`.`c`) AS `e` from `t1`	latin1	latin1_swedish_ci
+select d,e from v2;
+d	e
+1	1
+1	1
+2	2
+2	2
+3	3
+explain extended select d,e from v2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	5	100.00	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	5	100.00	
+Warnings:
+Note	1003	select `v2`.`d` AS `d`,`v2`.`e` AS `e` from `test`.`v2`
+create view v3 (d,e) as select d*2, e*2 from v1;
+select * from v3;
+d	e
+2	2
+2	2
+4	4
+4	4
+6	6
+explain extended select * from v3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	100.00	
+Warnings:
+Note	1003	select (abs(`test`.`t1`.`b`) * 2) AS `d`,(abs(`test`.`t1`.`c`) * 2) AS `e` from `test`.`t1`
+drop view v1,v2,v3;
+drop table t1;
+create table t1 (a int not null,
+b int as (-a), 
+c int as (-a) persistent);
+insert into t1 (a) values (1), (2), (3), (1), (2), (3);
+create view v1 as select distinct b from t1;
+select * from v1;
+b
+-1
+-2
+-3
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	3	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	6	Using temporary
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+1	-1	-1
+2	-2	-2
+3	-3	-3
+drop view v1;
+create view v1 as select distinct c from t1;
+select * from v1;
+c
+-1
+-2
+-3
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	3	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	6	Using temporary
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+1	-1	-1
+2	-2	-2
+3	-3	-3
+drop view v1;
+drop table t1;
+create table t1 (a int not null,
+b int as (-a), 
+c int as (-a) persistent);
+insert into t1 (a) values (1), (2), (3), (4);
+create view v1 as select b+1 from t1 order by 1 desc limit 2;
+select * from v1;
+b+1
+0
+-1
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	2	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	4	Using filesort
+drop view v1;
+create view v1 as select c+1 from t1 order by 1 desc limit 2;
+select * from v1;
+c+1
+0
+-1
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	2	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	4	Using filesort
+drop view v1;
+drop table t1;
+create table t1 (a int,
+b int,
+c int as (-a),
+d int as (-a) persistent,
+primary key(a));
+insert into t1 (a,b) values (10,2), (20,3), (30,4), (40,5), (50,10);
+create view v1 (a,e,f,g) as select a, b+1,c+1,d+1 from t1;
+update v1 set a=a+e;
+select * from v1;
+a	e	f	g
+13	3	-12	-12
+24	4	-23	-23
+35	5	-34	-34
+46	6	-45	-45
+61	11	-60	-60
+select * from t1;
+a	b	c	d
+13	2	-13	-13
+24	3	-24	-24
+35	4	-35	-35
+46	5	-46	-46
+61	10	-61	-61
+delete from v1;
+select * from v1;
+a	e	f	g
+select * from t1;
+a	b	c	d
+insert into v1 (a,e) values (60,15);
+ERROR HY000: The target table v1 of the INSERT is not insertable-into
+drop table t1;
+drop view v1;
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent,
+primary key(a));
+insert into t1 (a) values (1), (2), (3);
+create view v1 (x,y,z) as select a,b,c from t1 where b < -1;
+select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.b= v1.y);
+a	x	y	z
+1	NULL	NULL	NULL
+2	2	-2	-2
+3	3	-3	-3
+drop view v1;
+create view v1 (x,y,z) as select a,b,c from t1 where c < -1;
+select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.c= v1.z);
+a	x	y	z
+1	NULL	NULL	NULL
+2	2	-2	-2
+3	3	-3	-3
+drop view v1;
+drop table t1;
+create table t1 (a1 int,
+b1 int as (-a1),
+c1 int as (-a1) persistent);
+create table t2 (a2 int,
+b2 int as (-a2),
+c2 int as (-a2) persistent);
+insert into t1 (a1) values (1), (2);
+insert into t2 (a2) values (2), (3);
+create view v1 as select * from t1,t2 union all select * from t1,t2;
+select * from v1;
+a1	b1	c1	a2	b2	c2
+1	-1	-1	2	-2	-2
+2	-2	-2	2	-2	-2
+1	-1	-1	3	-3	-3
+2	-2	-2	3	-3	-3
+1	-1	-1	2	-2	-2
+2	-2	-2	2	-2	-2
+1	-1	-1	3	-3	-3
+2	-2	-2	3	-3	-3
+drop view v1;
+drop table t1, t2;
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent);
+create table t2 like t1;
+create view v1 as select a,b,c from t1;
+create view v2 as select a,b,c from t2 where b in (select b from v1);
+show create view v2;
+View	Create View	character_set_client	collation_connection
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a`,`t2`.`b` AS `b`,`t2`.`c` AS `c` from `t2` where `t2`.`b` in (select `v1`.`b` AS `b` from `v1`)	latin1	latin1_swedish_ci
+drop view v2, v1;
+drop table t1, t2;
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent);
+insert into t1 (a) values (1),(1),(2),(2),(3),(3);
+create view v1 as select b from t1;
+select distinct b from v1;
+b
+-1
+-2
+-3
+select distinct b from v1 limit 2;
+b
+-1
+-2
+select distinct b from t1 limit 2;
+b
+-1
+-2
+prepare stmt1 from "select distinct b from v1 limit 2";
+execute stmt1;
+b
+-1
+-2
+execute stmt1;
+b
+-1
+-2
+deallocate prepare stmt1;
+drop view v1;
+create view v1 as select c from t1;
+select distinct c from v1;
+c
+-1
+-2
+-3
+select distinct c from v1 limit 2;
+c
+-1
+-2
+select distinct c from t1 limit 2;
+c
+-1
+-2
+prepare stmt1 from "select distinct c from v1 limit 2";
+execute stmt1;
+c
+-1
+-2
+execute stmt1;
+c
+-1
+-2
+deallocate prepare stmt1;
+drop view v1;
+drop table t1;
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent);
+create view v1 as select * from t1 where b > -2 && c >-2 with check option;
+insert into v1 (a) values (1);
+insert into v1 (a) values (3);
+ERROR HY000: CHECK OPTION failed 'test.v1'
+insert ignore into v1 (a) values (2),(3),(0);
+Warnings:
+Error	1369	CHECK OPTION failed 'test.v1'
+Error	1369	CHECK OPTION failed 'test.v1'
+select * from t1;
+a	b	c
+1	-1	-1
+0	0	0
+drop view v1;
+drop table t1;

=== added file 'mysql-test/suite/vcol/r/vcol_view_myisam.result'
--- a/mysql-test/suite/vcol/r/vcol_view_myisam.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/vcol_view_myisam.result	2009-10-16 22:57:48 +0000
@@ -0,0 +1,276 @@
+SET @@session.storage_engine = 'MyISAM';
+create table t1 (a int not null,
+b int as (-a), 
+c int as (-a) persistent);
+insert into t1 (a) values (1), (1), (2), (2), (3);
+create view v1 (d,e) as select abs(b), abs(c) from t1;
+select d,e from v1;
+d	e
+1	1
+1	1
+2	2
+2	2
+3	3
+select is_updatable from information_schema.views where table_name='v1';
+is_updatable
+NO
+explain extended select d,e from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	100.00	
+Warnings:
+Note	1003	select abs(`test`.`t1`.`b`) AS `d`,abs(`test`.`t1`.`c`) AS `e` from `test`.`t1`
+create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1;
+show create view v2;
+View	Create View	character_set_client	collation_connection
+v2	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select abs(`t1`.`b`) AS `d`,abs(`t1`.`c`) AS `e` from `t1`	latin1	latin1_swedish_ci
+select d,e from v2;
+d	e
+1	1
+1	1
+2	2
+2	2
+3	3
+explain extended select d,e from v2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	5	100.00	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	5	100.00	
+Warnings:
+Note	1003	select `v2`.`d` AS `d`,`v2`.`e` AS `e` from `test`.`v2`
+create view v3 (d,e) as select d*2, e*2 from v1;
+select * from v3;
+d	e
+2	2
+2	2
+4	4
+4	4
+6	6
+explain extended select * from v3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	100.00	
+Warnings:
+Note	1003	select (abs(`test`.`t1`.`b`) * 2) AS `d`,(abs(`test`.`t1`.`c`) * 2) AS `e` from `test`.`t1`
+drop view v1,v2,v3;
+drop table t1;
+create table t1 (a int not null,
+b int as (-a), 
+c int as (-a) persistent);
+insert into t1 (a) values (1), (2), (3), (1), (2), (3);
+create view v1 as select distinct b from t1;
+select * from v1;
+b
+-1
+-2
+-3
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	3	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	6	Using temporary
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+1	-1	-1
+2	-2	-2
+3	-3	-3
+drop view v1;
+create view v1 as select distinct c from t1;
+select * from v1;
+c
+-1
+-2
+-3
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	3	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	6	Using temporary
+select * from t1;
+a	b	c
+1	-1	-1
+2	-2	-2
+3	-3	-3
+1	-1	-1
+2	-2	-2
+3	-3	-3
+drop view v1;
+drop table t1;
+create table t1 (a int not null,
+b int as (-a), 
+c int as (-a) persistent);
+insert into t1 (a) values (1), (2), (3), (4);
+create view v1 as select b+1 from t1 order by 1 desc limit 2;
+select * from v1;
+b+1
+0
+-1
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	2	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	4	Using filesort
+drop view v1;
+create view v1 as select c+1 from t1 order by 1 desc limit 2;
+select * from v1;
+c+1
+0
+-1
+explain select * from v1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	2	
+2	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	4	Using filesort
+drop view v1;
+drop table t1;
+create table t1 (a int,
+b int,
+c int as (-a),
+d int as (-a) persistent,
+primary key(a));
+insert into t1 (a,b) values (10,2), (20,3), (30,4), (40,5), (50,10);
+create view v1 (a,e,f,g) as select a, b+1,c+1,d+1 from t1;
+update v1 set a=a+e;
+select * from v1;
+a	e	f	g
+13	3	-12	-12
+24	4	-23	-23
+35	5	-34	-34
+46	6	-45	-45
+61	11	-60	-60
+select * from t1;
+a	b	c	d
+13	2	-13	-13
+24	3	-24	-24
+35	4	-35	-35
+46	5	-46	-46
+61	10	-61	-61
+delete from v1;
+select * from v1;
+a	e	f	g
+select * from t1;
+a	b	c	d
+insert into v1 (a,e) values (60,15);
+ERROR HY000: The target table v1 of the INSERT is not insertable-into
+drop table t1;
+drop view v1;
+create table t1 (a int, 
+b int as (-a),
+c int as (-a) persistent,
+primary key(a));
+insert into t1 (a) values (1), (2), (3);
+create view v1 (x,y,z) as select a,b,c from t1 where b < -1;
+select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.b= v1.y);
+a	x	y	z
+1	NULL	NULL	NULL
+2	2	-2	-2
+3	3	-3	-3
+drop view v1;
+create view v1 (x,y,z) as select a,b,c from t1 where c < -1;
+select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.c= v1.z);
+a	x	y	z
+1	NULL	NULL	NULL
+2	2	-2	-2
+3	3	-3	-3
+drop view v1;
+drop table t1;
+create table t1 (a1 int,
+b1 int as (-a1),
+c1 int as (-a1) persistent);
+create table t2 (a2 int,
+b2 int as (-a2),
+c2 int as (-a2) persistent);
+insert into t1 (a1) values (1), (2);
+insert into t2 (a2) values (2), (3);
+create view v1 as select * from t1,t2 union all select * from t1,t2;
+select * from v1;
+a1	b1	c1	a2	b2	c2
+1	-1	-1	2	-2	-2
+2	-2	-2	2	-2	-2
+1	-1	-1	3	-3	-3
+2	-2	-2	3	-3	-3
+1	-1	-1	2	-2	-2
+2	-2	-2	2	-2	-2
+1	-1	-1	3	-3	-3
+2	-2	-2	3	-3	-3
+drop view v1;
+drop table t1, t2;
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent);
+create table t2 like t1;
+create view v1 as select a,b,c from t1;
+create view v2 as select a,b,c from t2 where b in (select b from v1);
+show create view v2;
+View	Create View	character_set_client	collation_connection
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a`,`t2`.`b` AS `b`,`t2`.`c` AS `c` from `t2` where `t2`.`b` in (select `v1`.`b` AS `b` from `v1`)	latin1	latin1_swedish_ci
+drop view v2, v1;
+drop table t1, t2;
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent);
+insert into t1 (a) values (1),(1),(2),(2),(3),(3);
+create view v1 as select b from t1;
+select distinct b from v1;
+b
+-1
+-2
+-3
+select distinct b from v1 limit 2;
+b
+-1
+-2
+select distinct b from t1 limit 2;
+b
+-1
+-2
+prepare stmt1 from "select distinct b from v1 limit 2";
+execute stmt1;
+b
+-1
+-2
+execute stmt1;
+b
+-1
+-2
+deallocate prepare stmt1;
+drop view v1;
+create view v1 as select c from t1;
+select distinct c from v1;
+c
+-1
+-2
+-3
+select distinct c from v1 limit 2;
+c
+-1
+-2
+select distinct c from t1 limit 2;
+c
+-1
+-2
+prepare stmt1 from "select distinct c from v1 limit 2";
+execute stmt1;
+c
+-1
+-2
+execute stmt1;
+c
+-1
+-2
+deallocate prepare stmt1;
+drop view v1;
+drop table t1;
+create table t1 (a int,
+b int as (-a),
+c int as (-a) persistent);
+create view v1 as select * from t1 where b > -2 && c >-2 with check option;
+insert into v1 (a) values (1);
+insert into v1 (a) values (3);
+ERROR HY000: CHECK OPTION failed 'test.v1'
+insert ignore into v1 (a) values (2),(3),(0);
+Warnings:
+Error	1369	CHECK OPTION failed 'test.v1'
+Error	1369	CHECK OPTION failed 'test.v1'
+select * from t1;
+a	b	c
+1	-1	-1
+0	0	0
+drop view v1;
+drop table t1;

=== added directory 'mysql-test/suite/vcol/t'
=== added file 'mysql-test/suite/vcol/t/rpl_vcol.test'
--- a/mysql-test/suite/vcol/t/rpl_vcol.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/rpl_vcol.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,69 @@
+################################################################################
+# t/vcol_rpl.test                                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#   Test replication of tables with virtual columns.                           #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04 
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+SET @@session.storage_engine = 'InnoDB';
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source include/master-slave.inc
+
+connection master;
+create table t1 (a int, b int as (a+1));
+show create table t1;
+insert into t1 values (1,default);
+insert into t1 values (2,default);
+select * from t1;
+save_master_pos;
+
+connection slave;
+sync_with_master;
+select * from t1;
+
+connection master;
+drop table t1;
+save_master_pos;
+
+connection slave;
+sync_with_master;
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_archive.test'
--- a/mysql-test/suite/vcol/t/vcol_archive.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_archive.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,49 @@
+################################################################################
+# t/vcol_archive.test                                                          #
+#                                                                              #
+# Purpose:                                                                     #
+#        ARCHIVE branch                                                        #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_archive.inc
+SET @@session.storage_engine = 'archive';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+--source suite/vcol/inc/vcol_unsupported_storage_engines.inc
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_blackhole.test'
--- a/mysql-test/suite/vcol/t/vcol_blackhole.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_blackhole.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,49 @@
+################################################################################
+# t/vcol_blackhole.test                                                        #
+#                                                                              #
+# Purpose:                                                                     #
+#        BLACKHOLE branch                                                      #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_blackhole.inc
+SET @@session.storage_engine = 'blackhole';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+--source suite/vcol/inc/vcol_unsupported_storage_engines.inc
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,52 @@
+################################################################################
+# t/vcol_supported_sql_funcs.test                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#  Test SQL functions not allowed for virtual columns                          #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+let $skip_full_text_checks = 1;
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_blocked_sql_funcs_main.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,49 @@
+################################################################################
+# t/vcol_supported_sql_funcs.test                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#  Test SQL functions not allowed for virtual columns                          #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_blocked_sql_funcs_main.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,51 @@
+################################################################################
+# t/vcol_column_def_options_innodb.test                                        #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing different optional parameters of virtual columns.                   #
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_column_def_options.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,50 @@
+################################################################################
+# t/vcol_column_def_options_myisam.test                                        #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing different optional parameters of virtual columns.                   #
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_column_def_options.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_csv.test'
--- a/mysql-test/suite/vcol/t/vcol_csv.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_csv.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,54 @@
+################################################################################
+# t/vcol_csv.test                                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#        CSV branch                                                            #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_csv.inc
+SET @@session.storage_engine = 'CSV';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a+1));
+create table t1 (a int not null);
+--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+alter table t1 add column b int as (a+1);
+drop table t1;
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_handler_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_handler_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_handler_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,51 @@
+################################################################################
+# t/vcol_handler_innodb.test                                                   #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing HANDLER.
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_handler.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_handler_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_handler_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_handler_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,50 @@
+################################################################################
+# t/vcol_handler_myisam.test                                                   #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing HANDLER.
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_handler.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,51 @@
+################################################################################
+# t/vcol_ins_upd_innodb.test                                                   #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing DDL operations such as INSERT, UPDATE, REPLACE and DELETE.          #
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_ins_upd.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,50 @@
+################################################################################
+# t/vcol_ins_upd_myisam.test                                                   #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing DDL operations such as INSERT, UPDATE, REPLACE and DELETE.          #
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_ins_upd.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_keys_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_keys_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_keys_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,52 @@
+################################################################################
+# t/vcol_keys_innodb.test                                                      #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing keys, indexes defined upon virtual columns.                         # 
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+let $skip_spatial_index_check = 1;
+--source suite/vcol/inc/vcol_keys.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_keys_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_keys_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_keys_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,50 @@
+################################################################################
+# t/vcol_keys_myisam.test                                                      #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing keys, indexes defined upon virtual columns.                         # 
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_keys.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_memory.test'
--- a/mysql-test/suite/vcol/t/vcol_memory.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_memory.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,48 @@
+################################################################################
+# t/vcol_memory.test                                                           #
+#                                                                              #
+# Purpose:                                                                     #
+#        MEMORY branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-02                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+SET @@session.storage_engine = 'memory';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+--source suite/vcol/inc/vcol_unsupported_storage_engines.inc
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_merge.test'
--- a/mysql-test/suite/vcol/t/vcol_merge.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_merge.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,57 @@
+################################################################################
+# t/vcol_merge.test                                                            #
+#                                                                              #
+# Purpose:                                                                     #
+#        MERGE branch                                                          #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-03                                                    #
+# Change Author: Oleksandr Byelkin (Monty program Ab)
+# Date: 2009-03-24 
+# Change: Syntax changed
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+
+create table t1 (a int, b int as (a % 10));
+create table t2 (a int, b int as (a % 10));
+insert into t1 values (1,default);
+insert into t2 values (2,default);
+--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+create table t3 (a int, b int as (a % 10)) engine=MERGE UNION=(t1,t2);
+drop table t1,t2;
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,53 @@
+################################################################################
+# t/vcol_non_stored_columns_innodb.test                                        #
+#                                                                              #
+# Purpose:                                                                     #
+#  Ensure that MySQL behaviour is consistent irrelevant of                     #
+#    - the place of a non-stored column among other columns,                   #
+#    - the total number of non-stored fields.                                  #
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_non_stored_columns.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,52 @@
+################################################################################
+# t/vcol_non_stored_columns_myisam.test                                        #
+#                                                                              #
+# Purpose:                                                                     #
+#  Ensure that MySQL behaviour is consistent irrelevant of                     #
+#    - the place of a non-stored column among other columns,                   #
+#    - the total number of non-stored fields.                                  #
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_non_stored_columns.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_partition_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_partition_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_partition_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,52 @@
+################################################################################
+# t/vcol_partition_innodb.test                                                 #
+#                                                                              #
+# Purpose:                                                                     #
+#   Testing partitioning tables with virtual columns.                          #
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+--source include/have_partition.inc
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_partition.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_partition_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_partition_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_partition_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,51 @@
+################################################################################
+# t/vcol_partition_myisam.test                                                 #
+#                                                                              #
+# Purpose:                                                                     #
+#   Testing partitioning tables with virtual columns.                          #
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+--source include/have_partition.inc
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_partition.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_select_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_select_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_select_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,51 @@
+################################################################################
+# t/vcol_select_innodb.test                                                    #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing different SELECTs.                                                  #
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-18                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_select.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_select_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_select_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_select_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,50 @@
+################################################################################
+# t/vcol_select.test                                                           #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing different SELECTs.                                                  #
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-18                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_select.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_supported_sql_funcs_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,50 @@
+################################################################################
+# t/vcol_supported_sql_funcs.test                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#  Test SQL functions allowed for virtual columns                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_supported_sql_funcs_main.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_supported_sql_funcs_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,49 @@
+################################################################################
+# t/vcol_supported_sql_funcs.test                                              #
+#                                                                              #
+# Purpose:                                                                     #
+#  Test SQL functions allowed for virtual columns                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-08-31                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_supported_sql_funcs_main.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_syntax.test'
--- a/mysql-test/suite/vcol/t/vcol_syntax.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_syntax.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,30 @@
+#
+# test syntax
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+set @OLD_SQL_MODE=@@SESSION.SQL_MODE;
+create table t1 (a int, b int generated always  as (a+1));
+show create table t1;
+drop table t1;
+create table t1 (a int, b int as (a+1) virtual);
+show create table t1;
+drop table t1;
+create table t1 (a int, b int generated always  as (a+1) persistent);
+show create table t1;
+drop table t1;
+
+set session sql_mode='ORACLE';
+create table t1 (a int, b int as (a+1));
+show create table t1;
+drop table t1;
+create table t1 (a int, b int generated always as (a+1) virtual);
+show create table t1;
+drop table t1;
+create table t1 (a int, b int as (a+1) persistent);
+show create table t1;
+drop table t1;
+set session sql_mode=@OLD_SQL_MODE;
+

=== added file 'mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,52 @@
+################################################################################
+# t/vcol_trigger_sp_innodb.test                                                #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing triggers, stored procedures and functions                           #
+#  defined on tables with virtual columns.                                     #
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_trigger_sp.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,51 @@
+################################################################################
+# t/vcol_trigger_sp_myisam.test                                                #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing triggers, stored procedures and functions                           #
+#  defined on tables with virtual columns.                                     #
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_trigger_sp.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_view_innodb.test'
--- a/mysql-test/suite/vcol/t/vcol_view_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_view_innodb.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,51 @@
+################################################################################
+# t/vcol_view_innodb.test                                                      #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing views defined on tables with virtual columns.                       #
+#                                                                              #
+#        InnoDB branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+--source include/have_innodb.inc
+eval SET @@session.storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_view.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== added file 'mysql-test/suite/vcol/t/vcol_view_myisam.test'
--- a/mysql-test/suite/vcol/t/vcol_view_myisam.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/vcol_view_myisam.test	2009-10-16 22:57:48 +0000
@@ -0,0 +1,50 @@
+################################################################################
+# t/vcol_view_myisam.test                                                      #
+#                                                                              #
+# Purpose:                                                                     #
+#  Testing views defined on tables with virtual columns.                       #
+#                                                                              #
+#        MyISAM branch                                                         #
+#                                                                              #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov                                               #
+# Original Date: 2008-09-04                                                    #
+# Change Author:                                                               #
+# Change Date:                                                                 #
+# Change:                                                                      #
+################################################################################
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MYISAM SPECIFIC TESTCASES HERE !
+#       TESTCASES WHICH MUST BE APPLIED TO ALL STORAGE ENGINES MUST BE ADDED IN
+#       THE SOURCED FILES ONLY.
+#
+
+#------------------------------------------------------------------------------#
+# General not engine specific settings and requirements
+--source suite/vcol/inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#------------------------------------------------------------------------------#
+# Engine specific settings and requirements
+
+##### Storage engine to be tested
+# Set the session storage engine
+eval SET @@session.storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+#     none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source suite/vcol/inc/vcol_view.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2009-09-07 20:50:10 +0000
+++ b/sql/field.cc	2009-10-16 22:57:48 +0000
@@ -57,7 +57,7 @@ const char field_separator=',';
 ((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
 
 #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
-#define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+#define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || bitmap_is_set(&table->vcol_set, field_index)))
 
 /*
   Rules for merging different types of fields in UNION
@@ -1312,7 +1312,8 @@ Field::Field(uchar *ptr_arg,uint32 lengt
    key_start(0), part_of_key(0), part_of_key_not_clustered(0),
    part_of_sortkey(0), unireg_check(unireg_check_arg),
    field_length(length_arg), null_bit(null_bit_arg), 
-   is_created_from_null_item(FALSE)
+   is_created_from_null_item(FALSE),
+   vcol_info(0), stored_in_db(TRUE)
 {
   flags=null_ptr ? 0: NOT_NULL_FLAG;
   comment.str= (char*) "";
@@ -1611,7 +1612,7 @@ longlong Field::convert_decimal2longlong
 
 int Field_num::store_decimal(const my_decimal *val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int err= 0;
   longlong i= convert_decimal2longlong(val, unsigned_flag, &err);
   return test(err | store(i, unsigned_flag));
@@ -1683,7 +1684,7 @@ void Field_num::make_field(Send_field *f
 
 int Field_str::store_decimal(const my_decimal *d)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   double val;
   /* TODO: use decimal2string? */
   int err= warn_if_overflow(my_decimal2double(E_DEC_FATAL_ERROR &
@@ -1760,7 +1761,7 @@ bool Field::get_time(MYSQL_TIME *ltime)
 
 int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   char buff[MAX_DATE_STRING_REP_LENGTH];
   uint length= (uint) my_TIME_to_str(ltime, buff);
   return store(buff, length, &my_charset_bin);
@@ -1887,7 +1888,7 @@ void Field_decimal::overflow(bool negati
 
 int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   char buff[STRING_BUFFER_USUAL_SIZE];
   String tmp(buff,sizeof(buff), &my_charset_bin);
   const uchar *from= (uchar*) from_arg;
@@ -2258,7 +2259,7 @@ int Field_decimal::store(const char *fro
 
 int Field_decimal::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   if (unsigned_flag && nr < 0)
   {
     overflow(1);
@@ -2303,7 +2304,7 @@ int Field_decimal::store(double nr)
 
 int Field_decimal::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   char buff[22];
   uint length, int_part;
   char fyllchar;
@@ -2539,7 +2540,7 @@ void Field_new_decimal::set_value_on_ove
 
 bool Field_new_decimal::store_value(const my_decimal *decimal_value)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   DBUG_ENTER("Field_new_decimal::store_value");
 #ifndef DBUG_OFF
@@ -2584,7 +2585,7 @@ bool Field_new_decimal::store_value(cons
 int Field_new_decimal::store(const char *from, uint length,
                              CHARSET_INFO *charset_arg)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int err;
   my_decimal decimal_value;
   DBUG_ENTER("Field_new_decimal::store(char*)");
@@ -2651,7 +2652,7 @@ int Field_new_decimal::store(const char 
 
 int Field_new_decimal::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   my_decimal decimal_value;
   int err;
   DBUG_ENTER("Field_new_decimal::store(double)");
@@ -2686,7 +2687,7 @@ int Field_new_decimal::store(double nr)
 
 int Field_new_decimal::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   my_decimal decimal_value;
   int err;
 
@@ -2708,7 +2709,7 @@ int Field_new_decimal::store(longlong nr
 
 int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   return store_value(decimal_value);
 }
 
@@ -2929,7 +2930,7 @@ Field_new_decimal::unpack(uchar* to,
 
 int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error;
   longlong rnd;
   
@@ -2941,7 +2942,7 @@ int Field_tiny::store(const char *from,u
 
 int Field_tiny::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   nr=rint(nr);
   if (unsigned_flag)
@@ -2984,7 +2985,7 @@ int Field_tiny::store(double nr)
 
 int Field_tiny::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
 
   if (unsigned_flag)
@@ -3104,7 +3105,7 @@ void Field_tiny::sql_type(String &res) c
 
 int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int store_tmp;
   int error;
   longlong rnd;
@@ -3125,7 +3126,7 @@ int Field_short::store(const char *from,
 
 int Field_short::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   int16 res;
   nr=rint(nr);
@@ -3177,7 +3178,7 @@ int Field_short::store(double nr)
 
 int Field_short::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   int16 res;
 
@@ -3351,7 +3352,7 @@ void Field_short::sql_type(String &res) 
 
 int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int store_tmp;
   int error;
   longlong rnd;
@@ -3365,7 +3366,7 @@ int Field_medium::store(const char *from
 
 int Field_medium::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   nr=rint(nr);
   if (unsigned_flag)
@@ -3411,7 +3412,7 @@ int Field_medium::store(double nr)
 
 int Field_medium::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
 
   if (unsigned_flag)
@@ -3541,7 +3542,7 @@ void Field_medium::sql_type(String &res)
 
 int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   long store_tmp;
   int error;
   longlong rnd;
@@ -3562,7 +3563,7 @@ int Field_long::store(const char *from,u
 
 int Field_long::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   int32 res;
   nr=rint(nr);
@@ -3614,7 +3615,7 @@ int Field_long::store(double nr)
 
 int Field_long::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   int32 res;
 
@@ -3788,7 +3789,7 @@ void Field_long::sql_type(String &res) c
 
 int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   char *end;
   ulonglong tmp;
@@ -3818,7 +3819,7 @@ int Field_longlong::store(const char *fr
 
 int Field_longlong::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   longlong res;
 
@@ -3870,7 +3871,7 @@ int Field_longlong::store(double nr)
 
 int Field_longlong::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
 
   if (nr < 0)                                   // Only possible error
@@ -4096,7 +4097,7 @@ int Field_float::store(const char *from,
 
 int Field_float::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= truncate(&nr, FLT_MAX);
   float j= (float)nr;
 
@@ -4358,7 +4359,7 @@ int Field_double::store(const char *from
 
 int Field_double::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= truncate(&nr, DBL_MAX);
 
 #ifdef WORDS_BIGENDIAN
@@ -4785,7 +4786,7 @@ timestamp_auto_set_type Field_timestamp:
 
 int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   MYSQL_TIME l_time;
   my_time_t tmp= 0;
   int error;
@@ -4848,7 +4849,7 @@ int Field_timestamp::store(double nr)
 
 int Field_timestamp::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   MYSQL_TIME l_time;
   my_time_t timestamp= 0;
   int error;
@@ -5147,7 +5148,7 @@ int Field_time::store_time(MYSQL_TIME *l
 
 int Field_time::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   long tmp;
   int error= 0;
   if (nr > (double)TIME_MAX_VALUE)
@@ -5185,7 +5186,7 @@ int Field_time::store(double nr)
 
 int Field_time::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   long tmp;
   int error= 0;
   if (nr < (longlong) -TIME_MAX_VALUE && !unsigned_val)
@@ -5356,7 +5357,7 @@ void Field_time::sql_type(String &res) c
 
 int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   char *end;
   int error;
   longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
@@ -5404,7 +5405,7 @@ int Field_year::store(double nr)
 
 int Field_year::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155)
   {
     *ptr= 0;
@@ -5477,7 +5478,7 @@ void Field_year::sql_type(String &res) c
 
 int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   MYSQL_TIME l_time;
   uint32 tmp;
   int error;
@@ -5532,7 +5533,7 @@ int Field_date::store(double nr)
 
 int Field_date::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   MYSQL_TIME not_used;
   int error;
   longlong initial_nr= nr;
@@ -5711,7 +5712,7 @@ void Field_date::sql_type(String &res) c
 
 int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   long tmp;
   MYSQL_TIME l_time;
   int error;
@@ -5761,7 +5762,7 @@ int Field_newdate::store(double nr)
 
 int Field_newdate::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   MYSQL_TIME l_time;
   longlong tmp;
   int error;
@@ -5797,7 +5798,7 @@ int Field_newdate::store(longlong nr, bo
 
 int Field_newdate::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   long tmp;
   int error= 0;
   if (time_type == MYSQL_TIMESTAMP_DATE ||
@@ -5944,7 +5945,7 @@ void Field_newdate::sql_type(String &res
 
 int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   MYSQL_TIME time_tmp;
   int error;
   ulonglong tmp= 0;
@@ -5997,7 +5998,7 @@ int Field_datetime::store(double nr)
 
 int Field_datetime::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   MYSQL_TIME not_used;
   int error;
   longlong initial_nr= nr;
@@ -6035,7 +6036,7 @@ int Field_datetime::store(longlong nr, b
 
 int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   longlong tmp;
   int error= 0;
   /*
@@ -6338,7 +6339,7 @@ Field_longstr::report_if_important_data(
 
 int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   uint copy_length;
   const char *well_formed_error_pos;
   const char *cannot_convert_error_pos;
@@ -6379,7 +6380,7 @@ int Field_string::store(const char *from
 
 int Field_str::store(double nr)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
   uint length;
   uint local_char_length= field_length / charset()->mbmaxlen;
@@ -6994,7 +6995,7 @@ int Field_varstring::do_save_field_metad
 
 int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   uint copy_length;
   const char *well_formed_error_pos;
   const char *cannot_convert_error_pos;
@@ -7658,7 +7659,7 @@ void Field_blob::put_length(uchar *pos, 
 
 int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   uint copy_length, new_length;
   const char *well_formed_error_pos;
   const char *cannot_convert_error_pos;
@@ -8420,7 +8421,7 @@ void Field_enum::store_type(ulonglong va
 
 int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int err= 0;
   uint32 not_used;
   char buff[STRING_BUFFER_USUAL_SIZE];
@@ -8469,7 +8470,7 @@ int Field_enum::store(double nr)
 
 int Field_enum::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   if ((ulonglong) nr > typelib->count || nr == 0)
   {
@@ -8638,7 +8639,7 @@ Field *Field_enum::new_field(MEM_ROOT *r
 
 int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   bool got_warning= 0;
   int err= 0;
   char *not_used;
@@ -8678,7 +8679,7 @@ int Field_set::store(const char *from,ui
 
 int Field_set::store(longlong nr, bool unsigned_val)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int error= 0;
   ulonglong max_nr= set_bits(ulonglong, typelib->count);
   if ((ulonglong) nr > max_nr)
@@ -8942,7 +8943,7 @@ uint Field_bit::is_equal(Create_field *n
                        
 int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int delta;
 
   for (; length && !*from; from++, length--)          // skip left 0's
@@ -9353,7 +9354,7 @@ Field_bit_as_char::Field_bit_as_char(uch
 
 int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
 {
-  ASSERT_COLUMN_MARKED_FOR_WRITE;
+  ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
   int delta;
   uchar bits= (uchar) (field_length & 7);
 
@@ -9461,6 +9462,8 @@ void Create_field::init_for_tmp_table(en
               ((decimals_arg & FIELDFLAG_MAX_DEC) << FIELDFLAG_DEC_SHIFT) |
               (maybe_null ? FIELDFLAG_MAYBE_NULL : 0) |
               (is_unsigned ? 0 : FIELDFLAG_DECIMAL));
+  vcol_info= 0;
+  stored_in_db= TRUE;
 }
 
 
@@ -9480,6 +9483,7 @@ void Create_field::init_for_tmp_table(en
   @param fld_interval_list     Interval list (if any)
   @param fld_charset           Field charset
   @param fld_geom_type         Field geometry type (if any)
+  @param fld_vcol_info         Virtual column data
 
   @retval
     FALSE on success
@@ -9492,13 +9496,14 @@ bool Create_field::init(THD *thd, char *
                         uint fld_type_modifier, Item *fld_default_value,
                         Item *fld_on_update_value, LEX_STRING *fld_comment,
                         char *fld_change, List<String> *fld_interval_list,
-                        CHARSET_INFO *fld_charset, uint fld_geom_type)
+                        CHARSET_INFO *fld_charset, uint fld_geom_type,
+			Virtual_column_info *fld_vcol_info)
 {
   uint sign_len, allowed_type_modifier= 0;
   ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
 
   DBUG_ENTER("Create_field::init()");
-  
+
   field= 0;
   field_name= fld_name;
   def= fld_default_value;
@@ -9523,6 +9528,33 @@ bool Create_field::init(THD *thd, char *
   interval_list.empty();
 
   comment= *fld_comment;
+  vcol_info= fld_vcol_info;
+  stored_in_db= TRUE;
+
+  /* Initialize data for a computed field */
+  if ((uchar)fld_type == (uchar)MYSQL_TYPE_VIRTUAL)
+  {
+    DBUG_ASSERT(vcol_info && vcol_info->expr_item);
+    stored_in_db= vcol_info->is_stored();
+    /*
+      Walk through the Item tree checking if all items are valid
+      to be part of the virtual column
+    */
+    if (vcol_info->expr_item->walk(&Item::check_vcol_func_processor, 0, NULL))
+    {
+      my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
+      DBUG_RETURN(TRUE);
+    }
+
+    /*
+      Make a field created for the real type.
+      Note that regular and computed fields differ from each other only by
+      Field::vcol_info. It is is always NULL for a column that is not
+      computed.
+    */
+    sql_type= fld_type= vcol_info->get_real_type();
+  }
+
   /*
     Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
     it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
@@ -9813,7 +9845,7 @@ bool Create_field::init(THD *thd, char *
     }
   case MYSQL_TYPE_DECIMAL:
     DBUG_ASSERT(0); /* Was obsolete */
-  }
+ }
   /* Remember the value of length */
   char_length= length;
 
@@ -9912,7 +9944,6 @@ uint pack_length_to_packflag(uint type)
   return 0;					// This shouldn't happen
 }
 
-
 Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
 		  uchar *null_pos, uchar null_bit,
 		  uint pack_flag,
@@ -10106,6 +10137,8 @@ Create_field::Create_field(Field *old_fi
   charset=    old_field->charset();		// May be NULL ptr
   comment=    old_field->comment;
   decimals=   old_field->decimals();
+  vcol_info=  old_field->vcol_info;
+  stored_in_db= old_field->stored_in_db;
 
   /* Fix if the original table had 4 byte pointer blobs */
   if (flags & BLOB_FLAG)

=== modified file 'sql/field.h'
--- a/sql/field.h	2009-09-07 20:50:10 +0000
+++ b/sql/field.h	2009-10-16 22:57:48 +0000
@@ -45,6 +45,80 @@ inline uint get_set_pack_length(int elem
   return len > 4 ? 8 : len;
 }
 
+/*
+  Virtual_column_info is the class to contain additional
+  characteristics that is specific for a virtual/computed
+  field such as:
+   - the defining expression that is evaluated to compute the value
+  of the field 
+  - whether the field is to be stored in the database
+  - whether the field is used in a partitioning expression
+*/
+
+class Virtual_column_info: public Sql_alloc
+{
+private:
+  /*
+    The following data is only updated by the parser and read
+    when a Create_field object is created/initialized.
+  */
+  enum_field_types field_type;   /* Real field type*/
+  /* Flag indicating  that the field is physically stored in the database */
+  my_bool stored_in_db;
+  /* Flag indicating that the field used in a partitioning expression */
+  my_bool in_partitioning_expr;
+
+public:
+  /* The expression to compute the value of the virtual column */
+  Item *expr_item;
+  /* Text representation of the defining expression */
+  LEX_STRING expr_str;
+  /*
+    The list of items created when the defining expression for the virtual
+    column is being parsed and validated. These items are freed in the closefrm
+    function when the table containing this virtual column is removed from
+    the TABLE cache.
+    TODO. Items for all different virtual columns of a table should be put into
+    one list attached to the TABLE structure.    
+  */
+  Item *item_free_list;
+
+  Virtual_column_info()
+  : field_type((enum enum_field_types)MYSQL_TYPE_VIRTUAL),
+    stored_in_db(FALSE), in_partitioning_expr(FALSE), 
+    expr_item(NULL), item_free_list(NULL)
+  {
+    expr_str.str= NULL;
+    expr_str.length= 0;
+  };
+  ~Virtual_column_info() {}
+  enum_field_types get_real_type()
+  {
+    return field_type;
+  }
+  void set_field_type(enum_field_types fld_type)
+  {
+    /* Calling this function can only be done once. */
+    field_type= fld_type;
+  }
+  bool is_stored()
+  {
+    return stored_in_db;
+  }
+  void set_stored_in_db_flag(bool stored)
+  {
+    stored_in_db= stored;
+  }
+  bool is_in_partitioning_expr()
+  {
+    return in_partitioning_expr;
+  }
+  void mark_as_in_partitioning_expr()
+  {
+    in_partitioning_expr= TRUE;
+  }
+};
+
 class Field
 {
   Field(const Item &);				/* Prevent use of these */
@@ -57,7 +131,7 @@ public:
   uchar		*ptr;			// Position to field in record
   uchar		*null_ptr;		// Byte where null_bit is
   /*
-    Note that you can use table->in_use as replacement for current_thd member 
+    Note that you can use table->in_use as replacement for current_thd member
     only inside of val_*() and store() members (e.g. you can't use it in cons)
   */
   struct st_table *table;		// Pointer for table
@@ -67,10 +141,10 @@ public:
   /* Field is part of the following keys */
   key_map	key_start, part_of_key, part_of_key_not_clustered;
   key_map       part_of_sortkey;
-  /* 
-    We use three additional unireg types for TIMESTAMP to overcome limitation 
-    of current binary format of .frm file. We'd like to be able to support 
-    NOW() as default and on update value for such fields but unable to hold 
+  /*
+    We use three additional unireg types for TIMESTAMP to overcome limitation
+    of current binary format of .frm file. We'd like to be able to support
+    NOW() as default and on update value for such fields but unable to hold
     this info anywhere except unireg_check field. This issue will be resolved
     in more clean way with transition to new text based .frm format.
     See also comment for Field_timestamp::Field_timestamp().
@@ -103,6 +177,19 @@ public:
    */
   bool is_created_from_null_item;
 
+  /* 
+    This is additional data provided for any computed(virtual) field.
+    In particular it includes a pointer to the item by  which this field
+    can be computed from other fields.
+  */
+  Virtual_column_info *vcol_info;
+  /*
+    Flag indicating that the field is physically stored in tables
+    rather than just computed from other fields.
+    As of now, FALSE can be set only for computed virtual columns.
+  */
+  bool stored_in_db;
+
   Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
         uchar null_bit_arg, utype unireg_check_arg,
         const char *field_name_arg);
@@ -2044,6 +2131,20 @@ public:
 
   uint8 row,col,sc_length,interval_id;	// For rea_create_table
   uint	offset,pack_flag;
+
+    /* 
+    This is additinal data provided for any computed(virtual) field.
+    In particular it includes a pointer to the item by  which this field
+    can be computed from other fields.
+  */
+  Virtual_column_info *vcol_info;
+  /*
+    Flag indicating that the field is physically stored in tables
+    rather than just computed from other fields.
+    As of now, FALSE can be set only for computed virtual columns.
+  */
+  bool stored_in_db;
+
   Create_field() :after(0) {}
   Create_field(Field *field, Field *orig_field);
   /* Used to make a clone of this object for ALTER/CREATE TABLE */
@@ -2060,7 +2161,8 @@ public:
             char *decimals, uint type_modifier, Item *default_value,
             Item *on_update_value, LEX_STRING *comment, char *change,
             List<String> *interval_list, CHARSET_INFO *cs,
-            uint uint_geom_type);
+            uint uint_geom_type,
+	    Virtual_column_info *vcol_info);
 };
 
 

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2009-09-03 14:05:38 +0000
+++ b/sql/filesort.cc	2009-10-16 22:57:48 +0000
@@ -565,6 +565,8 @@ static ha_rows find_all_keys(SORTPARAM *
     {
       if ((error= select->quick->get_next()))
         break;
+      if (!error)
+        update_virtual_fields(sort_form);
       file->position(sort_form->record[0]);
       DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE););
     }
@@ -582,6 +584,8 @@ static ha_rows find_all_keys(SORTPARAM *
       else
       {
 	error=file->rnd_next(sort_form->record[0]);
+	if (!error)
+	  update_virtual_fields(sort_form);
 	if (!flag)
 	{
 	  my_store_ptr(ref_pos,ref_length,record); // Position to row

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2009-09-07 20:50:10 +0000
+++ b/sql/ha_partition.cc	2009-10-16 22:57:48 +0000
@@ -2436,7 +2436,7 @@ int ha_partition::open(const char *name,
     DBUG_RETURN(1);
   m_start_key.length= 0;
   m_rec0= table->record[0];
-  m_rec_length= table_share->reclength;
+  m_rec_length= table_share->stored_rec_length;
   alloc_len= m_tot_parts * (m_rec_length + PARTITION_BYTES_IN_POS);
   alloc_len+= table_share->max_key_length;
   if (!m_ordered_rec_buffer)

=== modified file 'sql/ha_partition.h'
--- a/sql/ha_partition.h	2009-02-19 09:01:25 +0000
+++ b/sql/ha_partition.h	2009-10-16 22:57:48 +0000
@@ -245,6 +245,7 @@ public:
     DBUG_RETURN(0);
   }
   virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
+  bool check_if_supported_virtual_columns(void) { return TRUE;}
   virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
                                           uint table_changes);
 private:

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2009-09-07 20:50:10 +0000
+++ b/sql/handler.h	2009-10-16 22:57:48 +0000
@@ -1760,6 +1760,17 @@ public:
 
   LEX_STRING *engine_name() { return hton_name(ht); }
 
+  /*
+    @brief
+    Check whether the engine supports virtual columns
+    
+    @retval
+      FALSE   if the engine does not support virtual columns    
+    @retval
+      TRUE    if the engine supports virtual columns
+  */
+  virtual bool check_if_supported_virtual_columns(void) { return FALSE;}
+
 protected:
   /* Service methods for use by storage engines. */
   void ha_statistic_increment(ulong SSV::*offset) const;

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2009-09-15 10:46:35 +0000
+++ b/sql/item.cc	2009-10-16 22:57:48 +0000
@@ -681,9 +681,24 @@ bool Item_field::register_field_in_read_
   TABLE *table= (TABLE *) arg;
   if (field->table == table || !table)
     bitmap_set_bit(field->table->read_set, field->field_index);
+  if (field->vcol_info && field->vcol_info->expr_item)
+    return field->vcol_info->expr_item->walk(&Item::register_field_in_read_map, 
+                                             1, arg);
   return 0;
 }
 
+/*
+  @brief
+  Mark field in bitmap supplied as *arg
+*/
+
+bool Item_field::register_field_in_bitmap(uchar *arg)
+{
+  MY_BITMAP *bitmap= (MY_BITMAP *) arg;
+  DBUG_ASSERT(bitmap);
+  bitmap_set_bit(bitmap, field->field_index);
+  return 0;
+}
 
 bool Item::check_cols(uint c)
 {
@@ -4453,6 +4468,21 @@ error:
   return TRUE;
 }
 
+/*
+  @brief
+  Mark virtual columns as used in a partitioning expression 
+*/
+
+bool Item_field::vcol_in_partition_func_processor(uchar *int_arg)
+{
+  DBUG_ASSERT(fixed);
+  if (field->vcol_info)
+  {
+    field->vcol_info->mark_as_in_partitioning_expr();
+  }
+  return FALSE;
+}
+
 
 Item *Item_field::safe_charset_converter(CHARSET_INFO *tocs)
 {

=== modified file 'sql/item.h'
--- a/sql/item.h	2009-09-15 10:46:35 +0000
+++ b/sql/item.h	2009-10-16 22:57:48 +0000
@@ -18,6 +18,24 @@
 #pragma interface			/* gcc class implementation */
 #endif
 
+inline
+bool trace_unsupported_func(const char *where, const char *processor_name)
+{
+  char buff[64];                                                         
+  sprintf(buff, "%s::%s", where, processor_name);
+  DBUG_ENTER(buff);
+  sprintf(buff, "%s returns TRUE: unsupported function", processor_name);
+  DBUG_PRINT("info", (buff));
+  DBUG_RETURN(TRUE);
+}
+
+inline
+bool trace_unsupported_by_check_vcol_func_processor(const char *where)
+{
+  return trace_unsupported_func(where, "check_vcol_func_processor");
+}
+
+
 class Protocol;
 struct TABLE_LIST;
 void item_init(void);			/* Init item functions */
@@ -895,6 +913,11 @@ public:
   virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; }
   virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; }
   /*
+    The next function differs from the previous one that a bitmap to be updated
+    is passed as uchar *arg.
+  */
+  virtual bool register_field_in_bitmap(uchar *arg) { return 0; }
+  /*
     Check if a partition function is allowed
     SYNOPSIS
       check_partition_func_processor()
@@ -946,11 +969,43 @@ public:
     fields.
   */
   virtual bool check_partition_func_processor(uchar *bool_arg) { return TRUE;}
+  /*
+    @brief
+    Processor used to mark virtual columns used in partitioning expression
+
+    @param
+    arg     always ignored
+
+    @retval
+      FALSE      always
+  */
+  virtual bool vcol_in_partition_func_processor(uchar *arg)
+  {
+    return FALSE;
+  }
+
   virtual bool subst_argument_checker(uchar **arg)
-  { 
+  {
     if (*arg)
-      *arg= NULL; 
-    return TRUE;     
+      *arg= NULL;
+    return TRUE;
+  }
+  /*
+    @brief
+    Processor used to check acceptability of an item in the defining
+    expression for a virtual column 
+    
+    @param
+      arg     always ignored
+      
+    @retval
+      FALSE    the item is accepted in the definition of a virtual column
+    @retval 
+      TRUE     otherwise
+  */
+  virtual bool check_vcol_func_processor(uchar *arg)
+  {
+    return trace_unsupported_by_check_vcol_func_processor(full_name());
   }
 
   virtual Item *equal_fields_propagator(uchar * arg) { return this; }
@@ -1327,6 +1382,10 @@ public:
   {
     return value_item->send(protocol, str);
   }
+  bool check_vcol_func_processor(uchar *arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("name_const");
+  }
 };
 
 bool agg_item_collations(DTCollation &c, const char *name,
@@ -1346,6 +1405,7 @@ public:
   virtual Item_num *neg()= 0;
   Item *safe_charset_converter(CHARSET_INFO *tocs);
   bool check_partition_func_processor(uchar *int_arg) { return FALSE;}
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 };
 
 #define NO_CACHED_FIELD_INDEX ((uint)(-1))
@@ -1505,7 +1565,10 @@ public:
   bool collect_item_field_processor(uchar * arg);
   bool find_item_in_field_list_processor(uchar *arg);
   bool register_field_in_read_map(uchar *arg);
+  bool register_field_in_bitmap(uchar *arg);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool vcol_in_partition_func_processor(uchar *bool_arg);
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
   bool enumerate_field_refs_processor(uchar *arg);
   void cleanup();
   bool result_as_longlong()
@@ -1566,6 +1629,7 @@ public:
 
   Item *safe_charset_converter(CHARSET_INFO *tocs);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 };
 
 class Item_null_result :public Item_null
@@ -1579,7 +1643,11 @@ public:
     save_in_field(result_field, no_conversions);
   }
   bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
-};  
+  bool check_vcol_func_processor(uchar *arg)
+  {
+    return trace_unsupported_by_check_vcol_func_processor(full_name());
+  }
+};
 
 /* Item represents one placeholder ('?') of prepared statement */
 
@@ -1720,6 +1788,7 @@ public:
   /** Item is a argument to a limit clause. */
   bool limit_clause_param;
   void set_param_type_and_swap_value(Item_param *from);
+
 };
 
 
@@ -1755,6 +1824,7 @@ public:
   { return (uint)(max_length - test(value < 0)); }
   bool eq(const Item *, bool binary_cmp) const;
   bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
+  bool check_vcol_func_processor(uchar arg) { return FALSE;}
 };
 
 
@@ -1773,6 +1843,7 @@ public:
   Item_num *neg ();
   uint decimal_precision() const { return max_length; }
   bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 };
 
 
@@ -1814,6 +1885,7 @@ public:
   bool eq(const Item *, bool binary_cmp) const;
   void set_decimal_value(my_decimal *value_par);
   bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 };
 
 
@@ -1971,6 +2043,7 @@ public:
   }
   virtual void print(String *str, enum_query_type query_type);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 
   /**
     Return TRUE if character-set-introducer was explicitly specified in the
@@ -2024,7 +2097,7 @@ double_from_string_with_check (CHARSET_I
 class Item_static_string_func :public Item_string
 {
   const char *func_name;
-public:
+ public:
   Item_static_string_func(const char *name_par, const char *str, uint length,
                           CHARSET_INFO *cs,
                           Derivation dv= DERIVATION_COERCIBLE)
@@ -2038,6 +2111,10 @@ public:
   }
 
   bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
+  bool check_vcol_func_processor(uchar *arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name);
+  }
 };
 
 
@@ -2049,6 +2126,10 @@ public:
                                   CHARSET_INFO *cs= NULL):
     Item_string(name_arg, length, cs)
   {}
+  bool check_vcol_func_processor(uchar *arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("safe_string");
+  }
 };
 
 
@@ -2128,6 +2209,7 @@ public:
   bool eq(const Item *item, bool binary_cmp) const;
   virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 };
 
 
@@ -2158,6 +2240,7 @@ public:
     save_in_field(result_field, no_conversions);
   }
   void cleanup();
+  bool check_vcol_func_processor(uchar *arg) { return FALSE;}
 };
 
 
@@ -2287,7 +2370,10 @@ public:
     if (ref && result_type() == ROW_RESULT)
       (*ref)->bring_value();
   }
-
+  bool check_vcol_func_processor(uchar *arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("ref");
+  }
 };
 
 
@@ -2563,6 +2649,10 @@ public:
   table_map used_tables() const { return (table_map) 1L; }
   bool const_item() const { return 0; }
   bool is_null() { return null_value; }
+  bool check_vcol_func_processor(uchar *arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("copy");
+  }
 
   /*  
     Override the methods below as pure virtual to make sure all the 
@@ -2805,6 +2895,10 @@ public:
     return arg->walk(processor, walk_subquery, args) ||
 	    (this->*processor)(args);
   }
+  bool check_vcol_func_processor(uchar *arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("values");
+  }
 };
 
 
@@ -2901,6 +2995,10 @@ private:
     BEFORE INSERT of BEFORE UPDATE trigger.
   */
   bool read_only;
+  virtual bool check_vcol_func_processor(uchar *arg)
+  {
+    return trace_unsupported_by_check_vcol_func_processor("trigger");
+  }
 };
 
 
@@ -2960,6 +3058,11 @@ public:
   {
     return this == item;
   }
+  bool check_vcol_func_processor(uchar *arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("cache");
+  }
+
 };
 
 

=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc	2009-09-07 20:50:10 +0000
+++ b/sql/item_func.cc	2009-10-16 22:57:48 +0000
@@ -3940,10 +3940,30 @@ bool Item_func_set_user_var::register_fi
     TABLE *table= (TABLE *) arg;
     if (result_field->table == table || !table)
       bitmap_set_bit(result_field->table->read_set, result_field->field_index);
+    if (result_field->vcol_info)
+      return result_field->vcol_info->
+               expr_item->walk(&Item::register_field_in_read_map, 1, arg);
   }
   return 0;
 }
 
+/*
+  Mark field in bitmap supplied as *arg
+
+*/
+
+bool Item_func_set_user_var::register_field_in_bitmap(uchar *arg)
+{
+  MY_BITMAP *bitmap = (MY_BITMAP *) arg;
+  DBUG_ASSERT(bitmap);
+  if (result_field)
+  {
+    if (!bitmap)
+      return 1;
+    bitmap_set_bit(bitmap, result_field->field_index);
+  }
+  return 0;
+}
 
 /**
   Set value to user variable.

=== modified file 'sql/item_func.h'
--- a/sql/item_func.h	2009-09-07 20:50:10 +0000
+++ b/sql/item_func.h	2009-10-16 22:57:48 +0000
@@ -339,6 +339,7 @@ public:
   void fix_length_and_dec();
   bool fix_fields(THD *thd, Item **ref);
   longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
+  bool check_vcol_func_processor(uchar *int_arg) { return TRUE;}
 };
 
 
@@ -399,6 +400,7 @@ public:
   Item_func_additive_op(Item *a,Item *b) :Item_num_op(a,b) {}
   void result_precision();
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -434,6 +436,7 @@ public:
   my_decimal *decimal_op(my_decimal *);
   void result_precision();
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -466,6 +469,7 @@ public:
   }
 
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -480,6 +484,7 @@ public:
   void result_precision();
   void fix_length_and_dec();
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -496,6 +501,7 @@ public:
   void fix_num_length_and_dec();
   uint decimal_precision() const { return args[0]->decimal_precision(); }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -509,6 +515,7 @@ public:
   const char *func_name() const { return "abs"; }
   void fix_length_and_dec();
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 // A class to handle logarithmic and trigonometric functions
@@ -664,6 +671,7 @@ public:
   double real_op();
   my_decimal *decimal_op(my_decimal *);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -676,6 +684,7 @@ public:
   double real_op();
   my_decimal *decimal_op(my_decimal *);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 /* This handles round and truncate */
@@ -707,6 +716,10 @@ public:
   void update_used_tables();
   bool fix_fields(THD *thd, Item **ref);
   void cleanup() { first_eval= TRUE; Item_real_func::cleanup(); }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 private:
   void seed_random (Item * val);  
 };
@@ -989,6 +1002,10 @@ public:
       max_length= args[0]->max_length;
   }
   bool fix_fields(THD *thd, Item **ref);
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1002,6 +1019,10 @@ public:
   const char *func_name() const { return "benchmark"; }
   void fix_length_and_dec() { max_length=1; maybe_null=0; }
   virtual void print(String *str, enum_query_type query_type);
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1017,6 +1038,10 @@ public:
     used_tables_cache|= RAND_TABLE_BIT;
   }
   longlong val_int();
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1266,6 +1291,10 @@ class Item_func_get_lock :public Item_in
   longlong val_int();
   const char *func_name() const { return "get_lock"; }
   void fix_length_and_dec() { max_length=1; maybe_null=1;}
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 class Item_func_release_lock :public Item_int_func
@@ -1276,6 +1305,10 @@ public:
   longlong val_int();
   const char *func_name() const { return "release_lock"; }
   void fix_length_and_dec() { max_length=1; maybe_null=1;}
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 /* replication functions */
@@ -1289,6 +1322,10 @@ public:
   longlong val_int();
   const char *func_name() const { return "master_pos_wait"; }
   void fix_length_and_dec() { max_length=21; maybe_null=1;}
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1360,6 +1397,7 @@ public:
   }
   void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
   bool register_field_in_read_map(uchar *arg);
+  bool register_field_in_bitmap(uchar *arg);
   bool set_entry(THD *thd, bool create_if_not_exists);
   void cleanup();
 };
@@ -1534,6 +1572,11 @@ public:
 
   bool fix_index();
   void init_search(bool no_order);
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    /* TODO: consider adding in support for the MATCH-based virtual columns */
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1553,6 +1596,17 @@ public:
   longlong val_int();
   const char *func_name() const { return "is_free_lock"; }
   void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+#if 0
+    DBUG_ENTER("Item_func_is_free_lock::check_vcol_func_processor");
+    DBUG_PRINT("info",
+      ("check_vcol_func_processor returns TRUE: unsupported function"));
+    DBUG_RETURN(TRUE);
+#else
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+#endif
+  }
 };
 
 class Item_func_is_used_lock :public Item_int_func
@@ -1563,6 +1617,10 @@ public:
   longlong val_int();
   const char *func_name() const { return "is_used_lock"; }
   void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;}
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 /* For type casts */
@@ -1582,6 +1640,11 @@ public:
   longlong val_int();
   const char *func_name() const { return "row_count"; }
   void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1690,6 +1753,10 @@ public:
   {
     return sp_result_field;
   }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1700,6 +1767,10 @@ public:
   longlong val_int();
   const char *func_name() const { return "found_rows"; }
   void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -1714,5 +1785,9 @@ public:
   void fix_length_and_dec()
   { max_length= 21; unsigned_flag=1; }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 

=== modified file 'sql/item_row.h'
--- a/sql/item_row.h	2008-02-22 10:30:33 +0000
+++ b/sql/item_row.h	2009-10-16 22:57:48 +0000
@@ -76,4 +76,5 @@ public:
   bool check_cols(uint c);
   bool null_inside() { return with_null; };
   void bring_value();
-};
+  bool check_vcol_func_processor(uchar *int_arg) {return FALSE; } 
+ };

=== modified file 'sql/item_strfunc.h'
--- a/sql/item_strfunc.h	2009-09-07 20:50:10 +0000
+++ b/sql/item_strfunc.h	2009-10-16 22:57:48 +0000
@@ -344,6 +344,10 @@ public:
   String *val_str(String *);
   void fix_length_and_dec() { maybe_null=1; max_length = 13; }
   const char *func_name() const { return "encrypt"; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 #include "sql_crypt.h"
@@ -381,6 +385,11 @@ public:
     call
   */
   virtual const char *fully_qualified_func_name() const = 0;
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(
+                                           fully_qualified_func_name());
+  }
 };
 
 
@@ -644,6 +653,10 @@ public:
     maybe_null=1;
     max_length=MAX_BLOB_WIDTH;
   }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -840,5 +853,9 @@ public:
   }
   const char *func_name() const{ return "uuid"; }
   String *val_str(String *);
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 

=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h	2009-08-31 20:02:09 +0000
+++ b/sql/item_subselect.h	2009-10-16 22:57:48 +0000
@@ -136,6 +136,10 @@ public:
   bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
   bool mark_as_eliminated_processor(uchar *arg);
   bool enumerate_field_refs_processor(uchar *arg);
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("subselect");
+  }
 
   /**
     Get the SELECT_LEX structure associated with this Item.

=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h	2009-09-15 10:46:35 +0000
+++ b/sql/item_sum.h	2009-10-16 22:57:48 +0000
@@ -399,6 +399,10 @@ public:  
   Item *get_arg(int i) { return args[i]; }
   Item *set_arg(int i, THD *thd, Item *new_val);
   uint get_arg_count() { return arg_count; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name()); 
+  }
 };
 
 
@@ -679,6 +683,10 @@ public:
   }
   void fix_length_and_dec() {}
   enum Item_result result_type () const { return hybrid_type; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("avg_field");
+  }
 };
 
 
@@ -747,6 +755,10 @@ public:
   }
   void fix_length_and_dec() {}
   enum Item_result result_type () const { return hybrid_type; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("var_field");
+  }
 };
 
 

=== modified file 'sql/item_timefunc.h'
--- a/sql/item_timefunc.h	2009-02-07 15:50:31 +0000
+++ b/sql/item_timefunc.h	2009-10-16 22:57:48 +0000
@@ -70,6 +70,7 @@ public:
   enum_monotonicity_info get_monotonicity_info() const;
   longlong val_int_endpoint(bool left_endp, bool *incl_endp);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -86,6 +87,7 @@ public:
     maybe_null=1; 
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -111,6 +113,7 @@ public:
     maybe_null=1; 
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -124,6 +127,7 @@ public:
   enum Item_result result_type () const { return STRING_RESULT; }
   void fix_length_and_dec();
   bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
+  bool check_vcol_func_processor(uchar *int_arg) {return FALSE;}
 };
 
 
@@ -140,6 +144,7 @@ public:
     maybe_null=1; 
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -156,6 +161,7 @@ public:
     maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -172,6 +178,7 @@ public:
     maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -188,6 +195,7 @@ public:
      maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -204,6 +212,7 @@ public:
     maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -234,6 +243,7 @@ public:
     maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -252,6 +262,7 @@ public:
     maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -282,6 +293,7 @@ public:
     maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 class Item_func_dayname :public Item_func_weekday
@@ -294,6 +306,7 @@ class Item_func_dayname :public Item_fun
   enum Item_result result_type () const { return STRING_RESULT; }
   void fix_length_and_dec();
   bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -310,6 +323,14 @@ public:
     decimals=0;
     max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
   }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    /*
+      TODO: Allow UNIX_TIMESTAMP called with an argument to be a part
+      of the expression for a virtual column
+    */
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -325,6 +346,7 @@ public:
     max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -445,6 +467,10 @@ public:
   */
   virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
   bool result_as_longlong() { return TRUE; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -481,6 +507,10 @@ public:
   void fix_length_and_dec();
   bool get_date(MYSQL_TIME *res, uint fuzzy_date);
   virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -521,6 +551,10 @@ public:
   void fix_length_and_dec();
   bool get_date(MYSQL_TIME *res, uint fuzzy_date);
   virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 
@@ -578,6 +612,7 @@ public:
   const char *func_name() const { return "from_days"; }
   bool get_date(MYSQL_TIME *res, uint fuzzy_date);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -705,6 +740,7 @@ class Item_extract :public Item_int_func
   bool eq(const Item *item, bool binary_cmp) const;
   virtual void print(String *str, enum_query_type query_type);
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 
@@ -953,6 +989,7 @@ public:
     maybe_null=1;
   }
   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
 };
 
 

=== modified file 'sql/item_xmlfunc.cc'
--- a/sql/item_xmlfunc.cc	2009-09-07 20:50:10 +0000
+++ b/sql/item_xmlfunc.cc	2009-10-16 22:57:48 +0000
@@ -220,6 +220,11 @@ public:
     collation.collation= pxml->charset();
   }
   const char *func_name() const { return "nodeset"; }
+  bool check_vcol_func_processor(uchar *int_arg)
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
+
 };
 
 
@@ -526,6 +531,10 @@ public:
   enum Type type() const { return XPATH_NODESET_CMP; };
   const char *func_name() const { return "xpath_nodeset_to_const_comparator"; }
   bool is_bool_func() { return 1; }
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 
   longlong val_int()
   {

=== modified file 'sql/item_xmlfunc.h'
--- a/sql/item_xmlfunc.h	2007-11-21 12:00:09 +0000
+++ b/sql/item_xmlfunc.h	2009-10-16 22:57:48 +0000
@@ -40,6 +40,10 @@ public:
   }
   void fix_length_and_dec();
   String *parse_xml(String *raw_xml, String *parsed_xml_buf);
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor(func_name());
+  }
 };
 
 

=== modified file 'sql/lex.h'
--- a/sql/lex.h	2009-09-07 20:50:10 +0000
+++ b/sql/lex.h	2009-10-16 22:57:48 +0000
@@ -62,6 +62,7 @@ static SYMBOL symbols[] = {
   { "ALL",		SYM(ALL)},
   { "ALGORITHM",	SYM(ALGORITHM_SYM)},
   { "ALTER",		SYM(ALTER)},
+  { "ALWAYS",           SYM(ALWAYS_SYM)},
   { "ANALYZE",		SYM(ANALYZE_SYM)},
   { "AND",		SYM(AND_SYM)},
   { "ANY",              SYM(ANY_SYM)},
@@ -220,6 +221,7 @@ static SYMBOL symbols[] = {
   { "FULL",		SYM(FULL)},
   { "FULLTEXT",		SYM(FULLTEXT_SYM)},
   { "FUNCTION",		SYM(FUNCTION_SYM)},
+  { "GENERATED",        SYM(GENERATED_SYM)},
   { "GEOMETRY",		SYM(GEOMETRY_SYM)},
   { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
   { "GET_FORMAT",       SYM(GET_FORMAT)},
@@ -385,14 +387,16 @@ static SYMBOL symbols[] = {
   { "OUTFILE",		SYM(OUTFILE)},
   { "OWNER",		SYM(OWNER_SYM)},
   { "PACK_KEYS",	SYM(PACK_KEYS_SYM)},
-  { "PARSER",           SYM(PARSER_SYM)},
   { "PAGE",	        SYM(PAGE_SYM)},
   { "PAGE_CHECKSUM",	SYM(PAGE_CHECKSUM_SYM)},
+  { "PARSER",           SYM(PARSER_SYM)},
+  { "PARSE_VCOL_EXPR",  SYM(PARSE_VCOL_EXPR_SYM)},
   { "PARTIAL",		SYM(PARTIAL)},
   { "PARTITION",        SYM(PARTITION_SYM)},
   { "PARTITIONING",     SYM(PARTITIONING_SYM)},
   { "PARTITIONS",       SYM(PARTITIONS_SYM)},
   { "PASSWORD",		SYM(PASSWORD)},
+  { "PERSISTENT",	SYM(PERSISTENT_SYM)},
   { "PHASE",            SYM(PHASE_SYM)},
   { "PLUGIN",           SYM(PLUGIN_SYM)},
   { "PLUGINS",          SYM(PLUGINS_SYM)},
@@ -581,13 +585,14 @@ static SYMBOL symbols[] = {
   { "VARCHARACTER",	SYM(VARCHAR)},
   { "VARIABLES",	SYM(VARIABLES)},
   { "VARYING",		SYM(VARYING)},
+  { "VIEW",		SYM(VIEW_SYM)},
+  { "VIRTUAL",          SYM(VIRTUAL_SYM)},
   { "WAIT",		SYM(WAIT_SYM)},
   { "WARNINGS",		SYM(WARNINGS)},
   { "WEEK",		SYM(WEEK_SYM)},
   { "WHEN",		SYM(WHEN_SYM)},
   { "WHERE",		SYM(WHERE)},
   { "WHILE",            SYM(WHILE_SYM)},
-  { "VIEW",		SYM(VIEW_SYM)},
   { "WITH",		SYM(WITH)},
   { "WORK",		SYM(WORK_SYM)},
   { "WRAPPER",		SYM(WRAPPER_SYM)},

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-09-15 10:46:35 +0000
+++ b/sql/mysql_priv.h	2009-10-16 22:57:48 +0000
@@ -1350,6 +1350,7 @@ 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(TABLE *table, bool ignore_stored= FALSE);
 
 #endif /* MYSQL_SERVER */
 
@@ -1470,14 +1471,16 @@ bool add_field_to_list(THD *thd, LEX_STR
 		       LEX_STRING *comment,
 		       char *change, List<String> *interval_list,
 		       CHARSET_INFO *cs,
-		       uint uint_geom_type);
+		       uint uint_geom_type,
+                       Virtual_column_info *vcol_info);
 Create_field * new_create_field(THD *thd, char *field_name, enum_field_types type,
 				char *length, char *decimals,
 				uint type_modifier, 
 				Item *default_value, Item *on_update_value,
 				LEX_STRING *comment, char *change, 
 				List<String> *interval_list, CHARSET_INFO *cs,
-				uint uint_geom_type);
+				uint uint_geom_type,
+				Virtual_column_info *vcol_info);
 void store_position_for_column(const char *name);
 bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
 bool push_new_name_resolution_context(THD *thd,

=== modified file 'sql/procedure.h'
--- a/sql/procedure.h	2008-03-21 15:48:28 +0000
+++ b/sql/procedure.h	2009-10-16 22:57:48 +0000
@@ -42,7 +42,11 @@ public:
   {
     init_make_field(tmp_field,field_type());
   }
-  unsigned int size_of() { return sizeof(*this);}  
+  unsigned int size_of() { return sizeof(*this);}
+  bool check_vcol_func_processor(uchar *int_arg) 
+  {
+    return trace_unsupported_by_check_vcol_func_processor("proc"); 
+  }
 };
 
 class Item_proc_real :public Item_proc

=== modified file 'sql/records.cc'
--- a/sql/records.cc	2009-05-06 12:03:24 +0000
+++ b/sql/records.cc	2009-10-16 22:57:48 +0000
@@ -323,6 +323,7 @@ static int rr_quick(READ_RECORD *info)
       break;
     }
   }
+  update_virtual_fields(info->table);
   return tmp;
 }
 
@@ -395,6 +396,8 @@ int rr_sequential(READ_RECORD *info)
       break;
     }
   }
+  if (!tmp)
+    update_virtual_fields(info->table);
   return tmp;
 }
 

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2009-09-15 11:55:37 +0000
+++ b/sql/share/errmsg.txt	2009-10-16 22:57:48 +0000
@@ -6206,3 +6206,30 @@ ER_TOO_MANY_CONCURRENT_TRXS
 
 WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED
   eng "Non-ASCII separator arguments are not fully supported"
+
+ER_VCOL_BASED_ON_VCOL
+        eng "A computed column cannot be based on a computed column"
+
+ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+        eng "Function or expression is not allowed for column '%s'."
+
+ER_DATA_CONVERSION_ERROR_FOR_VIRTUAL_COLUMN
+        eng "Generated value for computed column '%s' cannot be converted to type '%s'."
+
+ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN
+        eng "Primary key cannot be defined upon a computed column."
+
+ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+        eng "Key/Index cannot be defined on a non-stored computed column."
+
+ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN
+        eng "Cannot define foreign key with %s clause on a computed column."
+
+ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
+        eng "The value specified for computed column '%s' in table '%s' ignored."
+
+ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
+        eng "'%s' is not yet supported for computed columns."
+
+ER_CONST_EXPR_IN_VCOL
+         eng "Constant expression in computed column function is not allowed."

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2009-09-15 10:46:35 +0000
+++ b/sql/sp_head.cc	2009-10-16 22:57:48 +0000
@@ -816,6 +816,8 @@ sp_head::create_result_field(uint field_
                       m_return_field_def.interval,
                       field_name ? field_name : (const char *) m_name.str);
 
+  field->vcol_info= m_return_field_def.vcol_info;
+  field->stored_in_db= m_return_field_def.stored_in_db;
   if (field)
     field->init(table);
   
@@ -2197,7 +2199,8 @@ sp_head::fill_field_definition(THD *thd,
                       &lex->interval_list,
                       lex->charset ? lex->charset :
                                      thd->variables.collation_database,
-                      lex->uint_geom_type))
+                      lex->uint_geom_type,
+		      lex->vcol_info))
     return TRUE;
 
   if (field_def->interval_list.elements)

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2009-09-07 20:50:10 +0000
+++ b/sql/sql_base.cc	2009-10-16 22:57:48 +0000
@@ -5594,6 +5594,9 @@ static void update_field_dependencies(TH
     table->covering_keys.intersect(field->part_of_key);
     table->merge_keys.merge(field->part_of_key);
 
+    if (field->vcol_info)
+      table->mark_virtual_col(field);
+
     if (thd->mark_used_columns == MARK_COLUMNS_READ)
       current_bitmap= table->read_set;
     else
@@ -7887,6 +7890,12 @@ insert_fields(THD *thd, Name_resolution_
       {
         /* Mark fields as used to allow storage engine to optimze access */
         bitmap_set_bit(field->table->read_set, field->field_index);
+        /*
+          Mark virtual fields for write and others that the virtual fields
+          depend on for read.
+        */
+        if (field->vcol_info)
+          field->table->mark_virtual_col(field);
         if (table)
         {
           table->covering_keys.intersect(field->part_of_key);
@@ -8098,7 +8107,10 @@ fill_record(THD * thd, List<Item> &field
   Item *value, *fld;
   Item_field *field;
   TABLE *table= 0;
+  List<TABLE> tbl_list;
+  bool abort_on_warning_saved= thd->abort_on_warning;
   DBUG_ENTER("fill_record");
+  tbl_list.empty();
 
   /*
     Reset the table->auto_increment_field_not_null as it is valid for
@@ -8132,14 +8144,54 @@ fill_record(THD * thd, List<Item> &field
     table= rfield->table;
     if (rfield == table->next_number_field)
       table->auto_increment_field_not_null= TRUE;
+    if (rfield->vcol_info && 
+        value->type() != Item::DEFAULT_VALUE_ITEM && 
+        value->type() != Item::NULL_ITEM &&
+        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
+    {
+      thd->abort_on_warning= FALSE;
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
+                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
+                          rfield->field_name, table->s->table_name.str);
+      thd->abort_on_warning= abort_on_warning_saved;
+    }
     if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
     {
       my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
       goto err;
     }
+    tbl_list.push_back(table);
+  }
+  /* Update virtual fields*/
+  thd->abort_on_warning= FALSE;
+  if (tbl_list.head())
+  {
+    List_iterator_fast<TABLE> it(tbl_list);
+    TABLE *prev_table= 0;
+    while ((table= it++))
+    {
+      /*
+        Do simple optimization to prevent unnecessary re-generating 
+        values for virtual fields
+      */
+      if (table != prev_table)
+      {
+        prev_table= table;
+        if (table->vfield)
+        {
+          if (update_virtual_fields(table, TRUE))
+          {
+            goto err;
+          }
+        }
+      }
+    }
   }
+  thd->abort_on_warning= abort_on_warning_saved;
   DBUG_RETURN(thd->is_error());
 err:
+  thd->abort_on_warning= abort_on_warning_saved;
   if (table)
     table->auto_increment_field_not_null= FALSE;
   DBUG_RETURN(TRUE);
@@ -8175,9 +8227,31 @@ fill_record_n_invoke_before_triggers(THD
                                      Table_triggers_list *triggers,
                                      enum trg_event_type event)
 {
-  return (fill_record(thd, fields, values, ignore_errors) ||
-          (triggers && triggers->process_triggers(thd, event,
-                                                  TRG_ACTION_BEFORE, TRUE)));
+  bool result;
+  result= (fill_record(thd, fields, values, ignore_errors) ||
+           (triggers && triggers->process_triggers(thd, event,
+                                                   TRG_ACTION_BEFORE, TRUE)));
+  /*
+    Re-calculate virtual fields to cater for cases when base columns are
+    updated by the triggers.
+  */
+  if (!result && triggers)
+  {
+    TABLE *table= 0;
+    List_iterator_fast<Item> f(fields);
+    Item *fld;
+    Item_field *item_field;
+    if (fields.elements)
+    {
+      fld= (Item_field*)f++;
+      item_field= fld->filed_for_view_update();
+      if (item_field && item_field->field &&
+          (table= item_field->field->table) &&
+        table->vfield)
+        result= update_virtual_fields(table, TRUE);
+    }
+  }
+  return result;
 }
 
 
@@ -8205,11 +8279,14 @@ bool
 fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
 {
   List_iterator_fast<Item> v(values);
+  List<TABLE> tbl_list;
   Item *value;
   TABLE *table= 0;
+  bool abort_on_warning_saved= thd->abort_on_warning;
   DBUG_ENTER("fill_record");
 
   Field *field;
+  tbl_list.empty();
   /*
     Reset the table->auto_increment_field_not_null as it is valid for
     only one row.
@@ -8229,12 +8306,52 @@ fill_record(THD *thd, Field **ptr, List<
     table= field->table;
     if (field == table->next_number_field)
       table->auto_increment_field_not_null= TRUE;
+    if (field->vcol_info && 
+        value->type() != Item::DEFAULT_VALUE_ITEM && 
+        value->type() != Item::NULL_ITEM &&
+        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
+    {
+      thd->abort_on_warning= FALSE;
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
+                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
+                          field->field_name, table->s->table_name.str);
+      thd->abort_on_warning= abort_on_warning_saved;
+    }
     if (value->save_in_field(field, 0) < 0)
       goto err;
+    tbl_list.push_back(table);
+  }
+  /* Update virtual fields*/
+  thd->abort_on_warning= FALSE;
+  if (tbl_list.head())
+  {
+    List_iterator_fast<TABLE> t(tbl_list);
+    TABLE *prev_table= 0;
+    while ((table= t++))
+    {
+      /*
+        Do simple optimization to prevent unnecessary re-generating 
+        values for virtual fields
+      */
+      if (table != prev_table)
+      {
+        prev_table= table;
+        if (table->vfield)
+        {
+          if (update_virtual_fields(table, TRUE))
+          {
+            goto err;
+          }
+        }
+      }
+    }
   }
+  thd->abort_on_warning= abort_on_warning_saved;
   DBUG_RETURN(thd->is_error());
 
 err:
+  thd->abort_on_warning= abort_on_warning_saved;
   if (table)
     table->auto_increment_field_not_null= FALSE;
   DBUG_RETURN(TRUE);
@@ -8270,9 +8387,22 @@ fill_record_n_invoke_before_triggers(THD
                                      Table_triggers_list *triggers,
                                      enum trg_event_type event)
 {
-  return (fill_record(thd, ptr, values, ignore_errors) ||
-          (triggers && triggers->process_triggers(thd, event,
-                                                  TRG_ACTION_BEFORE, TRUE)));
+  bool result;
+  result= (fill_record(thd, ptr, values, ignore_errors) ||
+           (triggers && triggers->process_triggers(thd, event,
+                                                   TRG_ACTION_BEFORE, TRUE)));
+  /*
+    Re-calculate virtual fields to cater for cases when base columns are
+    updated by the triggers.
+  */
+  if (!result && triggers && *ptr)
+  {
+    TABLE *table= (*ptr)->table;
+    if (table->vfield)
+      result= update_virtual_fields(table, TRUE);
+  }
+  return result;
+
 }
 
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2009-09-15 10:46:35 +0000
+++ b/sql/sql_class.cc	2009-10-16 22:57:48 +0000
@@ -194,6 +194,59 @@ bool foreign_key_prefix(Key *a, Key *b)
 #endif
 }
 
+/*
+  @brief
+  Check if the foreign key options are compatible with the specification
+  of the columns on which the key is created
+
+  @retval
+    FALSE   The foreign key options are compatible with key columns
+  @retval
+    TRUE    Otherwise
+*/
+bool Foreign_key::validate(List<Create_field> &table_fields)
+{
+  Create_field  *sql_field;
+  Key_part_spec *column;
+  List_iterator<Key_part_spec> cols(columns);
+  List_iterator<Create_field> it(table_fields);
+  DBUG_ENTER("Foreign_key::validate");
+  while ((column= cols++))
+  {
+    it.rewind();
+    while ((sql_field= it++) &&
+           my_strcasecmp(system_charset_info,
+                         column->field_name,
+                         sql_field->field_name)) {}
+    if (!sql_field)
+    {
+      my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name);
+      DBUG_RETURN(TRUE);
+    }
+    if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
+    {
+      if (delete_opt == FK_OPTION_SET_NULL)
+      {
+        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0), 
+                 "ON DELETE SET NULL");
+        DBUG_RETURN(TRUE);
+      }
+      if (update_opt == FK_OPTION_SET_NULL)
+      {
+        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0), 
+                 "ON UPDATE SET NULL");
+        DBUG_RETURN(TRUE);
+      }
+      if (update_opt == FK_OPTION_CASCADE)
+      {
+        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0), 
+                 "ON UPDATE CASCADE");
+        DBUG_RETURN(TRUE);
+      }
+    }
+  }
+  DBUG_RETURN(FALSE);
+}
 
 /****************************************************************************
 ** Thread specific functions

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2009-09-15 10:46:35 +0000
+++ b/sql/sql_class.h	2009-10-16 22:57:48 +0000
@@ -249,6 +249,8 @@ public:
   */
   virtual Key *clone(MEM_ROOT *mem_root) const
   { return new (mem_root) Foreign_key(*this, mem_root); }
+  /* Used to validate foreign key options */
+  bool validate(List<Create_field> &table_fields);
 };
 
 typedef struct st_mysql_lock

=== modified file 'sql/sql_handler.cc'
--- a/sql/sql_handler.cc	2009-07-15 23:23:57 +0000
+++ b/sql/sql_handler.cc	2009-10-16 22:57:48 +0000
@@ -666,6 +666,8 @@ retry:
       }
       goto ok;
     }
+    /* Generate values for virtual fields */
+    update_virtual_fields(table);
     if (cond && !cond->val_int())
       continue;
     if (num_rows >= offset_limit_cnt)

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-09-07 20:50:10 +0000
+++ b/sql/sql_insert.cc	2009-10-16 22:57:48 +0000
@@ -280,6 +280,9 @@ static int check_insert_fields(THD *thd,
       }
     }
   }
+  /* Mark virtual columns used in the insert statement */
+  if (table->vfield)
+    table->mark_virtual_columns_for_write();
   // For the values we need select_priv
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2009-09-15 10:46:35 +0000
+++ b/sql/sql_lex.cc	2009-10-16 22:57:48 +0000
@@ -340,6 +340,7 @@ void lex_start(THD *thd)
   lex->reset_query_tables_list(FALSE);
   lex->expr_allows_subselect= TRUE;
   lex->use_only_table_context= FALSE;
+  lex->parse_vcol_expr= FALSE;
 
   lex->name.str= 0;
   lex->name.length= 0;

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2009-09-15 10:46:35 +0000
+++ b/sql/sql_lex.h	2009-10-16 22:57:48 +0000
@@ -1544,6 +1544,7 @@ typedef struct st_lex : public Query_tab
   LEX_USER *grant_user;
   XID *xid;
   THD *thd;
+  Virtual_column_info *vcol_info;
 
   /* maintain a list of used plugins for this LEX */
   DYNAMIC_ARRAY plugins;
@@ -1626,6 +1627,14 @@ typedef struct st_lex : public Query_tab
     syntax error back.
   */
   bool expr_allows_subselect;
+  /*
+    A special command "PARSE_VCOL_EXPR" is defined for the parser 
+    to translate a defining expression of a virtual column into an 
+    Item object.
+    The following flag is used to prevent other applications to use 
+    this command.
+  */
+  bool parse_vcol_expr;
 
   thr_lock_type lock_option;
   enum SSL_type ssl_type;			/* defined in violite.h */

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-09-15 10:46:35 +0000
+++ b/sql/sql_parse.cc	2009-10-16 22:57:48 +0000
@@ -6055,7 +6055,8 @@ bool add_field_to_list(THD *thd, LEX_STR
                        LEX_STRING *comment,
 		       char *change,
                        List<String> *interval_list, CHARSET_INFO *cs,
-		       uint uint_geom_type)
+		       uint uint_geom_type,
+		       Virtual_column_info *vcol_info)
 {
   register Create_field *new_field;
   LEX  *lex= thd->lex;
@@ -6141,7 +6142,7 @@ bool add_field_to_list(THD *thd, LEX_STR
   if (!(new_field= new Create_field()) ||
       new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
                       default_value, on_update_value, comment, change,
-                      interval_list, cs, uint_geom_type))
+                      interval_list, cs, uint_geom_type, vcol_info))
     DBUG_RETURN(1);
 
   lex->alter_info.create_list.push_back(new_field);

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2009-09-07 20:50:10 +0000
+++ b/sql/sql_partition.cc	2009-10-16 22:57:48 +0000
@@ -975,7 +975,8 @@ bool fix_fields_part_func(THD *thd, Item
   thd->lex->use_only_table_context= TRUE;
   thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
   
-  error= func_expr->fix_fields(thd, (Item**)&func_expr);
+  if (!(error= func_expr->fix_fields(thd, (Item**)&func_expr)))
+    func_expr->walk(&Item::vcol_in_partition_func_processor, 0, NULL);
 
   thd->lex->use_only_table_context= save_use_only_table_context;
 

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2009-09-15 10:46:35 +0000
+++ b/sql/sql_select.cc	2009-10-16 22:57:48 +0000
@@ -9761,6 +9761,10 @@ void setup_tmp_table_column_bitmaps(TABL
   bitmap_init(&table->tmp_set,
               (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)),
               field_count, FALSE);
+  bitmap_init(&table->vcol_set,
+              (my_bitmap_map*) (bitmaps+ 2+bitmap_buffer_size(field_count)),
+              field_count, FALSE);
+
   /* write_set and all_set are copies of read_set */
   table->def_write_set= table->def_read_set;
   table->s->all_set= table->def_read_set;
@@ -9908,7 +9912,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARA
                         &tmpname, (uint) strlen(path)+1,
                         &group_buff, (group && ! using_unique_constraint ?
                                       param->group_length : 0),
-                        &bitmaps, bitmap_buffer_size(field_count)*2,
+                        &bitmaps, bitmap_buffer_size(field_count)*3,
                         NullS))
   {
     if (temp_pool_slot != MY_BIT_NONE)
@@ -10512,7 +10516,7 @@ TABLE *create_virtual_tmp_table(THD *thd
                         &share, sizeof(*share),
                         &field, (field_count + 1) * sizeof(Field*),
                         &blob_field, (field_count+1) *sizeof(uint),
-                        &bitmaps, bitmap_buffer_size(field_count)*2,
+                        &bitmaps, bitmap_buffer_size(field_count)*3,
                         NullS))
     return 0;
 
@@ -11475,6 +11479,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
     return NESTED_LOOP_KILLED;               /* purecov: inspected */
   }
   DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
+  update_virtual_fields(join_tab->table);     
   if (!select_cond || select_cond->val_int())
   {
     /*
@@ -11684,6 +11689,8 @@ flush_cached_records(JOIN *join,JOIN_TAB
       return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
     }
     SQL_SELECT *select=join_tab->select;
+    if (rc == NESTED_LOOP_OK)
+      update_virtual_fields(join_tab->table);
     if (rc == NESTED_LOOP_OK &&
         (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
     {
@@ -11867,6 +11874,7 @@ join_read_system(JOIN_TAB *tab)
       empty_record(table);			// Make empty record
       return -1;
     }
+    update_virtual_fields(table);
     store_record(table,record[1]);
   }
   else if (!table->status)			// Only happens with left join
@@ -11915,6 +11923,7 @@ join_read_const(JOIN_TAB *tab)
 	return report_error(table, error);
       return -1;
     }
+    update_virtual_fields(table);
     store_record(table,record[1]);
   }
   else if (!(table->status & ~STATUS_NULL_ROW))	// Only happens with left join
@@ -12174,6 +12183,7 @@ join_read_next(READ_RECORD *info)
   int error;
   if ((error=info->file->index_next(info->record)))
     return report_error(info->table, error);
+
   return 0;
 }
 
@@ -12201,6 +12211,7 @@ join_read_last(JOIN_TAB *tab)
     error= table->file->prepare_index_scan();
   if (error || (error= tab->table->file->index_last(tab->table->record[0])))
     return report_error(table, error);
+
   return 0;
 }
 

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2009-09-23 11:03:47 +0000
+++ b/sql/sql_show.cc	2009-10-16 22:57:48 +0000
@@ -1185,6 +1185,19 @@ int store_create_info(THD *thd, TABLE_LI
     field->sql_type(type);
     packet->append(type.ptr(), type.length(), system_charset_info);
 
+    if (field->vcol_info)
+    {
+      packet->append(STRING_WITH_LEN(" AS ("));
+      packet->append(field->vcol_info->expr_str.str,
+                     field->vcol_info->expr_str.length,
+                     system_charset_info);
+      packet->append(STRING_WITH_LEN(")"));
+      if (field->stored_in_db)
+        packet->append(STRING_WITH_LEN(" PERSISTENT"));
+      else
+        packet->append(STRING_WITH_LEN(" VIRTUAL"));
+    }
+
     if (field->has_charset() &&
         !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
     {
@@ -1215,7 +1228,8 @@ int store_create_info(THD *thd, TABLE_LI
       packet->append(STRING_WITH_LEN(" NULL"));
     }
 
-    if (get_field_default_value(thd, table, field, &def_value, 1))
+    if (!field->vcol_info &&
+        get_field_default_value(thd, table, field, &def_value, 1))
     {
       packet->append(STRING_WITH_LEN(" DEFAULT "));
       packet->append(def_value.ptr(), def_value.length(), system_charset_info);
@@ -3908,6 +3922,8 @@ static int get_schema_column_record(THD 
         field->unireg_check != Field::TIMESTAMP_DN_FIELD)
       table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
                               cs);
+    if (field->vcol_info)
+      table->field[16]->store(STRING_WITH_LEN("VIRTUAL"), cs);
 
     table->field[18]->store(field->comment.str, field->comment.length, cs);
     if (schema_table_store_record(thd, table))

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2009-09-18 01:04:43 +0000
+++ b/sql/sql_table.cc	2009-10-16 22:57:48 +0000
@@ -2441,7 +2441,8 @@ int prepare_create_field(Create_field *s
                           (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
     break;
   }
-  if (!(sql_field->flags & NOT_NULL_FLAG))
+  if (!(sql_field->flags & NOT_NULL_FLAG) ||
+      (sql_field->vcol_info))  /* Make virtual columns allow NULL values */
     sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
   if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
     sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
@@ -2755,6 +2756,8 @@ mysql_prepare_create_table(THD *thd, HA_
             null_fields--;
 	  sql_field->flags=		dup_field->flags;
           sql_field->interval=          dup_field->interval;
+          sql_field->vcol_info=         dup_field->vcol_info;
+          sql_field->stored_in_db=      dup_field->stored_in_db;
 	  it2.remove();			// Remove first (create) definition
 	  select_field_pos--;
 	  break;
@@ -2787,7 +2790,23 @@ mysql_prepare_create_table(THD *thd, HA_
     sql_field->offset= record_offset;
     if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
       auto_increment++;
-    record_offset+= sql_field->pack_length;
+    /*
+      For now skip fields that are not physically stored in the database
+      (virtual fields) and update their offset later 
+      (see the next loop).
+    */
+    if (sql_field->stored_in_db)
+      record_offset+= sql_field->pack_length;
+  }
+  /* Update virtual fields' offset*/
+  it.rewind();
+  while ((sql_field=it++))
+  {
+    if (!sql_field->stored_in_db)
+    {
+      sql_field->offset= record_offset;
+      record_offset+= sql_field->pack_length;
+    }
   }
   if (timestamps_with_niladic > 1)
   {
@@ -2837,6 +2856,8 @@ mysql_prepare_create_table(THD *thd, HA_
     if (key->type == Key::FOREIGN_KEY)
     {
       fk_key_count++;
+      if (((Foreign_key *)key)->validate(alter_info->create_list))
+        DBUG_RETURN(TRUE);
       Foreign_key *fk_key= (Foreign_key*) key;
       if (fk_key->ref_columns.elements &&
 	  fk_key->ref_columns.elements != fk_key->columns.elements)
@@ -3123,6 +3144,17 @@ mysql_prepare_create_table(THD *thd, HA_
 	  }
 	}
 #endif
+        if (!sql_field->stored_in_db)
+        {
+          /* Key fields must always be physically stored. */
+          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
+          DBUG_RETURN(TRUE);
+        }
+        if (key->type == Key::PRIMARY && sql_field->vcol_info)
+        {
+          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
+          DBUG_RETURN(TRUE);
+        }
 	if (!(sql_field->flags & NOT_NULL_FLAG))
 	{
 	  if (key->type == Key::PRIMARY)
@@ -5644,6 +5676,19 @@ compare_tables(TABLE *table,
       DBUG_RETURN(0);
     }
 
+    /*
+      Check if the altered column is computed and either
+      is stored or is used in the partitioning expression.
+      TODO: Mark such a column with an alter flag only if
+      the defining expression has changed.
+    */
+    if (field->vcol_info && 
+        (field->stored_in_db || field->vcol_info->is_in_partitioning_expr()))
+    {
+      *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+      DBUG_RETURN(0);
+    }
+
     /* Don't pack rows in old tables if the user has requested this. */
       if (create_info->row_type == ROW_TYPE_DYNAMIC ||
           (tmp_new_field->flags & BLOB_FLAG) ||
@@ -6008,6 +6053,13 @@ mysql_prepare_alter_table(THD *thd, TABL
     if (def)
     {						// Field is changed
       def->field=field;
+      if (field->stored_in_db != def->stored_in_db)
+      {
+        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
+                 MYF(0),
+                 "Changing the STORED status");
+        goto err;
+      }
       if (!def->after)
       {
 	new_create_list.push_back(def);
@@ -6220,6 +6272,9 @@ mysql_prepare_alter_table(THD *thd, TABL
     Key *key;
     while ((key=key_it++))			// Add new keys
     {
+      if (key->type == Key::FOREIGN_KEY &&
+          ((Foreign_key *)key)->validate(new_create_list))
+        goto err;
       if (key->type != Key::FOREIGN_KEY)
         new_key_list.push_back(key);
       if (key->name &&
@@ -7600,6 +7655,7 @@ copy_data_between_tables(TABLE *from,TAB
 
   /* Tell handler that we have values for all columns in the to table */
   to->use_all_columns();
+  to->mark_virtual_columns_for_write();
   init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
   errpos= 4;
   if (ignore)
@@ -7614,6 +7670,7 @@ copy_data_between_tables(TABLE *from,TAB
       error= 1;
       break;
     }
+    update_virtual_fields(from);
     thd->row_count++;
     /* Return error if source table isn't empty. */
     if (error_if_not_empty)
@@ -7634,6 +7691,12 @@ copy_data_between_tables(TABLE *from,TAB
       copy_ptr->do_copy(copy_ptr);
     }
     prev_insert_id= to->file->next_insert_id;
+    update_virtual_fields(to, TRUE);
+    if (thd->is_error())
+    {
+      error= 1;
+      break;
+    }
     error=to->file->ha_write_row(to->record[0]);
     to->auto_increment_field_not_null= FALSE;
     if (error)

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2009-09-07 20:50:10 +0000
+++ b/sql/sql_yacc.yy	2009-10-16 22:57:48 +0000
@@ -549,6 +549,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  ALGORITHM_SYM
 %token  ALL                           /* SQL-2003-R */
 %token  ALTER                         /* SQL-2003-R */
+%token  ALWAYS_SYM
 %token  ANALYZE_SYM
 %token  AND_AND_SYM                   /* OPERATOR */
 %token  AND_SYM                       /* SQL-2003-R */
@@ -715,6 +716,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  FULLTEXT_SYM
 %token  FUNCTION_SYM                  /* SQL-2003-R */
 %token  GE
+%token  GENERATED_SYM
 %token  GEOMETRYCOLLECTION
 %token  GEOMETRY_SYM
 %token  GET_FORMAT                    /* MYSQL-FUNC */
@@ -892,11 +894,13 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  PAGE_CHECKSUM_SYM
 %token  PARAM_MARKER
 %token  PARSER_SYM
+%token  PARSE_VCOL_EXPR_SYM
 %token  PARTIAL                       /* SQL-2003-N */
 %token  PARTITIONING_SYM
 %token  PARTITIONS_SYM
 %token  PARTITION_SYM                 /* SQL-2003-R */
 %token  PASSWORD
+%token  PERSISTENT_SYM
 %token  PHASE_SYM
 %token  PLUGINS_SYM
 %token  PLUGIN_SYM
@@ -1090,6 +1094,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  VARIANCE_SYM
 %token  VARYING                       /* SQL-2003-R */
 %token  VAR_SAMP_SYM
+%token  VIRTUAL_SYM
 %token  VIEW_SYM                      /* SQL-2003-N */
 %token  WAIT_SYM
 %token  WARNINGS
@@ -1149,7 +1154,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
         text_string opt_gconcat_separator
 
 %type <num>
-        type int_type real_type order_dir lock_option
+        type int_type real_type order_dir lock_option field_def
         udf_type if_exists opt_local opt_table_options table_options
         table_option opt_if_not_exists opt_no_write_to_binlog
         delete_option opt_temporary all_or_any opt_distinct
@@ -1305,6 +1310,8 @@ bool my_yyoverflow(short **a, YYSTYPE **
         init_key_options key_options key_opts key_opt key_using_alg
         server_def server_options_list server_option
         definer_opt no_definer definer
+        parse_vcol_expr vcol_opt_specifier vcol_opt_attribute
+        vcol_opt_attribute_list vcol_attribute
 END_OF_INPUT
 
 %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -1436,6 +1443,7 @@ statement:
         | lock
         | optimize
         | keycache
+        | parse_vcol_expr
         | partition_entry
         | preload
         | prepare
@@ -4765,8 +4773,9 @@ field_spec:
             lex->default_value= lex->on_update_value= 0;
             lex->comment=null_lex_str;
             lex->charset=NULL;
+	    lex->vcol_info= 0;
           }
-          type opt_attribute
+          field_def
           {
             LEX *lex=Lex;
             if (add_field_to_list(lex->thd, &$1, (enum enum_field_types) $3,
@@ -4774,11 +4783,101 @@ field_spec:
                                   lex->default_value, lex->on_update_value, 
                                   &lex->comment,
                                   lex->change,&lex->interval_list,lex->charset,
-                                  lex->uint_geom_type))
+                                  lex->uint_geom_type,
+                                  lex->vcol_info))
               MYSQL_YYABORT;
           }
         ;
 
+field_def:
+          type opt_attribute {}
+        | type opt_generated_always AS '(' virtual_column_func ')'
+          vcol_opt_specifier
+          vcol_opt_attribute
+          {
+            $$= (enum enum_field_types)MYSQL_TYPE_VIRTUAL;
+            Lex->vcol_info->set_field_type((enum enum_field_types) $1);
+          }
+        ;
+
+opt_generated_always:
+          /* empty */
+        | GENERATED_SYM ALWAYS_SYM {}
+        ;
+
+vcol_opt_specifier:
+          /* empty */
+          {
+            Lex->vcol_info->set_stored_in_db_flag(FALSE);
+          }
+        | VIRTUAL_SYM
+          {
+            Lex->vcol_info->set_stored_in_db_flag(FALSE);
+          }
+        | PERSISTENT_SYM
+          {
+            Lex->vcol_info->set_stored_in_db_flag(TRUE);
+          }
+        ;
+
+vcol_opt_attribute:
+          /* empty */ {}
+        | vcol_opt_attribute_list {}
+        ;
+
+vcol_opt_attribute_list:
+          vcol_opt_attribute_list vcol_attribute {}
+        | vcol_attribute
+        ;
+
+vcol_attribute:
+          UNIQUE_SYM
+          {
+            LEX *lex=Lex;
+            lex->type|= UNIQUE_FLAG;
+            lex->alter_info.flags|= ALTER_ADD_INDEX;
+          }
+        | UNIQUE_SYM KEY_SYM
+          {
+            LEX *lex=Lex;
+            lex->type|= UNIQUE_KEY_FLAG;
+            lex->alter_info.flags|= ALTER_ADD_INDEX;
+          }
+        | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; }
+        ;
+
+parse_vcol_expr:
+          PARSE_VCOL_EXPR_SYM '(' virtual_column_func ')'
+          {
+            /*
+              "PARSE_VCOL_EXPR" can only be used by the SQL server
+              when reading a '*.frm' file.
+              Prevent the end user from invoking this command.
+            */
+            if (!Lex->parse_vcol_expr)
+            {
+              my_message(ER_SYNTAX_ERROR, ER(ER_SYNTAX_ERROR), MYF(0));
+              MYSQL_YYABORT;
+            }
+          }
+        ;
+
+virtual_column_func:
+          remember_name expr remember_end
+          {
+            Lex->vcol_info= new Virtual_column_info();
+            if (!Lex->vcol_info)
+            {
+              mem_alloc_error(sizeof(Virtual_column_info));
+              MYSQL_YYABORT;
+            }
+            uint expr_len= (uint)($3 - $1) - 1;
+            Lex->vcol_info->expr_str.str= (char* ) sql_memdup($1 + 1, expr_len);
+            Lex->vcol_info->expr_str.length= expr_len;
+            Lex->vcol_info->expr_item= $2;
+          }
+        ;
+
 type:
           int_type opt_field_length field_options { $$=$1; }
         | real_type opt_precision field_options { $$=$1; }
@@ -5866,8 +5965,9 @@ alter_list_item:
             lex->comment=null_lex_str;
             lex->charset= NULL;
             lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
+	    lex->vcol_info= 0;
           }
-          type opt_attribute
+          field_def
           {
             LEX *lex=Lex;
             if (add_field_to_list(lex->thd,&$3,
@@ -5876,7 +5976,8 @@ alter_list_item:
                                   lex->default_value, lex->on_update_value,
                                   &lex->comment,
                                   $3.str, &lex->interval_list, lex->charset,
-                                  lex->uint_geom_type))
+                                  lex->uint_geom_type,
+                                  lex->vcol_info))
               MYSQL_YYABORT;
           }
           opt_place
@@ -11430,6 +11531,7 @@ keyword_sp:
         | AGAINST                  {}
         | AGGREGATE_SYM            {}
         | ALGORITHM_SYM            {}
+        | ALWAYS_SYM               {}
         | ANY_SYM                  {}
         | AT_SYM                   {}
         | AUTHORS_SYM              {}
@@ -11499,6 +11601,7 @@ keyword_sp:
         | FIRST_SYM                {}
         | FIXED_SYM                {}
         | FRAC_SECOND_SYM          {}
+        | GENERATED_SYM            {}
         | GEOMETRY_SYM             {}
         | GEOMETRYCOLLECTION       {}
         | GET_FORMAT               {}
@@ -11586,6 +11689,7 @@ keyword_sp:
         | PARTITIONING_SYM         {}
         | PARTITIONS_SYM           {}
         | PASSWORD                 {}
+        | PERSISTENT_SYM           {}
         | PHASE_SYM                {}
         | PLUGIN_SYM               {}
         | PLUGINS_SYM              {}
@@ -11678,6 +11782,7 @@ keyword_sp:
         | USE_FRM                  {}
         | VARIABLES                {}
         | VIEW_SYM                 {}
+        | VIRTUAL_SYM              {}
         | VALUE_SYM                {}
         | WARNINGS                 {}
         | WAIT_SYM                 {}
@@ -13338,6 +13443,7 @@ sf_tail:
             lex->length= lex->dec= NULL;
             lex->interval_list.empty();
             lex->type= 0;
+            lex->vcol_info= 0;
           }
           type /* $11 */
           { /* $12 */

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2009-09-09 21:06:57 +0000
+++ b/sql/table.cc	2009-10-16 22:57:48 +0000
@@ -33,6 +33,12 @@ LEX_STRING GENERAL_LOG_NAME= {C_STRING_W
 /* SLOW_LOG name */
 LEX_STRING SLOW_LOG_NAME= {C_STRING_WITH_LEN("slow_log")};
 
+/* 
+  Keyword added as a prefix when parsing the defining expression for a
+  virtual column read from the column definition saved in the frm file
+*/
+LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
+
 	/* Functions defined in this file */
 
 void open_table_error(TABLE_SHARE *share, int error, int db_errno,
@@ -663,10 +669,11 @@ static int open_binary_frm(THD *thd, TAB
   uint interval_count, interval_parts, read_length, int_length;
   uint db_create_options, keys, key_parts, n_length;
   uint key_info_length, com_length, null_bit_pos;
+  uint vcol_screen_length;
   uint extra_rec_buf_length;
   uint i,j;
   bool use_hash;
-  char *keynames, *names, *comment_pos;
+  char *keynames, *names, *comment_pos, *vcol_screen_pos;
   uchar *record;
   uchar *disk_buff, *strpos, *null_flags, *null_pos;
   ulong pos, record_offset, *rec_per_key, rec_buff_length;
@@ -836,6 +843,7 @@ static int open_binary_frm(THD *thd, TAB
   strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
 
   share->reclength = uint2korr((head+16));
+  share->stored_rec_length= share->reclength;
   if (*(head+26) == 1)
     share->system= 1;				/* one-record-database */
 #ifdef HAVE_CRYPTED_FRM
@@ -1040,24 +1048,28 @@ static int open_binary_frm(THD *thd, TAB
   int_length= uint2korr(head+274);
   share->null_fields= uint2korr(head+282);
   com_length= uint2korr(head+284);
+  vcol_screen_length= uint2korr(head+286);
+  share->vfields= 0;
+  share->stored_fields= share->fields;
   share->comment.length=  (int) (head[46]);
   share->comment.str= strmake_root(&share->mem_root, (char*) head+47,
                                    share->comment.length);
 
-  DBUG_PRINT("info",("i_count: %d  i_parts: %d  index: %d  n_length: %d  int_length: %d  com_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length));
-
+  DBUG_PRINT("info",("i_count: %d  i_parts: %d  index: %d  n_length: %d  int_length: %d  com_length: %d  vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length));
   if (!(field_ptr = (Field **)
 	alloc_root(&share->mem_root,
 		   (uint) ((share->fields+1)*sizeof(Field*)+
 			   interval_count*sizeof(TYPELIB)+
 			   (share->fields+interval_parts+
 			    keys+3)*sizeof(char *)+
-			   (n_length+int_length+com_length)))))
+			   (n_length+int_length+com_length+
+			       vcol_screen_length)))))
     goto err;                                   /* purecov: inspected */
 
   share->field= field_ptr;
   read_length=(uint) (share->fields * field_pack_length +
-		      pos+ (uint) (n_length+int_length+com_length));
+		      pos+ (uint) (n_length+int_length+com_length+
+		                   vcol_screen_length));
   if (read_string(file,(uchar**) &disk_buff,read_length))
     goto err;                                   /* purecov: inspected */
 #ifdef HAVE_CRYPTED_FRM
@@ -1078,7 +1090,11 @@ static int open_binary_frm(THD *thd, TAB
   memcpy((char*) names, strpos+(share->fields*field_pack_length),
 	 (uint) (n_length+int_length));
   comment_pos= names+(n_length+int_length);
-  memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
+  memcpy(comment_pos, disk_buff+read_length-com_length-vcol_screen_length, 
+         com_length);
+  vcol_screen_pos= names+(n_length+int_length+com_length);
+  memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length, 
+         vcol_screen_length);
 
   fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
   if (share->fieldnames.count != share->fields)
@@ -1146,10 +1162,14 @@ static int open_binary_frm(THD *thd, TAB
   for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
   {
     uint pack_flag, interval_nr, unireg_type, recpos, field_length;
+    uint vcol_info_length=0;
+    uint vcol_expr_length=0;
     enum_field_types field_type;
     CHARSET_INFO *charset=NULL;
     Field::geometry_type geom_type= Field::GEOM_GEOMETRY;
     LEX_STRING comment;
+    Virtual_column_info *vcol_info= 0;
+    bool fld_stored_in_db= TRUE;
 
     if (new_frm_ver >= 3)
     {
@@ -1184,6 +1204,18 @@ static int open_binary_frm(THD *thd, TAB
           goto err;
         }
       }
+
+      if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL)
+      {
+        DBUG_ASSERT(interval_nr); // Expect non-null expression
+        /* 
+          The interval_id byte in the .frm file stores the length of the
+          expression statement for a virtual column.
+        */
+        vcol_info_length= interval_nr;
+        interval_nr= 0;
+      }
+
       if (!comment_length)
       {
 	comment.str= (char*) "";
@@ -1195,6 +1227,34 @@ static int open_binary_frm(THD *thd, TAB
 	comment.length= comment_length;
 	comment_pos+=   comment_length;
       }
+
+      if (vcol_info_length)
+      {
+        /*
+          Get virtual column data stored in the .frm file as follows:
+          byte 1      = 1 (always 1 to allow for future extensions)
+          byte 2      = sql_type
+          byte 3      = flags (as of now, 0 - no flags, 1 - field is physically stored)
+          byte 4-...  = virtual column expression (text data)
+        */
+        vcol_info= new Virtual_column_info();
+        if ((uint)vcol_screen_pos[0] != 1)
+        {
+          error= 4;
+          goto err;
+        }
+        field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
+        fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
+        vcol_expr_length= vcol_info_length-(uint)FRM_VCOL_HEADER_SIZE;
+        if (!(vcol_info->expr_str.str=
+              (char *)memdup_root(&share->mem_root,
+                                  vcol_screen_pos+(uint)FRM_VCOL_HEADER_SIZE,
+                                  vcol_expr_length)))
+          goto err;        
+        vcol_info->expr_str.length= vcol_expr_length;
+        vcol_screen_pos+= vcol_info_length;
+        share->vfields++;
+      }
     }
     else
     {
@@ -1285,6 +1345,8 @@ static int open_binary_frm(THD *thd, TAB
 
     reg_field->field_index= i;
     reg_field->comment=comment;
+    reg_field->vcol_info= vcol_info;
+    reg_field->stored_in_db= fld_stored_in_db;
     if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag))
     {
       if ((null_bit_pos+= field_length & 7) > 7)
@@ -1309,8 +1371,17 @@ static int open_binary_frm(THD *thd, TAB
     if (use_hash)
       (void) my_hash_insert(&share->name_hash,
                             (uchar*) field_ptr); // never fail
+    if (!reg_field->stored_in_db)
+    {
+      share->stored_fields--;
+      if (share->stored_rec_length>=recpos)
+        share->stored_rec_length= recpos-1;
+    }
   }
   *field_ptr=0;					// End marker
+  /* Sanity checks: */
+  DBUG_ASSERT(share->fields>=share->stored_fields);
+  DBUG_ASSERT(share->reclength>=share->stored_rec_length);
 
   /* Fix key->name and key_part->field */
   if (key_parts)
@@ -1597,6 +1668,297 @@ static int open_binary_frm(THD *thd, TAB
   DBUG_RETURN(error);
 } /* open_binary_frm */
 
+/*
+  @brief
+    Clear GET_FIXED_FIELDS_FLAG in all fields of a table
+
+  @param
+    table     The table for whose fields the flags are to be cleared
+
+  @note
+    This routine is used for error handling purposes.
+
+  @return
+    none
+*/
+
+static void clear_field_flag(TABLE *table)
+{
+  Field **ptr;
+  DBUG_ENTER("clear_field_flag");
+
+  for (ptr= table->field; *ptr; ptr++)
+    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
+  DBUG_VOID_RETURN;
+}
+
+
+/*
+  @brief 
+    Perform semantic analysis of the defining expression for a virtual column
+
+  @param
+    thd           The thread object
+  @param
+    table         The table containing the virtual column
+  @param
+    vcol_field    The virtual field whose defining expression is to be analyzed
+
+  @details
+    The function performs semantic analysis of the defining expression for
+    the virtual column vcol_field. The expression is used to compute the
+    values of this column.
+
+  @note
+   The function exploits the fact  that the fix_fields method sets the flag 
+   GET_FIXED_FIELDS_FLAG for all fields in the item tree.
+   This flag must always be unset before returning from this function
+   since it is used for other purposes as well.
+ 
+  @retval
+    TRUE           An error occurred, something was wrong with the function
+  @retval
+    FALSE          Otherwise
+*/
+
+bool fix_vcol_expr(THD *thd,
+                   TABLE *table,
+                   Field *vcol_field)
+{
+  Virtual_column_info *vcol_info= vcol_field->vcol_info;
+  Item* func_expr= vcol_info->expr_item;
+  uint dir_length, home_dir_length;
+  bool result= TRUE;
+  TABLE_LIST tables;
+  TABLE_LIST *save_table_list, *save_first_table, *save_last_table;
+  int error;
+  Name_resolution_context *context;
+  const char *save_where;
+  char* db_name;
+  char db_name_string[FN_REFLEN];
+  bool save_use_only_table_context;
+  Field **ptr, *field;
+  enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
+  DBUG_ASSERT(func_expr);
+  DBUG_ENTER("fix_vcol_expr");
+
+  /*
+    Set-up the TABLE_LIST object to be a list with a single table
+    Set the object to zero to create NULL pointers and set alias
+    and real name to table name and get database name from file name.
+  */
+
+  bzero((void*)&tables, sizeof(TABLE_LIST));
+  tables.alias= tables.table_name= (char*) table->s->table_name.str;
+  tables.table= table;
+  tables.next_local= 0;
+  tables.next_name_resolution_table= 0;
+  strmov(db_name_string, table->s->normalized_path.str);
+  dir_length= dirname_length(db_name_string);
+  db_name_string[dir_length - 1]= 0;
+  home_dir_length= dirname_length(db_name_string);
+  db_name= &db_name_string[home_dir_length];
+  tables.db= db_name;
+
+  thd->mark_used_columns= MARK_COLUMNS_NONE;
+
+  context= thd->lex->current_context();
+  table->map= 1; //To ensure correct calculation of const item
+  table->get_fields_in_item_tree= TRUE;
+  save_table_list= context->table_list;
+  save_first_table= context->first_name_resolution_table;
+  save_last_table= context->last_name_resolution_table;
+  context->table_list= &tables;
+  context->first_name_resolution_table= &tables;
+  context->last_name_resolution_table= NULL;
+  func_expr->walk(&Item::change_context_processor, 0, (uchar*) context);
+  save_where= thd->where;
+  thd->where= "virtual column function";
+
+  /* Save the context before fixing the fields*/
+  save_use_only_table_context= thd->lex->use_only_table_context;
+  thd->lex->use_only_table_context= TRUE;
+  /* Fix fields referenced to by the virtual column function */
+  error= func_expr->fix_fields(thd, (Item**)0);
+  /* Restore the original context*/
+  thd->lex->use_only_table_context= save_use_only_table_context;
+  context->table_list= save_table_list;
+  context->first_name_resolution_table= save_first_table;
+  context->last_name_resolution_table= save_last_table;
+
+  if (unlikely(error))
+  {
+    DBUG_PRINT("info", 
+    ("Field in virtual column expression does not belong to the table"));
+    goto end;
+  }
+  thd->where= save_where;
+#ifdef PARANOID
+  /*
+    Walk through the Item tree checking if all items are valid
+   to be part of the virtual column
+  */
+  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
+  if (error)
+  {
+    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
+    goto end;
+  }
+#endif
+  if (unlikely(func_expr->const_item()))
+  {
+    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
+    goto end;
+  }
+  /* Ensure that this virtual column is not based on another virtual field. */
+  ptr= table->field;
+  while ((field= *(ptr++))) 
+  {
+    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
+        (field->vcol_info))
+    {
+      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
+      goto end;
+    }
+  }
+  result= FALSE;
+
+end:
+
+  /* Clear GET_FIXED_FIELDS_FLAG for the fields of the table */
+  clear_field_flag(table);
+
+  table->get_fields_in_item_tree= FALSE;
+  thd->mark_used_columns= save_mark_used_columns;
+  table->map= 0; //Restore old value
+ 
+ DBUG_RETURN(result);
+}
+
+/*
+  @brief
+    Unpack the definition of a virtual column from its linear representation
+
+  @parm
+    thd                  The thread object
+  @param
+    table                The table containing the virtual column
+  @param
+    field                The field for the virtual
+  @param  
+    vcol_expr            The string representation of the defining expression
+  @param[out]
+    error_reported       The flag to inform the caller that no other error
+                         messages are to be generated
+
+  @details
+    The function takes string representation 'vcol_expr' of the defining
+    expression for the virtual field 'field' of the table 'table' and
+    parses it, building an item object for it. The pointer to this item is
+    placed into in field->vcol_info.expr_item. After this the function performs
+    semantic analysis of the item by calling the the function fix_vcol_expr.
+    Since the defining expression is part of the table definition the item
+    for it is created in table->memroot within a separate Query_arena.
+    The free_list of this arena is saved in field->vcol_info.item_free_list
+    to be freed when the table defition is removed from the TABLE_SHARE cache.
+
+  @note
+    Before passing 'vcol_expr" to the parser the function embraces it in 
+    parenthesis and prepands it a special keyword.
+  
+   @retval
+    FALSE           If a success
+   @retval
+    TRUE            Otherwise
+*/
+bool unpack_vcol_info_from_frm(THD *thd,
+                               TABLE *table,
+                               Field *field,
+                               LEX_STRING *vcol_expr,
+                               bool *error_reported)
+{
+  bool rc= FALSE;
+  DBUG_ENTER("unpack_vcol_info_from_frm");
+  DBUG_ASSERT(vcol_expr);
+
+  /* 
+    Step 1: Construct the input string for the parser.
+    The string to be parsed has to be of the following format:
+    "PARSE_VCOL_EXPR (<expr_string_from_frm>)".
+  */
+  char *vcol_expr_str;
+  int str_len= 0;
+  CHARSET_INFO *old_character_set_client;
+  
+  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
+                                          vcol_expr->length + 
+                                            parse_vcol_keyword.length + 3)))
+  {
+    DBUG_RETURN(TRUE);
+  }
+  memcpy(vcol_expr_str,
+         (char*) parse_vcol_keyword.str,
+         parse_vcol_keyword.length);
+  str_len= parse_vcol_keyword.length;
+  memcpy(vcol_expr_str + str_len, "(", 1);
+  str_len++;
+  memcpy(vcol_expr_str + str_len, 
+         (char*) vcol_expr->str, 
+         vcol_expr->length);
+  str_len+= vcol_expr->length;
+  memcpy(vcol_expr_str + str_len, ")", 1);
+  str_len++;
+  memcpy(vcol_expr_str + str_len, "\0", 1);
+  str_len++;
+  Parser_state parser_state(thd, vcol_expr_str, str_len);
+
+  /* 
+    Step 2: Setup thd for parsing.
+  */
+  Query_arena *backup_stmt_arena_ptr= thd->stmt_arena;
+  Query_arena backup_arena;
+  Query_arena vcol_arena(&table->mem_root, Query_arena::INITIALIZED);
+  thd->set_n_backup_active_arena(&vcol_arena, &backup_arena);
+  thd->stmt_arena= &vcol_arena;
+
+  thd->lex->parse_vcol_expr= TRUE;
+  old_character_set_client= thd->variables.character_set_client;
+
+  /* 
+    Step 3: Use the parser to build an Item object from vcol_expr_str.
+  */
+  if (parse_sql(thd, &parser_state, NULL))
+  {
+    goto err;
+  }
+  /* From now on use vcol_info generated by the parser. */
+  field->vcol_info= thd->lex->vcol_info;
+
+  /* Validate the Item tree. */
+  if (fix_vcol_expr(thd, table, field))
+  {
+    *error_reported= TRUE;
+    field->vcol_info= 0;
+    goto err;
+  }
+  field->vcol_info->item_free_list= thd->free_list;
+  goto end;
+
+err:
+  rc= TRUE;
+  thd->lex->parse_vcol_expr= FALSE;
+  thd->free_items();
+end:
+  thd->stmt_arena= backup_stmt_arena_ptr;
+  thd->restore_active_arena(&vcol_arena, &backup_arena);
+  thd->variables.character_set_client= old_character_set_client;
+
+  DBUG_RETURN(rc);
+}
+
+/*
+  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
+*/
 
 /*
   Open a table based on a TABLE_SHARE
@@ -1631,7 +1993,7 @@ int open_table_from_share(THD *thd, TABL
   uint records, i, bitmap_size;
   bool error_reported= FALSE;
   uchar *record, *bitmaps;
-  Field **field_ptr;
+  Field **field_ptr, **vfield_ptr;
   DBUG_ENTER("open_table_from_share");
   DBUG_PRINT("enter",("name: '%s.%s'  form: 0x%lx", share->db.str,
                       share->table_name.str, (long) outparam));
@@ -1785,6 +2147,34 @@ int open_table_from_share(THD *thd, TABL
     }
   }
 
+  /*
+    Process virtual columns, if any.
+  */
+  if (!(vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
+                                          (uint) ((share->vfields+1)*
+                                                  sizeof(Field*)))))
+    goto err;
+
+  outparam->vfield= vfield_ptr;
+  
+  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
+  {
+    if ((*field_ptr)->vcol_info)
+    {
+      if (unpack_vcol_info_from_frm(thd,
+                                    outparam,
+                                    *field_ptr,
+                                    &(*field_ptr)->vcol_info->expr_str,
+                                    &error_reported))
+      {
+        error= 4; // in case no error is reported
+        goto err;
+      }
+      *(vfield_ptr++)= *field_ptr;
+    }
+  }
+  *vfield_ptr= 0;                              // End marker
+
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   if (share->partition_info_len && outparam->file)
   {
@@ -1852,10 +2242,24 @@ partititon_err:
   }
 #endif
 
+  /* Check virtual columns against table's storage engine. */
+  if (share->vfields && 
+        ((outparam->file && 
+          !outparam->file->check_if_supported_virtual_columns()) ||
+	 (!outparam->file && share->db_type() && 
+	   share->db_type()->db_type == DB_TYPE_CSV_DB))) // Workaround for CSV
+  {
+    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
+             MYF(0), 
+             "Specified storage engine");
+    error_reported= TRUE;
+    goto err;
+  }
+
   /* Allocate bitmaps */
 
   bitmap_size= share->column_bitmap_size;
-  if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
+  if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*4)))
     goto err;
   bitmap_init(&outparam->def_read_set,
               (my_bitmap_map*) bitmaps, share->fields, FALSE);
@@ -1863,6 +2267,8 @@ partititon_err:
               (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE);
   bitmap_init(&outparam->tmp_set,
               (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE);
+  bitmap_init(&outparam->vcol_set,
+              (my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE);
   outparam->default_column_bitmaps();
 
   /* The table struct is now initialized;  Open the table */
@@ -1966,7 +2372,11 @@ int closefrm(register TABLE *table, bool
   if (table->field)
   {
     for (Field **ptr=table->field ; *ptr ; ptr++)
+    {
+      if ((*ptr)->vcol_info)
+        free_items((*ptr)->vcol_info->item_free_list);
       delete *ptr;
+    }
     table->field= 0;
   }
   delete table->file;
@@ -4302,6 +4712,7 @@ void st_table::clear_column_bitmaps()
     bitmap_clear_all(&table->def_write_set);
   */
   bzero((char*) def_read_set.bitmap, s->column_bitmap_size*2);
+  bzero((char*) def_read_set.bitmap, s->column_bitmap_size*4);
   column_bitmaps_set(&def_read_set, &def_write_set);
 }
 
@@ -4387,7 +4798,14 @@ void st_table::mark_columns_used_by_inde
   KEY_PART_INFO *key_part_end= (key_part +
                                 key_info[index].key_parts);
   for (;key_part != key_part_end; key_part++)
+  {
     bitmap_set_bit(bitmap, key_part->fieldnr-1);
+    if (key_part->field->vcol_info &&
+        key_part->field->vcol_info->expr_item)
+      key_part->field->vcol_info->
+               expr_item->walk(&Item::register_field_in_bitmap, 
+                               1, (uchar *) bitmap);
+  }
 }
 
 
@@ -4514,6 +4932,8 @@ void st_table::mark_columns_needed_for_u
       file->column_bitmaps_signal();
     }
   }
+  /* Mark all virtual columns needed for update */
+  mark_virtual_columns_for_write();
   DBUG_VOID_RETURN;
 }
 
@@ -4540,9 +4960,100 @@ void st_table::mark_columns_needed_for_i
   }
   if (found_next_number_field)
     mark_auto_increment_column();
+  /* Mark virtual columns for insert */
+  mark_virtual_columns_for_write();
 }
 
 
+/*
+   @brief Mark a column as virtual used by the query
+
+   @param field           the field for the column to be marked
+
+   @details
+     The function marks the column for 'field' as virtual (computed)
+     in the bitmap vcol_set.
+     If the column is marked for the first time the expression to compute
+     the column is traversed and all columns that are occurred there are
+     marked in the read_set of the table.
+
+   @retval
+     TRUE       if column is marked for the first time
+   @retval
+     FALSE      otherwise
+*/
+
+bool st_table::mark_virtual_col(Field *field)
+{
+  bool res;
+  DBUG_ASSERT(field->vcol_info);
+  if (!(res= bitmap_fast_test_and_set(&vcol_set, field->field_index)))
+  {
+    Item *vcol_item= field->vcol_info->expr_item;
+    DBUG_ASSERT(vcol_item);
+    vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
+  }
+  return res;
+}
+
+
+/* 
+  @brief Mark virtual columns for update/insert commands
+
+  @details
+    The function marks virtual columns used in a update/insert commands
+    in the vcol_set bitmap.
+    If a virtual column is from  write_set it is always marked in vcol_set.
+    If a stored virtual column is not from write_set but it is computed
+    through columns from write_set it is also marked in vcol_set, and,
+    besides, it is added to write_set. 
+
+  @return       void
+
+  @note
+    Let table t1 have columns a,b,c and let column c be a stored virtual 
+    column computed through columns a and b. Then for the query
+      UPDATE t1 SET a=1
+    column c will be placed into vcol_set and into write_set while
+    column b will be placed into read_set.
+    If column c was a virtual column, but not a stored virtual column
+    then it would not be added to any of the sets. Column b would not
+    be added to read_set either.           
+*/
+
+void st_table::mark_virtual_columns_for_write(void)
+{
+  Field **vfield_ptr, *tmp_vfield;
+  bool bitmap_updated= FALSE;
+
+  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
+  {
+    tmp_vfield= *vfield_ptr;
+    if (bitmap_is_set(write_set, tmp_vfield->field_index))
+      bitmap_updated= mark_virtual_col(tmp_vfield);
+    else if (tmp_vfield->stored_in_db)
+    {
+      MY_BITMAP *save_read_set;
+      Item *vcol_item= tmp_vfield->vcol_info->expr_item;
+      DBUG_ASSERT(vcol_item);
+      bitmap_clear_all(&tmp_set);
+      save_read_set= read_set;
+      read_set= &tmp_set;
+      vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
+      read_set= save_read_set;
+      bitmap_intersect(&tmp_set, write_set);
+      if (!bitmap_is_clear_all(&tmp_set))
+      {
+        bitmap_set_bit(write_set, tmp_vfield->field_index);
+        mark_virtual_col(tmp_vfield);
+        bitmap_updated= TRUE;
+      }
+    } 
+  }
+  if (bitmap_updated)
+    file->column_bitmaps_signal();
+}
+
 /**
   @brief Check if this is part of a MERGE table with attached children.
 
@@ -4550,7 +5061,7 @@ void st_table::mark_columns_needed_for_i
     @retval     TRUE            children are attached
     @retval     FALSE           no MERGE part or children not attached
 
-  @detail
+  @details
     A MERGE table consists of a parent TABLE and zero or more child
     TABLEs. Each of these TABLEs is called a part of a MERGE table.
 */
@@ -4796,6 +5307,54 @@ size_t max_row_length(TABLE *table, cons
   return length;
 }
 
+/*
+  @brief Compute values for virtual columns used in query
+
+  @param  table            The TABLE object
+  @param  for_write        Requests to compute only fields needed for write   
+  
+  @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. 
+ 
+  @retval
+    0    Success
+  @retval
+    >0   Error occurred when storing a virtual field value
+*/
+
+int update_virtual_fields(TABLE *table, bool for_write)
+{
+  DBUG_ENTER("update_virtual_fields");
+  Field **vfield_ptr, *vfield;
+  int error= 0;
+  if (!table || !table->vfield)
+    DBUG_RETURN(0);
+
+  /* Iterate over virtual fields in the table */
+  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
+  {
+    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))
+    {
+      /* Compute the actual value of the virtual fields */
+      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
+      DBUG_PRINT("info", ("field '%s' - updated", vfield->field_name));
+    }
+    else
+    {
+      DBUG_PRINT("info", ("field '%s' - skipped", vfield->field_name));
+    }
+  }
+  DBUG_RETURN(0);
+}
+
 /*****************************************************************************
 ** Instansiate templates
 *****************************************************************************/

=== modified file 'sql/table.h'
--- a/sql/table.h	2009-09-15 10:46:35 +0000
+++ b/sql/table.h	2009-10-16 22:57:48 +0000
@@ -352,6 +352,8 @@ typedef struct st_table_share
   ulong   version, mysql_version;
   ulong   timestamp_offset;		/* Set to offset+1 of record */
   ulong   reclength;			/* Recordlength */
+  /* Stored record length. No generated-only virtual fields are included */
+  ulong   stored_rec_length;            
 
   plugin_ref db_plugin;			/* storage engine plugin */
   inline handlerton *db_type() const	/* table_type for handler */
@@ -372,6 +374,8 @@ typedef struct st_table_share
   uint key_block_size;			/* create key_block_size, if used */
   uint null_bytes, last_null_bit_pos;
   uint fields;				/* Number of fields */
+  /* Number of stored fields, generated-only virtual fields are not included */
+  uint stored_fields;                   
   uint rec_buff_length;                 /* Size of table->record[] buffer */
   uint keys, key_parts;
   uint max_key_length, max_unique_length, total_key_length;
@@ -393,6 +397,7 @@ typedef struct st_table_share
   uint error, open_errno, errarg;       /* error from open_table_def() */
   uint column_bitmap_size;
   uchar frm_version;
+  uint vfields;                         /* Number of computed (virtual) fields */
   bool null_field_first;
   bool system;                          /* Set if system table (one record) */
   bool crypted;                         /* If .frm file is crypted */
@@ -657,6 +662,7 @@ struct st_table {
   Field *next_number_field;		/* Set if next_number is activated */
   Field *found_next_number_field;	/* Set on open */
   Field_timestamp *timestamp_field;
+  Field **vfield;                       /* Pointer to virtual fields*/
 
   /* Table's triggers, 0 if there are no of them */
   Table_triggers_list *triggers;
@@ -666,6 +672,7 @@ struct st_table {
   uchar		*null_flags;
   my_bitmap_map	*bitmap_init_value;
   MY_BITMAP     def_read_set, def_write_set, tmp_set; /* containers */
+  MY_BITMAP     vcol_set;                 /* set of used virtual columns */
   MY_BITMAP     *read_set, *write_set;          /* Active column sets */
   /*
    The ID of the query that opened and is using this table. Has different
@@ -819,6 +826,8 @@ struct st_table {
   void mark_columns_needed_for_update(void);
   void mark_columns_needed_for_delete(void);
   void mark_columns_needed_for_insert(void);
+  bool mark_virtual_col(Field *field);
+  void mark_virtual_columns_for_write(void);
   inline void column_bitmaps_set(MY_BITMAP *read_set_arg,
                                  MY_BITMAP *write_set_arg)
   {

=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc	2009-09-07 20:50:10 +0000
+++ b/sql/unireg.cc	2009-10-16 22:57:48 +0000
@@ -583,7 +583,7 @@ static bool pack_header(uchar *forminfo,
 {
   uint length,int_count,int_length,no_empty, int_parts;
   uint time_stamp_pos,null_fields;
-  ulong reclength, totlength, n_length, com_length;
+  ulong reclength, totlength, n_length, com_length, vcol_info_length;
   DBUG_ENTER("pack_header");
 
   if (create_fields.elements > MAX_FIELDS)
@@ -594,8 +594,8 @@ static bool pack_header(uchar *forminfo,
 
   totlength= 0L;
   reclength= data_offset;
-  no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields=
-    com_length=0;
+  no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields=0;
+  com_length=vcol_info_length=0;
   n_length=2L;
 
 	/* Check fields */
@@ -623,6 +623,30 @@ static bool pack_header(uchar *forminfo,
                           field->field_name, tmp_len);
       field->comment.length= tmp_len;
     }
+    if (field->vcol_info)
+    {
+      tmp_len=
+        system_charset_info->cset->charpos(system_charset_info,
+                                           field->vcol_info->expr_str.str,
+                                           field->vcol_info->expr_str.str +
+                                           field->vcol_info->expr_str.length,
+                                           VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
+
+      if (tmp_len < field->vcol_info->expr_str.length)
+      {
+        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
+                 field->vcol_info->expr_str.str,"VIRTUAL COLUMN EXPRESSION",
+                 (uint) VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
+        DBUG_RETURN(1);
+      }
+      /*
+        Sum up the length of the expression string and the length of the
+        mandatory header to the total length of info on the defining 
+        expressions saved in the frm file for virtual columns.
+      */
+      vcol_info_length+= field->vcol_info->expr_str.length+
+                         (uint)FRM_VCOL_HEADER_SIZE;
+    }
 
     totlength+= field->length;
     com_length+= field->comment.length;
@@ -642,8 +666,6 @@ static bool pack_header(uchar *forminfo,
 	!time_stamp_pos)
       time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1;
     length=field->pack_length;
-    /* Ensure we don't have any bugs when generating offsets */
-    DBUG_ASSERT(reclength == field->offset + data_offset);
     if ((uint) field->offset+ (uint) data_offset+ length > reclength)
       reclength=(uint) (field->offset+ data_offset + length);
     n_length+= (ulong) strlen(field->field_name)+1;
@@ -710,7 +732,8 @@ static bool pack_header(uchar *forminfo,
   /* Hack to avoid bugs with small static rows in MySQL */
   reclength=max(file->min_record_length(table_options),reclength);
   if (info_length+(ulong) create_fields.elements*FCOMP+288+
-      n_length+int_length+com_length > 65535L || int_count > 255)
+      n_length+int_length+com_length+vcol_info_length > 65535L || 
+      int_count > 255)
   {
     my_message(ER_TOO_MANY_FIELDS, ER(ER_TOO_MANY_FIELDS), MYF(0));
     DBUG_RETURN(1);
@@ -718,7 +741,7 @@ static bool pack_header(uchar *forminfo,
 
   bzero((char*)forminfo,288);
   length=(info_length+create_fields.elements*FCOMP+288+n_length+int_length+
-	  com_length);
+	  com_length+vcol_info_length);
   int2store(forminfo,length);
   forminfo[256] = (uint8) screens;
   int2store(forminfo+258,create_fields.elements);
@@ -735,7 +758,8 @@ static bool pack_header(uchar *forminfo,
   int2store(forminfo+280,22);			/* Rows needed */
   int2store(forminfo+282,null_fields);
   int2store(forminfo+284,com_length);
-  /* Up to forminfo+288 is free to use for additional information */
+  int2store(forminfo+286,vcol_info_length);
+  /* forminfo+288 is free to use for additional information */
   DBUG_RETURN(0);
 } /* pack_header */
 
@@ -774,7 +798,7 @@ static bool pack_fields(File file, List<
                         ulong data_offset)
 {
   reg2 uint i;
-  uint int_count, comment_length=0;
+  uint int_count, comment_length= 0, vcol_info_length=0;
   uchar buff[MAX_FIELD_WIDTH];
   Create_field *field;
   DBUG_ENTER("pack_fields");
@@ -787,6 +811,7 @@ static bool pack_fields(File file, List<
   while ((field=it++))
   {
     uint recpos;
+    uint cur_vcol_expr_len= 0;
     buff[0]= (uchar) field->row;
     buff[1]= (uchar) field->col;
     buff[2]= (uchar) field->sc_length;
@@ -809,6 +834,17 @@ static bool pack_fields(File file, List<
       buff[14]= (uchar) field->charset->number;
     else
       buff[14]= 0;				// Numerical
+    if (field->vcol_info)
+    {
+      /* 
+        Use the interval_id place in the .frm file to store the length of
+        the additional data saved for the virtual field
+      */
+      buff[12]= cur_vcol_expr_len= field->vcol_info->expr_str.length +
+                (uint)FRM_VCOL_HEADER_SIZE;
+      vcol_info_length+= cur_vcol_expr_len+(uint)FRM_VCOL_HEADER_SIZE;
+      buff[13]= (uchar) MYSQL_TYPE_VIRTUAL;
+    }
     int2store(buff+15, field->comment.length);
     comment_length+= field->comment.length;
     set_if_bigger(int_count,field->interval_id);
@@ -903,6 +939,34 @@ static bool pack_fields(File file, List<
 	  DBUG_RETURN(1);
     }
   }
+  if (vcol_info_length)
+  {
+    it.rewind();
+    int_count=0;
+    while ((field=it++))
+    {
+      /*
+        Pack each virtual field as follows:
+        byte 1      = 1 (always 1 to allow for future extensions)
+        byte 2      = sql_type
+        byte 3      = flags (as of now, 0 - no flags, 1 - field is physically stored)
+        byte 4-...  = virtual column expression (text data)
+      */
+      if (field->vcol_info && field->vcol_info->expr_str.length)
+      {
+        buff[0]= (uchar)1;
+        buff[1]= (uchar) field->sql_type;
+        buff[2]= (uchar) field->stored_in_db;
+        if (my_write(file, buff, 3, MYF_RW))
+          DBUG_RETURN(1);
+        if (my_write(file,
+                     (uchar*) field->vcol_info->expr_str.str,
+                     field->vcol_info->expr_str.length,
+                     MYF_RW))
+          DBUG_RETURN(1);
+      }
+    }
+  }
   DBUG_RETURN(0);
 }
 

=== modified file 'sql/unireg.h'
--- a/sql/unireg.h	2009-09-07 20:50:10 +0000
+++ b/sql/unireg.h	2009-10-16 22:57:48 +0000
@@ -212,6 +212,13 @@
 
 #define DEFAULT_KEY_CACHE_NAME "default"
 
+/* The length of the header part for each virtual column in the .frm file */
+#define FRM_VCOL_HEADER_SIZE 3
+
+/* Maximum length of the defining expression for a virtual columns */
+#define VIRTUAL_COLUMN_EXPRESSION_MAXLEN 255 - FRM_VCOL_HEADER_SIZE
+
+
 /* Include prototypes for unireg */
 
 #include "mysqld_error.h"

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2009-09-07 20:50:10 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2009-10-16 22:57:48 +0000
@@ -2577,12 +2577,12 @@ ha_innobase::open(
 	}
 
 	/* Create buffers for packing the fields of a record. Why
-	table->reclength did not work here? Obviously, because char
+	table->stored_rec_length did not work here? Obviously, because char
 	fields when packed actually became 1 byte longer, when we also
 	stored the string length as the first byte. */
 
 	upd_and_key_val_buff_len =
-				table->s->reclength + table->s->max_key_length
+				table->s->stored_rec_length + table->s->max_key_length
 							+ MAX_REF_PARTS * 3;
 	if (!(uchar*) my_multi_malloc(MYF(MY_WME),
 			&upd_buff, upd_and_key_val_buff_len,
@@ -2657,7 +2657,7 @@ retry:
 
 	prebuilt = row_create_prebuilt(ib_table);
 
-	prebuilt->mysql_row_len = table->s->reclength;
+	prebuilt->mysql_row_len = table->s->stored_rec_length;;
 	prebuilt->default_rec = table->s->default_values;
 	ut_ad(prebuilt->default_rec);
 
@@ -3360,11 +3360,11 @@ build_template(
 	dict_index_t*	clust_index;
 	mysql_row_templ_t* templ;
 	Field*		field;
-	ulint		n_fields;
+	ulint		n_fields, n_stored_fields;
 	ulint		n_requested_fields	= 0;
 	ibool		fetch_all_in_key	= FALSE;
 	ibool		fetch_primary_key_cols	= FALSE;
-	ulint		i;
+	ulint		i, sql_idx, innodb_idx=0;
 	/* byte offset of the end of last requested column */
 	ulint		mysql_prefix_len	= 0;
 
@@ -3425,11 +3425,12 @@ build_template(
 	}
 
 	n_fields = (ulint)table->s->fields; /* number of columns */
+	n_stored_fields= (ulint)table->s->stored_fields; /* number of stored columns */
 
 	if (!prebuilt->mysql_template) {
 		prebuilt->mysql_template = (mysql_row_templ_t*)
 						mem_alloc_noninline(
-					n_fields * sizeof(mysql_row_templ_t));
+					n_stored_fields * sizeof(mysql_row_templ_t));
 	}
 
 	prebuilt->template_type = templ_type;
@@ -3439,15 +3440,17 @@ build_template(
 
 	/* Note that in InnoDB, i is the column number. MySQL calls columns
 	'fields'. */
-	for (i = 0; i < n_fields; i++) {
+	for (sql_idx = 0; sql_idx < n_fields; sql_idx++) {
 		templ = prebuilt->mysql_template + n_requested_fields;
-		field = table->field[i];
+		field = table->field[sql_idx];
+		if (!field->stored_in_db)
+		  goto skip_field;
 
 		if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
 			/* Decide which columns we should fetch
 			and which we can skip. */
 			register const ibool	index_contains_field =
-				dict_index_contains_col_or_prefix(index, i);
+				dict_index_contains_col_or_prefix(index, innodb_idx);
 
 			if (!index_contains_field && prebuilt->read_just_key) {
 				/* If this is a 'key read', we do not need
@@ -3462,8 +3465,8 @@ build_template(
 				goto include_field;
 			}
 
-			if (bitmap_is_set(table->read_set, i) ||
-			    bitmap_is_set(table->write_set, i)) {
+			if (bitmap_is_set(table->read_set, sql_idx) ||
+			    bitmap_is_set(table->write_set, sql_idx)) {
 				/* This field is needed in the query */
 
 				goto include_field;
@@ -3471,7 +3474,7 @@ build_template(
 
 			if (fetch_primary_key_cols
 				&& dict_table_col_in_clustered_key(
-					index->table, i)) {
+					index->table, innodb_idx)) {
 				/* This field is needed in the query */
 
 				goto include_field;
@@ -3484,14 +3487,14 @@ build_template(
 include_field:
 		n_requested_fields++;
 
-		templ->col_no = i;
+		templ->col_no = innodb_idx;
 
 		if (index == clust_index) {
 			templ->rec_field_no = dict_col_get_clust_pos_noninline(
-				&index->table->cols[i], index);
+				&index->table->cols[innodb_idx], index);
 		} else {
 			templ->rec_field_no = dict_index_get_nth_col_pos(
-								index, i);
+								index, innodb_idx);
 		}
 
 		if (templ->rec_field_no == ULINT_UNDEFINED) {
@@ -3517,7 +3520,7 @@ include_field:
 			mysql_prefix_len = templ->mysql_col_offset
 				+ templ->mysql_col_len;
 		}
-		templ->type = index->table->cols[i].mtype;
+		templ->type = index->table->cols[innodb_idx].mtype;
 		templ->mysql_type = (ulint)field->type();
 
 		if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
@@ -3526,16 +3529,18 @@ include_field:
 		}
 
 		templ->charset = dtype_get_charset_coll_noninline(
-				index->table->cols[i].prtype);
-		templ->mbminlen = index->table->cols[i].mbminlen;
-		templ->mbmaxlen = index->table->cols[i].mbmaxlen;
-		templ->is_unsigned = index->table->cols[i].prtype
+				index->table->cols[innodb_idx].prtype);
+		templ->mbminlen = index->table->cols[innodb_idx].mbminlen;
+		templ->mbmaxlen = index->table->cols[innodb_idx].mbmaxlen;
+		templ->is_unsigned = index->table->cols[innodb_idx].prtype
 							& DATA_UNSIGNED;
 		if (templ->type == DATA_BLOB) {
 			prebuilt->templ_contains_blob = TRUE;
 		}
 skip_field:
-		;
+                if (field->stored_in_db) {
+                    innodb_idx++;
+                }
 	}
 
 	prebuilt->n_template = n_requested_fields;
@@ -3998,7 +4003,7 @@ calc_row_difference(
 	ulint		n_changed = 0;
 	dfield_t	dfield;
 	dict_index_t*	clust_index;
-	uint		i;
+	uint		sql_idx, innodb_idx= 0;
 
 	n_fields = table->s->fields;
 	clust_index = dict_table_get_first_index_noninline(prebuilt->table);
@@ -4006,8 +4011,10 @@ calc_row_difference(
 	/* We use upd_buff to convert changed fields */
 	buf = (byte*) upd_buff;
 
-	for (i = 0; i < n_fields; i++) {
-		field = table->field[i];
+	for (sql_idx = 0; sql_idx < n_fields; sql_idx++) {
+		field = table->field[sql_idx];
+		if (!field->stored_in_db)
+		  continue;
 
 		o_ptr = (byte*) old_row + get_field_offset(table, field);
 		n_ptr = (byte*) new_row + get_field_offset(table, field);
@@ -4025,7 +4032,7 @@ calc_row_difference(
 
 		field_mysql_type = field->type();
 
-		col_type = prebuilt->table->cols[i].mtype;
+		col_type = prebuilt->table->cols[innodb_idx].mtype;
 
 		switch (col_type) {
 
@@ -4080,7 +4087,7 @@ calc_row_difference(
 			/* Let us use a dummy dfield to make the conversion
 			from the MySQL column format to the InnoDB format */
 
-			dict_col_copy_type_noninline(prebuilt->table->cols + i,
+			dict_col_copy_type_noninline(prebuilt->table->cols + innodb_idx,
 						     &dfield.type);
 
 			if (n_len != UNIV_SQL_NULL) {
@@ -4101,9 +4108,11 @@ calc_row_difference(
 
 			ufield->exp = NULL;
 			ufield->field_no = dict_col_get_clust_pos_noninline(
-				&prebuilt->table->cols[i], clust_index);
+				&prebuilt->table->cols[innodb_idx], clust_index);
 			n_changed++;
 		}
+                if (field->stored_in_db)
+                  innodb_idx++;
 	}
 
 	uvect->n_fields = n_changed;
@@ -5088,7 +5097,7 @@ create_table_def(
 	/* We pass 0 as the space id, and determine at a lower level the space
 	id where to store the table */
 
-	table = dict_mem_table_create(table_name, 0, n_cols, flags);
+	table = dict_mem_table_create(table_name, 0, form->s->stored_fields, flags);
 
 	if (path_of_temp_table) {
 		table->dir_path_of_temp_table =
@@ -5097,6 +5106,8 @@ create_table_def(
 
 	for (i = 0; i < n_cols; i++) {
 		field = form->field[i];
+		if (!field->stored_in_db)
+		  continue;
 
 		col_type = get_innobase_type_from_mysql_type(&unsigned_type,
 									field);
@@ -5385,7 +5396,7 @@ ha_innobase::create(
 	}
 #endif
 
-	if (form->s->fields > 1000) {
+	if (form->s->stored_fields > 1000) {
 		/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
 		but we play safe here */
 
@@ -5895,10 +5906,10 @@ ha_innobase::records_in_range(
 	KEY*		key;
 	dict_index_t*	index;
 	uchar*		key_val_buff2	= (uchar*) my_malloc(
-						  table->s->reclength
+						  table->s->stored_rec_length
 					+ table->s->max_key_length + 100,
 								MYF(MY_FAE));
-	ulint		buff2_len = table->s->reclength
+	ulint		buff2_len = table->s->stored_rec_length
 					+ table->s->max_key_length + 100;
 	dtuple_t*	range_start;
 	dtuple_t*	range_end;

=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h	2009-04-24 11:28:46 +0000
+++ b/storage/innobase/handler/ha_innodb.h	2009-10-16 22:57:48 +0000
@@ -199,6 +199,7 @@ class ha_innobase: public handler
 	int cmp_ref(const uchar *ref1, const uchar *ref2);
 	bool check_if_incompatible_data(HA_CREATE_INFO *info,
 					uint table_changes);
+	bool check_if_supported_virtual_columns(void) { return TRUE;}
 };
 
 /* Some accessor functions which the InnoDB plugin needs, but which

=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc	2009-09-07 20:50:10 +0000
+++ b/storage/myisam/ha_myisam.cc	2009-10-16 22:57:48 +0000
@@ -252,7 +252,7 @@ int table2myisam(TABLE *table_arg, MI_KE
   record= table_arg->record[0];
   recpos= 0;
   recinfo_pos= recinfo;
-  while (recpos < (uint) share->reclength)
+  while (recpos < (uint) share->stored_rec_length)
   {
     Field **field, *found= 0;
     minpos= share->reclength;

=== modified file 'storage/myisam/ha_myisam.h'
--- a/storage/myisam/ha_myisam.h	2009-09-07 20:50:10 +0000
+++ b/storage/myisam/ha_myisam.h	2009-10-16 22:57:48 +0000
@@ -133,6 +133,7 @@ class ha_myisam: public handler
   int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt);
   int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
   bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
+  bool check_if_supported_virtual_columns(void) { return TRUE;}
 #ifdef HAVE_REPLICATION
   int dump(THD* thd, int fd);
   int net_read_dump(NET* net);

=== modified file 'storage/pbxt/src/discover_xt.cc'
--- a/storage/pbxt/src/discover_xt.cc	2009-09-03 13:20:22 +0000
+++ b/storage/pbxt/src/discover_xt.cc	2009-10-16 22:57:48 +0000
@@ -1340,7 +1340,8 @@ int xt_create_table_frm(handlerton *hton
 				COLUMN_FORMAT_TYPE_FIXED,
 #endif
 		       NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/, 
-		       NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/)) 
+		       NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/, 
+		       NULL /*vcol_info*/)) 
 #endif
 			goto error;
 

=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc	2009-09-09 21:06:57 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc	2009-10-16 22:57:48 +0000
@@ -3200,12 +3200,12 @@ ha_innobase::open(
 	}
 
 	/* Create buffers for packing the fields of a record. Why
-	table->reclength did not work here? Obviously, because char
+	table->stored_rec_length did not work here? Obviously, because char
 	fields when packed actually became 1 byte longer, when we also
 	stored the string length as the first byte. */
 
 	upd_and_key_val_buff_len =
-				table->s->reclength + table->s->max_key_length
+				table->s->stored_rec_length + table->s->max_key_length
 							+ MAX_REF_PARTS * 3;
 	if (!(uchar*) my_multi_malloc(MYF(MY_WME),
 			&upd_buff, upd_and_key_val_buff_len,
@@ -3280,7 +3280,7 @@ retry:
 
 	prebuilt = row_create_prebuilt(ib_table);
 
-	prebuilt->mysql_row_len = table->s->reclength;
+	prebuilt->mysql_row_len = table->s->stored_rec_length;;
 	prebuilt->default_rec = table->s->default_values;
 	ut_ad(prebuilt->default_rec);
 
@@ -3996,11 +3996,11 @@ build_template(
 	dict_index_t*	clust_index;
 	mysql_row_templ_t* templ;
 	Field*		field;
-	ulint		n_fields;
+	ulint		n_fields, n_stored_fields;
 	ulint		n_requested_fields	= 0;
 	ibool		fetch_all_in_key	= FALSE;
 	ibool		fetch_primary_key_cols	= FALSE;
-	ulint		i;
+	ulint		i, sql_idx, innodb_idx=0;
 	/* byte offset of the end of last requested column */
 	ulint		mysql_prefix_len	= 0;
 
@@ -4061,10 +4061,11 @@ build_template(
 	}
 
 	n_fields = (ulint)table->s->fields; /* number of columns */
+	n_stored_fields= (ulint)table->s->stored_fields; /* number of stored columns */
 
 	if (!prebuilt->mysql_template) {
 		prebuilt->mysql_template = (mysql_row_templ_t*)
-			mem_alloc(n_fields * sizeof(mysql_row_templ_t));
+			mem_alloc(n_stored_fields * sizeof(mysql_row_templ_t));
 	}
 
 	prebuilt->template_type = templ_type;
@@ -4074,15 +4075,17 @@ build_template(
 
 	/* Note that in InnoDB, i is the column number. MySQL calls columns
 	'fields'. */
-	for (i = 0; i < n_fields; i++) {
+	for (sql_idx = 0; sql_idx < n_fields; sql_idx++) {
 		templ = prebuilt->mysql_template + n_requested_fields;
-		field = table->field[i];
+		field = table->field[sql_idx];
+		if (!field->stored_in_db)
+		  goto skip_field;
 
 		if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
 			/* Decide which columns we should fetch
 			and which we can skip. */
 			register const ibool	index_contains_field =
-				dict_index_contains_col_or_prefix(index, i);
+				dict_index_contains_col_or_prefix(index, innodb_idx);
 
 			if (!index_contains_field && prebuilt->read_just_key) {
 				/* If this is a 'key read', we do not need
@@ -4097,8 +4100,8 @@ build_template(
 				goto include_field;
 			}
 
-			if (bitmap_is_set(table->read_set, i) ||
-			    bitmap_is_set(table->write_set, i)) {
+			if (bitmap_is_set(table->read_set, sql_idx) ||
+			    bitmap_is_set(table->write_set, sql_idx)) {
 				/* This field is needed in the query */
 
 				goto include_field;
@@ -4106,7 +4109,7 @@ build_template(
 
 			if (fetch_primary_key_cols
 				&& dict_table_col_in_clustered_key(
-					index->table, i)) {
+					index->table, innodb_idx)) {
 				/* This field is needed in the query */
 
 				goto include_field;
@@ -4119,14 +4122,14 @@ build_template(
 include_field:
 		n_requested_fields++;
 
-		templ->col_no = i;
+		templ->col_no = innodb_idx;
 
 		if (index == clust_index) {
 			templ->rec_field_no = dict_col_get_clust_pos(
-				&index->table->cols[i], index);
+				&index->table->cols[innodb_idx], index);
 		} else {
 			templ->rec_field_no = dict_index_get_nth_col_pos(
-								index, i);
+								index, innodb_idx);
 		}
 
 		if (templ->rec_field_no == ULINT_UNDEFINED) {
@@ -4152,7 +4155,7 @@ include_field:
 			mysql_prefix_len = templ->mysql_col_offset
 				+ templ->mysql_col_len;
 		}
-		templ->type = index->table->cols[i].mtype;
+		templ->type = index->table->cols[innodb_idx].mtype;
 		templ->mysql_type = (ulint)field->type();
 
 		if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
@@ -4161,16 +4164,18 @@ include_field:
 		}
 
 		templ->charset = dtype_get_charset_coll(
-			index->table->cols[i].prtype);
-		templ->mbminlen = index->table->cols[i].mbminlen;
-		templ->mbmaxlen = index->table->cols[i].mbmaxlen;
-		templ->is_unsigned = index->table->cols[i].prtype
+				index->table->cols[innodb_idx].prtype);
+		templ->mbminlen = index->table->cols[innodb_idx].mbminlen;
+		templ->mbmaxlen = index->table->cols[innodb_idx].mbmaxlen;
+		templ->is_unsigned = index->table->cols[innodb_idx].prtype
 							& DATA_UNSIGNED;
 		if (templ->type == DATA_BLOB) {
 			prebuilt->templ_contains_blob = TRUE;
 		}
 skip_field:
-		;
+                if (field->stored_in_db) {
+                    innodb_idx++;
+                }
 	}
 
 	prebuilt->n_template = n_requested_fields;
@@ -4634,7 +4639,7 @@ calc_row_difference(
 	ulint		n_changed = 0;
 	dfield_t	dfield;
 	dict_index_t*	clust_index;
-	uint		i;
+	uint		sql_idx, innodb_idx= 0;
 
 	n_fields = table->s->fields;
 	clust_index = dict_table_get_first_index(prebuilt->table);
@@ -4642,8 +4647,10 @@ calc_row_difference(
 	/* We use upd_buff to convert changed fields */
 	buf = (byte*) upd_buff;
 
-	for (i = 0; i < n_fields; i++) {
-		field = table->field[i];
+	for (sql_idx = 0; sql_idx < n_fields; sql_idx++) {
+		field = table->field[sql_idx];
+		if (!field->stored_in_db)
+		  continue;
 
 		o_ptr = (const byte*) old_row + get_field_offset(table, field);
 		n_ptr = (const byte*) new_row + get_field_offset(table, field);
@@ -4661,7 +4668,7 @@ calc_row_difference(
 
 		field_mysql_type = field->type();
 
-		col_type = prebuilt->table->cols[i].mtype;
+		col_type = prebuilt->table->cols[innodb_idx].mtype;
 
 		switch (col_type) {
 
@@ -4716,7 +4723,7 @@ calc_row_difference(
 			/* Let us use a dummy dfield to make the conversion
 			from the MySQL column format to the InnoDB format */
 
-			dict_col_copy_type(prebuilt->table->cols + i,
+			dict_col_copy_type(prebuilt->table->cols + innodb_idx,
 					   dfield_get_type(&dfield));
 
 			if (n_len != UNIV_SQL_NULL) {
@@ -4735,9 +4742,11 @@ calc_row_difference(
 			ufield->exp = NULL;
 			ufield->orig_len = 0;
 			ufield->field_no = dict_col_get_clust_pos(
-				&prebuilt->table->cols[i], clust_index);
+				&prebuilt->table->cols[innodb_idx], clust_index);
 			n_changed++;
 		}
+                if (field->stored_in_db)
+                  innodb_idx++;
 	}
 
 	uvect->n_fields = n_changed;
@@ -5754,7 +5763,7 @@ create_table_def(
 	/* We pass 0 as the space id, and determine at a lower level the space
 	id where to store the table */
 
-	table = dict_mem_table_create(table_name, 0, n_cols, flags);
+	table = dict_mem_table_create(table_name, 0, form->s->stored_fields, flags);
 
 	if (path_of_temp_table) {
 		table->dir_path_of_temp_table =
@@ -5763,6 +5772,8 @@ create_table_def(
 
 	for (i = 0; i < n_cols; i++) {
 		field = form->field[i];
+		if (!field->stored_in_db)
+		  continue;
 
 		col_type = get_innobase_type_from_mysql_type(&unsigned_type,
 									field);
@@ -6224,7 +6235,7 @@ ha_innobase::create(
 	}
 #endif
 
-	if (form->s->fields > 1000) {
+	if (form->s->stored_fields > 1000) {
 		/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
 		but we play safe here */
 
@@ -6890,10 +6901,10 @@ ha_innobase::records_in_range(
 	KEY*		key;
 	dict_index_t*	index;
 	uchar*		key_val_buff2	= (uchar*) my_malloc(
-						  table->s->reclength
+						  table->s->stored_rec_length
 					+ table->s->max_key_length + 100,
 								MYF(MY_FAE));
-	ulint		buff2_len = table->s->reclength
+	ulint		buff2_len = table->s->stored_rec_length
 					+ table->s->max_key_length + 100;
 	dtuple_t*	range_start;
 	dtuple_t*	range_end;

=== modified file 'storage/xtradb/handler/ha_innodb.h'
--- a/storage/xtradb/handler/ha_innodb.h	2009-03-26 06:11:11 +0000
+++ b/storage/xtradb/handler/ha_innodb.h	2009-10-16 22:57:48 +0000
@@ -204,6 +204,7 @@ class ha_innobase: public handler
 	/** @} */
 	bool check_if_incompatible_data(HA_CREATE_INFO *info,
 					uint table_changes);
+	bool check_if_supported_virtual_columns(void) { return TRUE; }
 };
 
 /* Some accessor functions which the InnoDB plugin needs, but which