summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/vcol
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:24:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:24:36 +0000
commit06eaf7232e9a920468c0f8d74dcf2fe8b555501c (patch)
treee2c7b5777f728320e5b5542b6213fd3591ba51e2 /mysql-test/suite/vcol
parentInitial commit. (diff)
downloadmariadb-06eaf7232e9a920468c0f8d74dcf2fe8b555501c.tar.xz
mariadb-06eaf7232e9a920468c0f8d74dcf2fe8b555501c.zip
Adding upstream version 1:10.11.6.upstream/1%10.11.6
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mysql-test/suite/vcol')
-rw-r--r--mysql-test/suite/vcol/disabled.def0
-rw-r--r--mysql-test/suite/vcol/inc/vcol_cleanup.inc25
-rw-r--r--mysql-test/suite/vcol/inc/vcol_column_def_options.inc113
-rw-r--r--mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc43
-rw-r--r--mysql-test/suite/vcol/inc/vcol_handler.inc77
-rw-r--r--mysql-test/suite/vcol/inc/vcol_init_vars.pre17
-rw-r--r--mysql-test/suite/vcol/inc/vcol_ins_upd.inc381
-rw-r--r--mysql-test/suite/vcol/inc/vcol_keys.inc233
-rw-r--r--mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc174
-rw-r--r--mysql-test/suite/vcol/inc/vcol_partition.inc139
-rw-r--r--mysql-test/suite/vcol/inc/vcol_select.inc222
-rw-r--r--mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc42
-rw-r--r--mysql-test/suite/vcol/inc/vcol_trigger_sp.inc296
-rw-r--r--mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc21
-rw-r--r--mysql-test/suite/vcol/inc/vcol_view.inc211
-rw-r--r--mysql-test/suite/vcol/r/alter_inplace-9045.result45
-rw-r--r--mysql-test/suite/vcol/r/binlog.result97
-rw-r--r--mysql-test/suite/vcol/r/charsets.result31
-rw-r--r--mysql-test/suite/vcol/r/cross_db.result17
-rw-r--r--mysql-test/suite/vcol/r/delayed.result7
-rw-r--r--mysql-test/suite/vcol/r/index.result101
-rw-r--r--mysql-test/suite/vcol/r/innodb_autoinc_vcol.result16
-rw-r--r--mysql-test/suite/vcol/r/innodb_virtual_fk.result101
-rw-r--r--mysql-test/suite/vcol/r/load_data.result20
-rw-r--r--mysql-test/suite/vcol/r/mrr.result25
-rw-r--r--mysql-test/suite/vcol/r/myisam_repair_prefix_varchar.result134
-rw-r--r--mysql-test/suite/vcol/r/not_supported.result57
-rw-r--r--mysql-test/suite/vcol/r/partition.result103
-rw-r--r--mysql-test/suite/vcol/r/races.result16
-rw-r--r--mysql-test/suite/vcol/r/range.result9
-rw-r--r--mysql-test/suite/vcol/r/rpl_vcol.result26
-rw-r--r--mysql-test/suite/vcol/r/update.result179
-rw-r--r--mysql-test/suite/vcol/r/update_binlog.result361
-rw-r--r--mysql-test/suite/vcol/r/upgrade.result34
-rw-r--r--mysql-test/suite/vcol/r/vcol_archive.result7
-rw-r--r--mysql-test/suite/vcol/r/vcol_blackhole.result7
-rw-r--r--mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result251
-rw-r--r--mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result146
-rw-r--r--mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result146
-rw-r--r--mysql-test/suite/vcol/r/vcol_csv.result7
-rw-r--r--mysql-test/suite/vcol/r/vcol_handler_aria.result76
-rw-r--r--mysql-test/suite/vcol/r/vcol_handler_innodb.result76
-rw-r--r--mysql-test/suite/vcol/r/vcol_handler_myisam.result76
-rw-r--r--mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result673
-rw-r--r--mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result628
-rw-r--r--mysql-test/suite/vcol/r/vcol_keys_aria.result2
-rw-r--r--mysql-test/suite/vcol/r/vcol_keys_innodb.result286
-rw-r--r--mysql-test/suite/vcol/r/vcol_keys_myisam.result420
-rw-r--r--mysql-test/suite/vcol/r/vcol_memory.result7
-rw-r--r--mysql-test/suite/vcol/r/vcol_merge.result8
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result579
-rw-r--r--mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result258
-rw-r--r--mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result258
-rw-r--r--mysql-test/suite/vcol/r/vcol_partition_innodb.result89
-rw-r--r--mysql-test/suite/vcol/r/vcol_partition_myisam.result89
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_innodb.result270
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_myisam.result515
-rw-r--r--mysql-test/suite/vcol/r/vcol_sql_mode.result434
-rw-r--r--mysql-test/suite/vcol/r/vcol_sql_mode_datetime.result113
-rw-r--r--mysql-test/suite/vcol/r/vcol_sql_mode_time.result113
-rw-r--r--mysql-test/suite/vcol/r/vcol_sql_mode_timestamp.result107
-rw-r--r--mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result345
-rw-r--r--mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result2956
-rw-r--r--mysql-test/suite/vcol/r/vcol_syntax.result240
-rw-r--r--mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result316
-rw-r--r--mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result316
-rw-r--r--mysql-test/suite/vcol/r/vcol_view_innodb.result286
-rw-r--r--mysql-test/suite/vcol/r/vcol_view_myisam.result283
-rw-r--r--mysql-test/suite/vcol/r/wrong_arena.result89
-rw-r--r--mysql-test/suite/vcol/t/alter_inplace-9045.test32
-rw-r--r--mysql-test/suite/vcol/t/binlog.test83
-rw-r--r--mysql-test/suite/vcol/t/charsets.test19
-rw-r--r--mysql-test/suite/vcol/t/cross_db.test12
-rw-r--r--mysql-test/suite/vcol/t/delayed.test5
-rw-r--r--mysql-test/suite/vcol/t/index.test97
-rw-r--r--mysql-test/suite/vcol/t/innodb_autoinc_vcol.test9
-rw-r--r--mysql-test/suite/vcol/t/innodb_virtual_fk.test115
-rw-r--r--mysql-test/suite/vcol/t/load_data.test15
-rw-r--r--mysql-test/suite/vcol/t/mrr.test13
-rw-r--r--mysql-test/suite/vcol/t/myisam_repair_prefix_varchar.test131
-rw-r--r--mysql-test/suite/vcol/t/not_supported.test66
-rw-r--r--mysql-test/suite/vcol/t/partition.test80
-rw-r--r--mysql-test/suite/vcol/t/races.test22
-rw-r--r--mysql-test/suite/vcol/t/range.test10
-rw-r--r--mysql-test/suite/vcol/t/rpl_vcol.test70
-rw-r--r--mysql-test/suite/vcol/t/update.test129
-rw-r--r--mysql-test/suite/vcol/t/update_binlog.test14
-rw-r--r--mysql-test/suite/vcol/t/upgrade.test28
-rw-r--r--mysql-test/suite/vcol/t/vcol_archive.test49
-rw-r--r--mysql-test/suite/vcol/t/vcol_blackhole.test49
-rw-r--r--mysql-test/suite/vcol/t/vcol_blocked_sql_funcs.test49
-rw-r--r--mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc359
-rw-r--r--mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test51
-rw-r--r--mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test50
-rw-r--r--mysql-test/suite/vcol/t/vcol_csv.test48
-rw-r--r--mysql-test/suite/vcol/t/vcol_handler_aria.test52
-rw-r--r--mysql-test/suite/vcol/t/vcol_handler_innodb.test51
-rw-r--r--mysql-test/suite/vcol/t/vcol_handler_myisam.test50
-rw-r--r--mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test51
-rw-r--r--mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test50
-rw-r--r--mysql-test/suite/vcol/t/vcol_keys_aria.test3
-rw-r--r--mysql-test/suite/vcol/t/vcol_keys_innodb.opt1
-rw-r--r--mysql-test/suite/vcol/t/vcol_keys_innodb.test137
-rw-r--r--mysql-test/suite/vcol/t/vcol_keys_myisam.test315
-rw-r--r--mysql-test/suite/vcol/t/vcol_memory.test48
-rw-r--r--mysql-test/suite/vcol/t/vcol_merge.test57
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.opt1
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test543
-rw-r--r--mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test53
-rw-r--r--mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test52
-rw-r--r--mysql-test/suite/vcol/t/vcol_partition_innodb.test51
-rw-r--r--mysql-test/suite/vcol/t/vcol_partition_myisam.test51
-rw-r--r--mysql-test/suite/vcol/t/vcol_select_innodb.test56
-rw-r--r--mysql-test/suite/vcol/t/vcol_select_myisam.test132
-rw-r--r--mysql-test/suite/vcol/t/vcol_sql_mode.test322
-rw-r--r--mysql-test/suite/vcol/t/vcol_sql_mode_datetime.test134
-rw-r--r--mysql-test/suite/vcol/t/vcol_sql_mode_time.test135
-rw-r--r--mysql-test/suite/vcol/t/vcol_sql_mode_timestamp.test122
-rw-r--r--mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test193
-rw-r--r--mysql-test/suite/vcol/t/vcol_supported_sql_funcs.test49
-rw-r--r--mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc1223
-rw-r--r--mysql-test/suite/vcol/t/vcol_syntax.test189
-rw-r--r--mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test52
-rw-r--r--mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test51
-rw-r--r--mysql-test/suite/vcol/t/vcol_view_innodb.test55
-rw-r--r--mysql-test/suite/vcol/t/vcol_view_myisam.test50
-rw-r--r--mysql-test/suite/vcol/t/wrong_arena.test66
127 files changed, 19845 insertions, 0 deletions
diff --git a/mysql-test/suite/vcol/disabled.def b/mysql-test/suite/vcol/disabled.def
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/mysql-test/suite/vcol/disabled.def
diff --git a/mysql-test/suite/vcol/inc/vcol_cleanup.inc b/mysql-test/suite/vcol/inc/vcol_cleanup.inc
new file mode 100644
index 00000000..f8adec03
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_cleanup.inc
@@ -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
diff --git a/mysql-test/suite/vcol/inc/vcol_column_def_options.inc b/mysql-test/suite/vcol/inc/vcol_column_def_options.inc
new file mode 100644
index 00000000..61eac001
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_column_def_options.inc
@@ -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);
+show create table t1;
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN
+alter table t1 modify b int as (a % 2) persistent;
+show create table t1;
+drop table t1;
diff --git a/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc b/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc
new file mode 100644
index 00000000..91a55013
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_dependancies_on_vcol.inc
@@ -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);
+
diff --git a/mysql-test/suite/vcol/inc/vcol_handler.inc b/mysql-test/suite/vcol/inc/vcol_handler.inc
new file mode 100644
index 00000000..49e2ddc2
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_handler.inc
@@ -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;
diff --git a/mysql-test/suite/vcol/inc/vcol_init_vars.pre b/mysql-test/suite/vcol/inc/vcol_init_vars.pre
new file mode 100644
index 00000000..f3c55c22
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_init_vars.pre
@@ -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;
diff --git a/mysql-test/suite/vcol/inc/vcol_ins_upd.inc b/mysql-test/suite/vcol/inc/vcol_ins_upd.inc
new file mode 100644
index 00000000..8cf0fb9e
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_ins_upd.inc
@@ -0,0 +1,381 @@
+################################################################################
+# 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 ignore 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 ignore 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 ignore 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 ignore 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 ignore 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 ignore 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.default_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;
+
+--echo #
+--echo # MDEV-9093: Persistent computed column is not updated when
+--echo # update query contains join
+--echo #
+
+CREATE TABLE `t1` (
+ `id` bigint(20) NOT NULL,
+ `name` varchar(254) DEFAULT NULL,
+ `name_hash` varchar(64) AS (sha1(name)) PERSISTENT,
+ PRIMARY KEY (`id`)
+);
+
+insert into t1(id,name) values (2050, 'name1'),(2051, 'name2'),(2041, 'name3');
+
+create table t2 (id bigint);
+insert into t2 values (2050),(2051),(2041);
+
+select * from t1;
+
+update t1 join t2 using(id) set name = concat(name,
+'+1') where t1.id in (2051,2041);
+
+select * from t1;
+
+drop table t1,t2;
+
+--echo #
+--echo # Test error handling with virtual columns
+--echo #
+
+CREATE TABLE IF NOT EXISTS t1 (
+ f1 DOUBLE,
+ f2 DOUBLE NOT NULL DEFAULT '0',
+ f3 DOUBLE,
+ f4 DOUBLE NOT NULL DEFAULT '0',
+ v1 DOUBLE AS ( ( f1 DIV ( f1 ) ) <= f2 ) VIRTUAL,
+ v2 DOUBLE AS ( ( f2 DIV ( f2 ) ) <= f2 ) VIRTUAL,
+ KEY (v2)
+);
+
+set sql_mode='strict_all_tables,error_for_division_by_zero';
+--error ER_DIVISION_BY_ZERO
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 0, 0, 0);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 1, 1, 1);
+--error ER_DIVISION_BY_ZERO
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+INSERT IGNORE INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 1, 1, 1);
+select v1 from t1;
+
+--error ER_DIVISION_BY_ZERO
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0,0,0,0), (2,2,2,2);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (3,3,3,3), (4,4,4,4);
+--error ER_DIVISION_BY_ZERO
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (5,5,5,5), (1,0,0,0);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (6,6,0,0);
+
+--error ER_DIVISION_BY_ZERO
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT f3, f4, f3, f4 FROM t1;
+select count(*) from t1;
+DELETE FROM t1 WHERE v2 != f1 and f1 < 5;
+select count(*) from t1;
+select * from t1;
+--error ER_BAD_NULL_ERROR
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1;
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1 where f2 !=0;
+UPDATE t1 SET f3 = v1 WHERE f2 = 2 AND v2 is null;
+SELECT * FROM t1;
+TRUNCATE TABLE t1;
+
+set sql_mode='error_for_division_by_zero';
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 0, 0, 0);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 1, 1, 1);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 1, 1, 1);
+select v1 from t1;
+
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0,0,0,0), (2,2,2,2);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (3,3,3,3), (4,4,4,4);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (5,5,5,5), (1,0,0,0);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (6,6,0,0);
+
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT f3, f4, f3, f4 FROM t1;
+select count(*) from t1;
+DELETE FROM t1 WHERE v2 != f1 and f1 < 5;
+select count(*) from t1;
+select * from t1;
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1;
+UPDATE t1 SET f3 = v1 WHERE f2 = 2 AND v2 is null;
+drop table t1;
+set sql_mode=@@global.sql_mode;
diff --git a/mysql-test/suite/vcol/inc/vcol_keys.inc b/mysql-test/suite/vcol/inc/vcol_keys.inc
new file mode 100644
index 00000000..8ec89daf
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_keys.inc
@@ -0,0 +1,233 @@
+################################################################################
+# 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
+create table t1 (a int, b int as (a*2) unique);
+drop table t1;
+create table t1 (a int, b int as (a*2) persistent unique);
+show create table t1;
+describe t1;
+drop table t1;
+
+create table t1 (a int, b int as (a*2), unique key (b));
+drop table t1;
+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));
+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
+create table t1 (a int, b int as (a*2), index (b));
+drop table t1;
+create table t1 (a int, b int as (a*2), index (a,b));
+drop table t1;
+
+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));
+alter table t1 add index (b);
+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 geometry as (a+1) persistent, spatial index (b));
+ create table t1 (a int, b int as (a+1) persistent);
+ --error ER_WRONG_ARGUMENTS
+ alter table t1 add spatial index (b);
+ drop table t1;
+}
+
+--echo # FOREIGN KEY
+
+--echo # Rejected FK options.
+--error ER_WRONG_FK_OPTION_FOR_GENERATED_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_GENERATED_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_GENERATED_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_GENERATED_COLUMN
+alter table t1 add foreign key (b) references t2(a) on update set null;
+--error ER_WRONG_FK_OPTION_FOR_GENERATED_COLUMN
+alter table t1 add foreign key (b) references t2(a) on update cascade;
+--error ER_WRONG_FK_OPTION_FOR_GENERATED_COLUMN
+alter table t1 add foreign key (b) references t2(a) on delete set null;
+drop table t1;
+
+if ($with_foreign_keys) {
+--error ER_CANT_CREATE_TABLE
+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_CANT_CREATE_TABLE
+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
+
+#
+# Restrictions when indexed:
+#
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b timestamp as (now()), key (b));
+create table t1 (a int, b timestamp as (now()));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add index (b);
+drop table t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b varchar(100) as (user()), key (b));
+create table t1 (a int, b varchar(100) as (user()));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add index (b);
+drop table t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b double as (rand()), key (b));
+create table t1 (a int, b double as (rand()));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add index (b);
+drop table t1;
+
+#
+# MDEV-11598 Assertion `!table || (!table->read_set... failed
+#
+
+CREATE OR REPLACE TABLE t1 (
+ f2 DOUBLE NOT NULL DEFAULT '0',
+ f3 DOUBLE NOT NULL DEFAULT '0',
+ f4 DOUBLE,
+ f5 DOUBLE DEFAULT '0',
+ v4 DOUBLE AS (IF(f4,f3,f2)) VIRTUAL,
+ KEY (f5),
+ KEY (v4)
+);
+
+INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,4,1,0),(5,7,NULL,0);
+INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f3, f5, f3 FROM t1;
+INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,0,NULL,1);
+INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f5, f5, f3 FROM t1;
+DELETE FROM t1 WHERE f5 = 1 OR v4 = 4 ORDER BY f5,v4 LIMIT 9;
+SELECT * from t1;
+DROP TABLE t1;
+
+# Another similar failure
+
+CREATE TABLE t1 (
+ d DECIMAL(63,0) NOT NULL DEFAULT 0,
+ c VARCHAR(64) NOT NULL DEFAULT '',
+ vd DECIMAL(63,0) AS (d) VIRTUAL,
+ vc VARCHAR(2048) AS (c) VIRTUAL,
+ pk BIGINT AUTO_INCREMENT,
+ PRIMARY KEY(pk));
+
+INSERT INTO t1 (d,c) VALUES (0.5,'foo');
+SELECT * FROM t1 WHERE vc != 'bar' ORDER BY vd;
+DROP TABLE t1;
+
+#
+# MDEV-11729: Crash when using partial indexed virtual fields
+#
+
+CREATE TABLE t1 (
+ pk BIGINT,
+ c CHAR(64) NOT NULL DEFAULT '',
+ vc CHAR(64) AS (c) VIRTUAL,
+ PRIMARY KEY(pk),
+ INDEX(vc(32))
+);
+DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc b/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc
new file mode 100644
index 00000000..771053fa
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc
@@ -0,0 +1,174 @@
+################################################################################
+# 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_GENERATED_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_GENERATED_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,0)) 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,0)));
+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;
+
+--echo #
+--echo # MDEV-6103 - Adding/removing non-materialized virtual column triggers
+--echo # table recreation
+--echo #
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
+enable_info;
+ALTER TABLE t1 ADD COLUMN b INT AS (a + 1) VIRTUAL;
+ALTER TABLE t1 DROP COLUMN b;
+disable_info;
+CHECK TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/inc/vcol_partition.inc b/mysql-test/suite/vcol/inc/vcol_partition.inc
new file mode 100644
index 00000000..8a667b6e
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_partition.inc
@@ -0,0 +1,139 @@
+################################################################################
+# 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);
+insert into t1 (a) values ('2007-01-02');
+select * from t1;
+
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+
+--echo # Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+
+select * from t1;
+
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+
+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);
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+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;
+#select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+
+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;
+
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+
+--echo # Modify the expression of virtual column b
+ALTER TABLE t1 modify b int as (year(a)-1);
+
+select * from t1;
+
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+
+drop table t1;
+
+#
+# Restrictions when partitioned
+#
+
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+create table t1 (a int, b datetime as (now())) partition by hash(b+1) partitions 3;
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+create table t1 (a int, b varchar(100) as (user())) partition by hash(b+1) partitions 3;
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+create table t1 (a int, b double as (rand())) partition by hash(b+1) partitions 3;
diff --git a/mysql-test/suite/vcol/inc/vcol_select.inc b/mysql-test/suite/vcol/inc/vcol_select.inc
new file mode 100644
index 00000000..56e1fc7a
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_select.inc
@@ -0,0 +1,222 @@
+################################################################################
+# 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),(5),(4),(7);
+
+
+--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
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
+let $s = select * from (select a,b,c from t1) as t11;
+eval $s;
+eval explain $s;
+
+set optimizer_switch=@tmp_optimizer_switch;
+
+--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.default_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.default_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;
+
diff --git a/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc
new file mode 100644
index 00000000..c3f15941
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_supported_sql_funcs.inc
@@ -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 ignore 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;
diff --git a/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
new file mode 100644
index 00000000..c7dedcdd
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_trigger_sp.inc
@@ -0,0 +1,296 @@
+################################################################################
+# 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;
+
+--echo #
+--echo # MDEV-3845 values of virtual columns are not computed for triggers
+--echo #
+
+CREATE TABLE t1 (
+ a INTEGER UNSIGNED NULL DEFAULT NULL,
+ b INTEGER UNSIGNED GENERATED ALWAYS AS (a) VIRTUAL
+);
+
+CREATE TABLE t2 (c INTEGER UNSIGNED NOT NULL);
+
+DELIMITER |;
+
+CREATE TRIGGER t1_ins_aft
+ AFTER INSERT
+ ON t1
+ FOR EACH ROW
+BEGIN
+ INSERT INTO t2 (c) VALUES (NEW.b);
+END |
+
+CREATE TRIGGER t1_del_bef
+ BEFORE DELETE
+ ON t1
+ FOR EACH ROW
+BEGIN
+ INSERT INTO t2 (c) VALUES (OLD.b);
+END |
+
+DELIMITER ;|
+
+INSERT INTO t1 (a) VALUES (1), (2), (3);
+SELECT * FROM t2;
+DELETE FROM t1;
+SELECT * FROM t2;
+
+DROP TRIGGER t1_ins_aft;
+DROP TRIGGER t1_del_bef;
+DROP TABLE t1,t2;
+
+#
+# MDEV-11706 Assertion `is_stat_field || !table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || (table->vcol_set && bitmap_is_set(table->vcol_set, field_index)))' failed in Field_time::store_TIME_with_warning
+#
+create table t1 (i int, t time not null, vt time(4) as (t) virtual);
+create trigger trg before update on t1 for each row set @a = 1;
+insert ignore into t1 (i) values (1);
+drop table t1;
+
+--echo #
+--echo # Examine the number of times triggers are recalculated for updates
+--echo #
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1 (
+ a INTEGER UNSIGNED NULL DEFAULT NULL,
+ b CHAR(10) NULL DEFAULT NULL,
+ c blob NULL DEFAULT NULL,
+ blob_a blob GENERATED ALWAYS AS (last_value(@a:=@a+1,a)) VIRTUAL,
+ blob_b blob GENERATED ALWAYS AS (last_value(@b:=@b+1,b)) VIRTUAL,
+ blob_c blob GENERATED ALWAYS AS (last_value(@c:=@c+1,c)) VIRTUAL
+);
+
+DELIMITER |;
+CREATE TRIGGER t1_ins
+ BEFORE INSERT
+ ON t1
+ FOR EACH ROW
+BEGIN
+ IF NEW.b IS NULL THEN
+ SET NEW.b="generated before insert";
+ END IF;
+END |
+
+CREATE TRIGGER t1_update
+ BEFORE UPDATE
+ ON t1
+ FOR EACH ROW
+BEGIN
+ IF NEW.b IS NULL or NEW.c IS NULL THEN
+ SET NEW.b="generated before update";
+ SET NEW.c="generated before update";
+ END IF;
+END |
+
+DELIMITER ;|
+
+--echo # Inserts
+set @a=0,@b=0,@c=0;
+
+--disable_ps2_protocol
+insert into t1 (a) values(1);
+insert into t1 (a,b) values(2, "*2*");
+insert into t1 (a,b,c) values(3, "*3*", "**3**");
+insert into t1 (a,c) values(4, "**4**");
+select * from t1;
+select @a,@b,@c;
+select * from t1;
+select @a,@b,@c;
+select a,b,c from t1;
+select @a,@b,@c;
+select a,b,c,blob_a from t1;
+select @a,@b,@c;
+
+--echo # updates
+set @a=0,@b=0,@c=0;
+
+update t1 set a=a+100 where a=1;
+update t1 set a=a+100, b="*102*" where a=2;
+update t1 set a=a+100, b=NULL where a=3;
+update t1 set a=a+100, b="invisible", c=NULL where a=4;
+select @a,@b,@c;
+select * from t1;
+--enable_ps2_protocol
+
+drop trigger t1_ins;
+drop trigger t1_update;
+drop table t1;
+
+SET sql_mode = DEFAULT;
+
+--echo #
+--echo # Same test, but with virtual keys
+--echo #
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1 (
+ a INTEGER UNSIGNED NULL DEFAULT NULL,
+ b CHAR(10) NULL DEFAULT NULL,
+ c blob NULL DEFAULT NULL,
+ blob_a blob GENERATED ALWAYS AS (a) VIRTUAL,
+ blob_b blob GENERATED ALWAYS AS (RTRIM(b)) VIRTUAL,
+ blob_c blob GENERATED ALWAYS AS (c) VIRTUAL,
+ key (a),
+ key (blob_a(10)),
+ key (blob_b(10)),
+ key (blob_c(10))
+);
+
+DELIMITER |;
+CREATE TRIGGER t1_ins
+ BEFORE INSERT
+ ON t1
+ FOR EACH ROW
+BEGIN
+ IF NEW.b IS NULL THEN
+ SET NEW.b="generated before insert";
+ END IF;
+END |
+
+CREATE TRIGGER t1_update
+ BEFORE UPDATE
+ ON t1
+ FOR EACH ROW
+BEGIN
+ IF NEW.b IS NULL or NEW.c IS NULL THEN
+ SET NEW.b="generated before update";
+ SET NEW.c="generated before update";
+ END IF;
+END |
+
+DELIMITER ;|
+
+--echo # Inserts
+insert into t1 (a) values(1);
+insert into t1 (a,b) values(2, "*2*");
+insert into t1 (a,b,c) values(3, "*3*", "**3**");
+insert into t1 (a,c) values(4, "**4**");
+select * from t1;
+select @a,@b,@c;
+select * from t1;
+select @a,@b,@c;
+select a,b,c from t1;
+select @a,@b,@c;
+select a,b,c,blob_a from t1;
+select @a,@b,@c;
+
+--echo # updates
+update t1 set a=a+100 where a=1;
+update t1 set a=a+100, b="*102*" where a=2;
+update t1 set a=a+100, b=NULL where a=3;
+update t1 set a=a+100, b="invisible", c=NULL where a=4;
+select * from t1;
+
+drop trigger t1_ins;
+drop trigger t1_update;
+drop table t1;
+SET sql_mode = DEFAULT;
diff --git a/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc b/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc
new file mode 100644
index 00000000..f012ccf1
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_unsupported_storage_engines.inc
@@ -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_ENGINE_FOR_GENERATED_COLUMNS
+create table t1 (a int, b int as (a+1));
+create table t1 (a int not null);
+--error ER_UNSUPPORTED_ENGINE_FOR_GENERATED_COLUMNS
+alter table t1 add column b int as (a+1);
+drop table t1;
diff --git a/mysql-test/suite/vcol/inc/vcol_view.inc b/mysql-test/suite/vcol/inc/vcol_view.inc
new file mode 100644
index 00000000..abbeda60
--- /dev/null
+++ b/mysql-test/suite/vcol/inc/vcol_view.inc
@@ -0,0 +1,211 @@
+################################################################################
+# 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;
+--echo MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+--echo MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
+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;
+--echo MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+--echo MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
+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
+#
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
+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;
+
+SET optimizer_switch=@save_optimizer_switch;
+
+#
+# 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;
+
diff --git a/mysql-test/suite/vcol/r/alter_inplace-9045.result b/mysql-test/suite/vcol/r/alter_inplace-9045.result
new file mode 100644
index 00000000..862685b7
--- /dev/null
+++ b/mysql-test/suite/vcol/r/alter_inplace-9045.result
@@ -0,0 +1,45 @@
+create table t1(id int auto_increment primary key, handle int, data bigint not null default 0) engine = innodb;
+insert into t1(handle) values(12),(54),(NULL);
+select *, md5(handle) from t1;
+id handle data md5(handle)
+1 12 0 c20ad4d76fe97759aa27a0c99bff6710
+2 54 0 a684eceee76fc522773286a895bc8436
+3 NULL 0 NULL
+alter table t1 add index handle(handle), algorithm=inplace;
+alter table t1 add column hash varchar(32) as (md5(handle)) persistent, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+alter table t1 add column hash varchar(32) as (md5(handle)) persistent, add unique index hash(hash), algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+alter table t1 add column hash varchar(32) as (md5(handle)) persistent, add unique index hash(hash), algorithm=copy;
+select * from t1;
+id handle data hash
+1 12 0 c20ad4d76fe97759aa27a0c99bff6710
+2 54 0 a684eceee76fc522773286a895bc8436
+3 NULL 0 NULL
+alter table t1 modify column hash varchar(32) as (md5(handle+1)) persistent, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+alter table t1 modify column hash varchar(32) as (md5(handle+1)) persistent, algorithm=copy;
+select * from t1;
+id handle data hash
+1 12 0 c51ce410c124a10e0db5e4b97fc2af39
+2 54 0 b53b3a3d6ab90ce0268229151c9bde11
+3 NULL 0 NULL
+alter table t1 modify column handle int not null, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+alter table t1 modify column handle int not null, algorithm=copy;
+Warnings:
+Warning 1265 Data truncated for column 'handle' at row 3
+select * from t1;
+id handle data hash
+1 12 0 c51ce410c124a10e0db5e4b97fc2af39
+2 54 0 b53b3a3d6ab90ce0268229151c9bde11
+3 0 0 c4ca4238a0b923820dcc509a6f75849b
+alter table t1 drop index handle, algorithm=inplace;
+create index data on t1(data) algorithm=inplace;
+alter table t1 drop column data, algorithm=inplace;
+alter table t1 add column sha varchar(32) as (sha1(handle)) persistent, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+alter table t1 add column sha varchar(32), algorithm=inplace;
+alter table t1 drop column hash, algorithm=inplace;
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/binlog.result b/mysql-test/suite/vcol/r/binlog.result
new file mode 100644
index 00000000..1f66a632
--- /dev/null
+++ b/mysql-test/suite/vcol/r/binlog.result
@@ -0,0 +1,97 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE t1 (
+pk SERIAL,
+vcol_date DATE AS (col_date) PERSISTENT,
+vcol_int INT AS (col_int) VIRTUAL,
+vcol_year YEAR AS (col_year) PERSISTENT,
+vcol_blob BLOB AS (col_blob) VIRTUAL,
+col_date DATE,
+col_int INT NULL,
+col_blob BLOB NULL,
+col_year YEAR,
+PRIMARY KEY(pk)
+) ENGINE=InnoDB;
+INSERT INTO t1 (col_date,col_int,col_blob,col_year) VALUES ('2010-04-24',5,'foo',1981);
+SET SQL_MODE='';
+set binlog_row_image="FULL";
+CREATE VIEW v1 AS SELECT * FROM t1;
+REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1982 FROM t1;
+Warnings:
+Warning 1906 The value specified for generated column 'vcol_date' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_int' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_year' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_blob' in table 't1' has been ignored
+select col_date,col_int,col_blob,col_year from v1;
+col_date col_int col_blob col_year
+2010-04-24 5 foo 1982
+connection slave;
+select col_date,col_int,col_blob,col_year from v1;
+col_date col_int col_blob col_year
+2010-04-24 5 foo 1982
+connection master;
+DROP VIEW v1;
+set binlog_row_image="MINIMAL";
+CREATE VIEW v1 AS SELECT * FROM t1;
+REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1983 FROM t1;
+Warnings:
+Warning 1906 The value specified for generated column 'vcol_date' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_int' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_year' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_blob' in table 't1' has been ignored
+select col_date,col_int,col_blob,col_year from v1;
+col_date col_int col_blob col_year
+2010-04-24 5 foo 1983
+connection slave;
+select col_date,col_int,col_blob,col_year from v1;
+col_date col_int col_blob col_year
+2010-04-24 5 foo 1983
+connection master;
+DROP VIEW v1;
+set @@binlog_row_image="NOBLOB";
+CREATE VIEW v1 AS SELECT * FROM t1;
+REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1984 FROM t1;
+Warnings:
+Warning 1906 The value specified for generated column 'vcol_date' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_int' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_year' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'vcol_blob' in table 't1' has been ignored
+select col_date,col_int,col_blob,col_year from v1;
+col_date col_int col_blob col_year
+2010-04-24 5 foo 1984
+connection slave;
+select col_date,col_int,col_blob,col_year from v1;
+col_date col_int col_blob col_year
+2010-04-24 5 foo 1984
+connection master;
+DROP VIEW v1;
+set @@binlog_row_image=default;
+DROP TABLE t1;
+SET SQL_MODE=default;
+CREATE TABLE t1 (pk INT, a VARCHAR(3), b VARCHAR(1) AS (a) VIRTUAL, PRIMARY KEY (pk));
+INSERT IGNORE INTO t1 (pk, a) VALUES (1,'foo'),(2,'bar');
+Warnings:
+Warning 1265 Data truncated for column 'b' at row 1
+Warning 1265 Data truncated for column 'b' at row 2
+REPLACE INTO t1 (pk) VALUES (2);
+ERROR 22001: Data too long for column 'b' at row 1
+UPDATE IGNORE t1 SET a = NULL;
+Warnings:
+Warning 1265 Data truncated for column 'b' at row 1
+Warning 1265 Data truncated for column 'b' at row 2
+DROP TABLE t1;
+#
+# MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+#
+SET SESSION binlog_row_image= noblob;
+CREATE TEMPORARY TABLE t1 SELECT UUID();
+show create table t1;
+Table Create Table
+t1 CREATE TEMPORARY TABLE `t1` (
+ `UUID()` uuid DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+CREATE TABLE t2 (a INT PRIMARY KEY, b TEXT, c INT GENERATED ALWAYS AS(b));
+INSERT INTO t2 (a,b) VALUES (1,1);
+SET SESSION binlog_row_image= default;
+DROP TABLE t2;
+include/rpl_end.inc
diff --git a/mysql-test/suite/vcol/r/charsets.result b/mysql-test/suite/vcol/r/charsets.result
new file mode 100644
index 00000000..aeff00d3
--- /dev/null
+++ b/mysql-test/suite/vcol/r/charsets.result
@@ -0,0 +1,31 @@
+set names utf8;
+create table t1 (
+a int,
+b varchar(100) as (if(a,collation('й'),hex('ю')))
+) character set koi8r;
+insert t1 (a) values (0),(1);
+select * from t1;
+a b
+0 C0
+1 koi8r_general_ci
+set names latin1;
+select * from t1;
+a b
+0 C0
+1 koi8r_general_ci
+flush tables;
+select * from t1;
+a b
+0 C0
+1 koi8r_general_ci
+set names koi8r;
+select * from t1;
+a b
+0 C0
+1 koi8r_general_ci
+flush tables;
+select * from t1;
+a b
+0 C0
+1 koi8r_general_ci
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/cross_db.result b/mysql-test/suite/vcol/r/cross_db.result
new file mode 100644
index 00000000..096ad888
--- /dev/null
+++ b/mysql-test/suite/vcol/r/cross_db.result
@@ -0,0 +1,17 @@
+create database mysqltest1;
+create table mysqltest1.t1 (i int, j int as (i) persistent);
+show create table mysqltest1.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL,
+ `j` int(11) GENERATED ALWAYS AS (`i`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+alter table mysqltest1.t1 add index (i);
+show create table mysqltest1.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL,
+ `j` int(11) GENERATED ALWAYS AS (`i`) STORED,
+ KEY `i` (`i`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop database mysqltest1;
diff --git a/mysql-test/suite/vcol/r/delayed.result b/mysql-test/suite/vcol/r/delayed.result
new file mode 100644
index 00000000..ba3ac5c1
--- /dev/null
+++ b/mysql-test/suite/vcol/r/delayed.result
@@ -0,0 +1,7 @@
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (10,1);
+replace delayed t (a,b) values (10,5);
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+drop table t;
diff --git a/mysql-test/suite/vcol/r/index.result b/mysql-test/suite/vcol/r/index.result
new file mode 100644
index 00000000..6ab9aa5e
--- /dev/null
+++ b/mysql-test/suite/vcol/r/index.result
@@ -0,0 +1,101 @@
+#
+# Test table with a key that consists of indirect virtual fields
+#
+CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=myisam;
+insert into t1 (a) values (1),(2),(3);
+update t1 set a=5 where a=3;
+delete from t1 where a=1;
+select * from t1;
+a b c
+2 3 4
+5 6 7
+select * from t1 where c=7;
+a b c
+5 6 7
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1;
+a b c
+2 3 4
+5 6 7
+drop table t1;
+CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=innodb;
+insert into t1 (a) values (1),(2),(3);
+update t1 set a=5 where a=3;
+delete from t1 where a=1;
+select * from t1;
+a b c
+2 3 4
+5 6 7
+select * from t1 where c=7;
+a b c
+5 6 7
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1;
+a b c
+2 3 4
+5 6 7
+drop table t1;
+#
+# MDEV-15114
+# ASAN heap-use-after-free in mem_heap_dup or
+# dfield_data_is_binary_equal
+#
+CREATE TABLE t1 (
+pk INT,
+extra tinyint,
+c TEXT,
+vc LONGTEXT AS (c) VIRTUAL,
+i INT,
+PRIMARY KEY(pk),
+UNIQUE(i),
+INDEX(vc(64))
+) ENGINE=InnoDB;
+INSERT INTO t1 (pk,extra, c, i) VALUES (1, 10, REPEAT('foo ',15000),0);
+REPLACE INTO t1 (pk,extra, c,i) SELECT pk,extra+10, c,i FROM t1;
+select pk, extra, left(c, 10), length(c), left(vc,10), length(vc), extra from t1;
+pk extra left(c, 10) length(c) left(vc,10) length(vc) extra
+1 20 foo foo fo 60000 foo foo fo 60000 20
+DROP TABLE t1;
+#
+# Update of deleted row with binary logging enabled
+#
+SET BINLOG_FORMAT=row;
+CREATE TABLE t1 (
+pk INT,
+c TEXT,
+vc LONGTEXT AS (c) VIRTUAL,
+i INT,
+PRIMARY KEY(pk),
+UNIQUE(i),
+INDEX(vc(64))
+) ENGINE=InnoDB;
+INSERT INTO t1 (pk,c,i) VALUES (1,REPEAT('foo ',15000),10);
+INSERT INTO t1 (pk,c,i) VALUES (2,REPEAT('bar ',15000),11);
+connect c1,localhost,root,,;
+connection c1;
+begin;
+DELETE from t1 WHERE pk=1;
+connection default;
+update t1 set pk=1 where pk=2;
+connection c1;
+commit;
+connection default;
+select pk, left(c, 10), length(c), i from t1;
+pk left(c, 10) length(c) i
+1 bar bar ba 60000 11
+drop table t1;
+disconnect c1;
+CREATE TABLE t1 (b BLOB, vb TEXT AS (b) PERSISTENT, KEY(vb(64))) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES ('foo');
+connect con1,localhost,root,,test;
+CREATE TABLE t2 LIKE t1;
+connection default;
+DELETE FROM t1;
+connection con1;
+disconnect con1;
+connection default;
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/vcol/r/innodb_autoinc_vcol.result b/mysql-test/suite/vcol/r/innodb_autoinc_vcol.result
new file mode 100644
index 00000000..5349b7a0
--- /dev/null
+++ b/mysql-test/suite/vcol/r/innodb_autoinc_vcol.result
@@ -0,0 +1,16 @@
+create table t1 (c2 int as (1+1), c1 int primary key auto_increment) engine=innodb;
+insert into t1(c1) values (null),(null),(null);
+select * from t1;
+c2 c1
+2 1
+2 2
+2 3
+alter table t1 auto_increment = 3;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c2` int(11) GENERATED ALWAYS AS (1 + 1) VIRTUAL,
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/innodb_virtual_fk.result b/mysql-test/suite/vcol/r/innodb_virtual_fk.result
new file mode 100644
index 00000000..419603c1
--- /dev/null
+++ b/mysql-test/suite/vcol/r/innodb_virtual_fk.result
@@ -0,0 +1,101 @@
+set default_storage_engine=innodb;
+create table t1 (id int primary key, id2 int as (id) virtual, key id2 (id2));
+create table t2 (id int key, constraint fk_id foreign key (id) references t1 (id) on delete cascade);
+insert into t1 (id) values (1), (2);
+insert into t2 (id) values (1), (2);
+delete from t1;
+select * from t1;
+id id2
+select * from t2;
+id
+drop table t2;
+drop table t1;
+#
+# End of 10.2 tests
+#
+#
+# MDEV-18114 Foreign Key Constraint actions don't affect Virtual Column
+#
+create table t1 (id int primary key);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update cascade);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete set null);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update set null);
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update cascade);
+ERROR HY000: Function or expression 'id' cannot be used in the GENERATED ALWAYS AS clause of `id2`
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete set null);
+ERROR HY000: Function or expression 'id' cannot be used in the GENERATED ALWAYS AS clause of `id2`
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update set null);
+ERROR HY000: Function or expression 'id' cannot be used in the GENERATED ALWAYS AS clause of `id2`
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update cascade);
+ERROR HY000: Function or expression 'id2' cannot be used in the GENERATED ALWAYS AS clause of `id3`
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete set null);
+ERROR HY000: Function or expression 'id2' cannot be used in the GENERATED ALWAYS AS clause of `id3`
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update set null);
+ERROR HY000: Function or expression 'id2' cannot be used in the GENERATED ALWAYS AS clause of `id3`
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update cascade);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete set null);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update set null);
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update cascade);
+ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `id2`
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete set null);
+ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `id2`
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update set null);
+ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `id2`
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update cascade);
+ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `CONSTRAINT_1`
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete set null);
+ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `CONSTRAINT_1`
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update set null);
+ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `CONSTRAINT_1`
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update cascade);
+ERROR HY000: Function or expression 'id2' cannot be used in the CHECK clause of `CONSTRAINT_1`
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete set null);
+ERROR HY000: Function or expression 'id2' cannot be used in the CHECK clause of `CONSTRAINT_1`
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update set null);
+ERROR HY000: Function or expression 'id2' cannot be used in the CHECK clause of `CONSTRAINT_1`
+drop table if exists t2, t1;
+Warnings:
+Note 1051 Unknown table 'test.t2'
+#
+# MDEV-31853 Assertion failure in Column_definition::check_vcol_for_key upon adding FK
+#
+create table t (a int, b int, c int generated always as (a), key(b), key(c));
+alter table t add foreign key (a) references t (b) on update set null, algorithm=nocopy;
+ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Adding foreign keys needs foreign_key_checks=OFF. Try ALGORITHM=COPY
+alter table t add foreign key (a) references t (b);
+show create table t;
+Table Create Table
+t CREATE TABLE `t` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `b` (`b`),
+ KEY `c` (`c`),
+ KEY `a` (`a`),
+ CONSTRAINT `t_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t` (`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t;
+#
+# End of 10.5 tests
+#
diff --git a/mysql-test/suite/vcol/r/load_data.result b/mysql-test/suite/vcol/r/load_data.result
new file mode 100644
index 00000000..2432cdd0
--- /dev/null
+++ b/mysql-test/suite/vcol/r/load_data.result
@@ -0,0 +1,20 @@
+create table t1 ( c1 varchar(10), c2 varchar(10), c3 int );
+insert into t1 values ("a" , "b", 1), ("a" , "b", 2);
+create table t2 like t1 ;
+alter table t2 add column c4 bigint unsigned as (CONV(LEFT(MD5(concat(c1,c2,c3)), 16), 16, 10)) persistent unique key;
+select * into outfile 't1.csv' from t1;
+load data infile 't1.csv' ignore into table t2 ;
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 2 doesn't contain data for all columns
+select * from t2;
+c1 c2 c3 c4
+a b 1 7545402351885872315
+a b 2 6048842355806993119
+insert into t2 (c1,c2,c3) values ("a" , "b", 4);
+select * from t2;
+c1 c2 c3 c4
+a b 1 7545402351885872315
+a b 2 6048842355806993119
+a b 4 15541743660496249717
+drop table t1, t2;
diff --git a/mysql-test/suite/vcol/r/mrr.result b/mysql-test/suite/vcol/r/mrr.result
new file mode 100644
index 00000000..39337f32
--- /dev/null
+++ b/mysql-test/suite/vcol/r/mrr.result
@@ -0,0 +1,25 @@
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+col_int_nokey INT NULL,
+col_int_key INT AS (col_int_nokey) VIRTUAL,
+KEY (col_int_key)
+);
+INSERT INTO t1 (col_int_nokey)
+VALUES (0), (5), (4), (3), (7), (42), (5), (0), (3);
+SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1;
+pk col_int_nokey col_int_key
+3 4 4
+4 3 3
+9 3 3
+set optimizer_switch='index_condition_pushdown=off';
+SELECT * FROM t1 WHERE col_int_key IN (3, 4) ORDER BY 1;
+pk col_int_nokey col_int_key
+3 4 4
+4 3 3
+9 3 3
+SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1;
+pk col_int_nokey col_int_key
+3 4 4
+4 3 3
+9 3 3
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/r/myisam_repair_prefix_varchar.result b/mysql-test/suite/vcol/r/myisam_repair_prefix_varchar.result
new file mode 100644
index 00000000..ec331c37
--- /dev/null
+++ b/mysql-test/suite/vcol/r/myisam_repair_prefix_varchar.result
@@ -0,0 +1,134 @@
+create table t4 (
+pk bigint auto_increment,
+col_int smallint(48) not null default 0,
+col_datetime datetime(6) null,
+col_enum set('','a','b','c','d','e','f','foo','bar') null,
+col_dec decimal(65,38) unsigned zerofill null,
+col_bit bit(26) null,
+col_year year null,
+col_datetime2 datetime(6) null,
+col_date date null,
+col_char binary(242) not null default '',
+col_time time(1) null,
+col_blob tinytext null,
+col_varchar varchar(1855) not null default '',
+vcol_varchar varchar(2116) as (col_varchar) virtual,
+vvcol_varchar varchar(2116) as (vcol_varchar) virtual,
+primary key(pk)
+) engine=myisam;
+insert into t4 (col_int,col_datetime,col_enum,col_dec,col_bit,col_year,col_datetime2,col_date,col_char,col_time,col_blob,col_varchar) values
+(9,NULL,'',0.2,b'10100001',2026,NULL,'1988-08-27','bar','14:20:46.009603','bar','bar'),
+(6,'2013-06-27 15:21:27.016500','',0.1,b'01000100',1983,'2014-03-26 03:00:53.052916','2000-09-04','','22:30:46.061648','bar','bar'),
+(156,'2017-04-04 00:00:00','',0.8,NULL,1992,'1991-10-18 17:41:54.030689',NULL,'f','16:58:37.037585','z','a'),
+(7,'1979-05-14 19:13:18.060777',NULL,0.4,b'0',1994,'1900-01-01 00:00:00','2030-01-06','bar','03:24:01.010412','bar','bar'),
+(5,'1975-08-06 00:00:02.061160','',0.7,b'01',1996,'1982-06-10 13:09:15.005717','2008-04-23','bar',NULL,'bar','bar'),
+(14,'2029-05-19 07:56:57.028948','',0.0,NULL,1973,'1900-01-01 00:00:00','2006-03-01','p','20:58:23.064148','v','a'),
+(23,NULL,'',NULL,b'011111111000',2014,'2004-06-19 17:20:37.029214','1974-06-26','bar','14:55:15.000814','m','bar'),
+(6,NULL,'',0.6,b'1100100011011101001111',1986,'2014-07-01 03:01:16.043826','2020-01-15','z','04:57:32.018208','bar','g'),
+(2,'1987-03-12 05:18:40.006865','',0.6,b'001001001011000011001',2012,NULL,'2020-04-21','','20:45:31.021923','k','t'),
+(1,'1993-05-23 10:37:22.054985','',0.4,b'01001',NULL,'1997-08-16 02:35:53.002484','2001-12-09','bar','07:36:35.044493','','s'),
+(9,'2020-11-17 01:09:54.053312','',0.7,b'0',2022,'1900-01-01 00:00:00','2026-05-12','bar','21:41:10.040515','bar','bar'),
+(1,'2025-04-21 16:08:16.033559','',0.4,b'0000',1991,'2013-03-14 09:03:02.016013',NULL,'bar','23:22:08.056231','c','bar'),
+(4,NULL,'',0.5,b'101000000',2023,'1900-01-01 00:00:00','1991-05-26','bar','08:23:51.037917','bar',''),
+(5,'2035-09-13 00:00:00','',0.4,b'1110100001001111',2027,'2001-01-13 19:20:36.044577','2019-04-03','foo','08:18:11.001097','','bar'),
+(6,'1975-08-15 21:42:22.049174','',0.3,b'010010010101',2032,NULL,'2023-01-21','bar','22:08:23.001364','bar','bar'),
+(4,'2013-05-01 00:00:00','',0.3,b'011101010000110000',2021,'2030-07-16 00:00:00','2027-12-07','e','10:09:49.061627','bar','bar'),
+(2,'2035-06-20 22:55:45.008894','',0.8,b'11000',2034,'1983-12-20 07:27:43.035034','1986-09-12','bar','19:02:29.013068','bar','foo'),
+(0,NULL,'',0.1,b'01111010100011',2029,'1978-01-08 00:00:00','1974-12-16','','03:44:02.034839','bar','foo'),
+(1,'1983-11-04 19:04:57.035319','',0.8,b'100001110100110001010',2001,NULL,'1981-05-05','f','00:00:00','bar','bar'),
+(5,NULL,'',0.7,b'0011110001101',NULL,NULL,'1999-07-28','bar','20:33:42.039257','x','r'),
+(3,NULL,'',0.9,b'00110110111',2019,'2008-12-27 00:00:00','2012-03-14','bar','19:12:32.062124','bar','bar'),
+(8,NULL,'',0.9,b'001011001111',1977,'1995-02-20 00:00:00','1985-02-04','bar','23:08:10.014396','bar','bar'),
+(0,NULL,NULL,0.9,b'01',2001,'2011-03-16 22:54:22.026461',NULL,'foo','07:07:55.017714','z','m'),
+(8,'2027-08-03 00:00:00','',0.2,b'110001',2035,'2011-06-24 15:58:37.049649','2028-11-21','qux','16:37:54.001939','d','f'),
+(2,'1900-01-01 00:00:00','',0.1,b'10',2015,'1973-11-22 15:34:01.047131','2010-08-18','foo','17:43:20.056086','bar','b'),
+(7,NULL,'',0.7,b'00100100',1974,'1983-04-16 15:00:17.003592',NULL,'qux','00:00:00','bar','foo'),
+(7,'1980-05-10 20:47:46.049712','',0.0,NULL,2010,'1900-01-01 00:00:00','1974-06-01','foo','08:34:02.056752','bar','qux'),
+(0,'2029-01-10 19:49:58.002777',NULL,0.4,b'1100',2026,'2007-11-24 04:06:32.038008','1980-02-20','foo','06:01:30.019582','qux','bar'),
+(8,'2010-01-04 12:54:59.003789','',0.8,b'01001110111010111',1971,'2010-01-17 06:56:30.006700','2007-09-21','u','13:31:53.061759','bar','foo'),
+(1,'1976-11-17 00:00:00','',0.0,b'00010001011101',2034,'1976-11-08 21:18:21.053929','2029-04-19','','00:38:43.046200','qux','bar'),
+(4,'1991-06-12 16:01:19.007026','',0.4,b'110111010100101111011001',1997,'2004-03-07 18:06:41.050645',NULL,'','17:23:17.056960','o',''),
+(4,'2021-12-14 20:59:31.062969',NULL,0.8,b'01100001010111011101000101',NULL,'2034-04-17 02:55:45.046064',NULL,'bar','10:28:15.003445','n','foo'),
+(85,'1998-09-24 21:01:37.043422','',0.3,b'1001001001111010',1997,'2033-03-23 12:54:48.043906','2030-10-10','r','08:12:29.026018','d','foo'),
+(5,'2031-11-20 00:00:00','',0.1,b'11010011111',2011,'1989-07-07 16:45:29.060242',NULL,'qux','05:12:14.002326','foo','bar'),
+(9,'1900-01-01 00:00:00','',0.3,b'0100010',2035,'1900-01-01 00:00:00','1982-12-04','bar',NULL,NULL,'qux'),
+(8,'2024-11-03 23:31:40.058574','',0.2,b'11001101110101100100001011',2027,'1977-12-18 00:00:00','1972-01-13','tqvbj','16:27:36.004472','qux','f'),
+(1,'1976-01-06 23:32:58.038263','',0.6,NULL,2020,'2029-03-08 18:36:33.010902','1900-01-01','qux','19:36:37.015269','e','bar'),
+(9,'1900-01-01 00:00:00','',0.1,b'010010111101111110000',1993,'2000-10-27 16:52:51.015854','1974-12-22','qux','05:46:08.055789','i','bar'),
+(6,'1900-01-01 00:00:00','',0.0,b'00',2010,'2009-06-09 18:30:10.054617',NULL,'qux','01:36:44.033940','bar',''),
+(6,'2006-04-13 05:21:03.061942','',0.0,b'0000101101100011010000111',1971,'2032-04-05 16:01:44.056007',NULL,'r','01:08:36.007948',NULL,'bar'),
+(8,'2001-03-27 10:39:48.064273','',0.2,b'1000111100100100110',2021,'2016-11-21 07:09:28.035220','2020-01-08','qux','21:33:51.036722','','bar'),
+(6,'2009-11-26 00:00:00','',0.0,b'0000110010001010110111',2009,'2034-02-16 11:01:29.027539','2009-04-12','q','12:01:56.032072','bar','qux'),
+(2,'1990-03-12 07:26:22.053357','',0.7,b'0110',2002,'1975-12-13 03:14:35.064214','2015-05-04','foo','18:17:43.065361','qux','bar'),
+(3,'1900-01-01 00:00:00','',0.8,b'0',1990,'2004-03-24 17:19:30.055335','2005-01-21','bar','07:08:14.014929','b','b'),
+(7,'2012-12-18 00:00:00','',0.5,NULL,1981,'1981-02-17 15:47:55.041049','1989-09-26','bar','09:00:19.031063','t','foo'),
+(3,'1981-12-09 10:10:34.008107','',0.8,NULL,1976,NULL,'1980-01-20','foo','00:00:00','qux','bar'),
+(2,'2006-06-05 03:56:10.030366','',0.5,b'001000101000100000100',1996,'1998-08-17 00:00:00','1994-02-11','bar','20:55:21.044208',NULL,'foo'),
+(4,'1900-01-01 00:00:00',NULL,0.4,b'00111000011000001010000',1980,NULL,NULL,'e','09:37:44.034108','','k'),
+(2,'2018-03-01 21:14:08.062101','',0.2,b'00001101011101000',1985,'2022-06-09 17:17:31.039498','1900-01-01','bar','00:00:00','j','qux'),
+(1,'2018-05-06 20:12:14.043515',NULL,NULL,b'1100100000100001101011',NULL,'2020-12-20 11:46:57.017685','1973-04-20','qux','00:00:00','','bar'),
+(8,'1985-07-12 02:16:53.034909',NULL,0.3,b'10111000100110110101',1997,'1985-11-07 23:07:06.015091','2007-01-08','z','04:14:58.038324','bar','x'),
+(5,'2027-09-21 16:28:36.016865','',0.9,NULL,1986,'2013-11-16 07:22:14.009509','1900-01-01','qux','16:19:03.023217','bar','d'),
+(1,'1900-01-01 00:00:00','',0.5,b'010101',2007,'1987-03-23 01:34:02.040253','2004-01-24','bar','00:00:00','qux','t'),
+(0,NULL,'',0.3,b'10111010001110111011',2030,NULL,'2007-11-17','qux','14:16:15.008674','bar','foo'),
+(5,'1900-01-01 00:00:00','',0.3,b'1',2004,'1978-03-06 00:00:00','2003-07-08','','09:33:46.000325','','bar'),
+(207,'2019-10-05 19:24:40.063253','',NULL,b'1010111000110110110000',1977,'1992-01-07 15:50:41.043085','2003-10-24','d','12:50:19.026611','qux','bar'),
+(1,'2012-07-01 23:30:29.042644','',0.8,b'01111010111001001101',1974,'1976-03-16 00:00:00','2006-01-09','qux','22:22:44.040748','','bar'),
+(2,'1995-06-21 00:00:00','',0.9,b'000101001100100',2022,'2006-09-23 00:00:00',NULL,'bar','06:13:27.061694','v','qux'),
+(1,'1900-01-01 00:00:00',NULL,0.8,b'000000001000',2027,'2028-03-20 08:34:05.027629','1999-09-28','bar','01:39:33.047138','foo','qux'),
+(5,'1996-06-01 05:23:35.020694','',0.9,b'1111001111001110001011001',1996,'1973-12-13 05:51:14.039856','1993-04-13','','20:24:00.040657','foo','bar'),
+(8,'2000-02-18 12:32:03.020086','',0.3,b'0000111010',2010,'1972-09-12 01:43:50.058850',NULL,'qux','23:12:01.017030','bar','x'),
+(8,'1992-05-27 02:39:01.058236','',0.7,b'011101110',2032,NULL,'1998-04-03','h','12:22:12.041362','p','bar'),
+(7,'1900-01-01 00:00:00','',0.3,b'10111111110011010111',1989,'1998-06-08 00:00:00','1993-02-10','qux','12:44:43.060254','h','bar'),
+(164,'2034-08-09 10:48:51.053786',NULL,0.0,b'00100111',1973,'2026-01-13 19:29:43.039915','2022-03-01','bar','11:51:54.036462','','qux'),
+(0,'2030-02-22 18:02:11.043075','',0.8,b'011000111111011111111100',2001,'2030-02-09 15:46:56.055798','2026-03-20','bar','10:31:58.002654','q','qux'),
+(7,'2009-11-19 06:26:11.008028','',0.8,NULL,2004,'2009-07-05 00:00:00','2014-04-22','t','05:45:36.023615',NULL,'u'),
+(1,'1987-04-17 04:16:29.007028','',0.5,b'00',1976,'1900-01-01 00:00:00','2023-12-07','foo','22:25:07.010419','qux','bar'),
+(6,NULL,'',0.6,b'0',2003,'2025-04-15 11:19:34.034736','2010-06-20','qux','00:00:00','bar','foo'),
+(2,'2025-03-26 07:09:22.012297','',0.5,b'00110000001110111110',2033,'1974-03-16 18:35:58.062140','1982-04-07','qux','18:50:57.025695',NULL,'z'),
+(4,'2032-12-08 13:05:51.020675','',0.4,b'11001001100011',NULL,'1983-08-26 11:47:49.027635','2019-07-08','qux','00:00:00','','x'),
+(0,'1972-12-10 00:00:00','',NULL,b'00000100010110100000',1978,'1990-12-28 15:20:43.027572','2008-02-23','r','17:48:05.030363','foo','bar'),
+(6,'1900-01-01 00:00:00',NULL,0.9,b'111000001101010',2026,'1997-08-09 00:00:00','1900-01-01','c','00:00:00','','qux'),
+(6,NULL,'',0.5,b'011110001001',2010,'1900-01-01 00:00:00','2018-01-11','foo','00:00:00','qux','bar'),
+(9,'2000-11-10 06:31:29.024423','',0.7,NULL,2004,'1900-01-01 00:00:00','1972-04-10','qux','22:50:18.046302','foo','bar'),
+(0,'2008-02-11 00:00:00','',0.3,b'111010011',NULL,'1976-10-02 06:40:56.017017','1900-01-01','q','12:50:11.001180',NULL,'foo'),
+(6,'2032-01-13 00:00:00',NULL,0.7,b'0101110010010110011001000',2006,NULL,'2015-06-08','bar','00:27:52.030995','qux','foo'),
+(5,NULL,'',0.2,b'101100101000',1993,'2008-03-26 00:00:00','2023-03-25','bar','17:51:32.035040','foo','qux'),
+(0,NULL,NULL,NULL,b'01110000111011010101',2020,'1988-02-20 19:30:16.015815','2027-02-07','bar','11:18:36.020832','qux','foo'),
+(8,'1990-02-04 11:52:45.035803','',0.2,b'1',2034,'2014-06-28 16:58:27.046952','2020-12-05','bar','08:36:43.060728','','qux'),
+(1,NULL,'',0.7,b'110010010111110100110001',2002,'2019-06-19 03:39:03.040619','2001-08-28','bar','01:59:24.036052','foo','qux'),
+(6,'2003-09-12 14:34:37.035049','',0.3,b'110010',2029,NULL,'2025-11-09','bar','18:51:11.041328','d',''),
+(9,NULL,'',NULL,b'00010',2005,'2027-07-12 23:36:51.053942','2000-06-04','qux','13:46:39.062130','bar',''),
+(5,'2035-12-19 04:59:44.044122','',0.8,b'110011011010010101101100',2000,'1980-06-16 02:14:18.040078','1900-01-01','j',NULL,'qux','c'),
+(4,'1978-06-11 18:53:14.037991','',0.4,b'00000',NULL,'2018-03-13 18:56:39.056433','2020-12-07','foo','17:58:15.029684','bar','y'),
+(2,NULL,'',0.2,b'100101110010101',1976,'2017-06-12 18:40:22.011803','2021-11-01','qux','15:16:59.059052','foo','bar'),
+(5,'2017-08-07 01:53:34.056737','',0.1,b'1110101100',1979,'1900-01-01 00:00:00','1900-01-01','foo','03:13:31.046205','bar',REPEAT('a',1693)),
+(7,'2022-09-25 03:36:08.040842','',0.7,b'11010111110001010',2026,NULL,'2018-04-15','bar','16:08:47.004044','','qux'),
+(5,'1988-04-05 07:40:37.041464','',0.6,b'101110100110110',NULL,'2011-08-08 02:23:59.013723','2020-01-28','qux','00:00:00','foo','y'),
+(6,NULL,NULL,0.7,b'1100001',1995,NULL,'2026-02-01','',NULL,'o','qux'),
+(9,'1985-05-13 00:00:00','',0.5,b'1110101011010100101110',1973,'1975-04-08 00:00:00','2006-09-22','qux','13:43:19.008905','foo','bar'),
+(7,'2032-07-23 00:00:00','',0.6,b'10100100011110110100',1985,'1997-02-22 02:04:16.040238','1971-05-24','y','10:27:41.006741','i','qux'),
+(1,'1900-01-01 00:00:00','',0.5,NULL,2013,'2002-09-28 00:00:00','2025-03-17','o','13:27:32.040813','','y'),
+(8,'2014-08-03 10:02:33.055574','',0.0,b'1',1992,NULL,'1978-12-27','x','10:58:03.022898','foo',''),
+(9,'2011-05-25 00:00:00','',0.8,b'11001001000011100',2019,NULL,'2003-10-06','qux','00:00:00',NULL,'bar'),
+(8,'1900-01-01 00:00:00','',0.0,b'101101000010100011011111',2000,'2005-05-18 00:00:00','1995-07-13','bar','13:19:40.057958','foo',''),
+(4,NULL,'',0.8,b'011011',1972,NULL,'2008-04-16','b','00:00:00','bar','foo'),
+(8,'2005-07-21 07:54:38.040060','',0.5,b'100',2003,'1900-01-01 00:00:00','1994-09-03','qux','02:36:25.048212','','b'),
+(7,'2002-07-03 01:08:02.012450','',0.5,b'101100010001101101',1990,'1974-04-15 02:53:22.018939','2002-02-12','','10:40:14.031253','w','c'),
+(174,'2029-09-28 01:08:52.004131','',NULL,b'001001000011',1976,'2034-12-11 02:11:04.035857','2005-07-18','qux','00:00:00','xd','bar'),
+(255,'2004-02-02 06:53:55.023459',NULL,NULL,b'111010100',1982,'1983-12-17 00:00:00','2003-12-20','bar','01:23:47.001055','t','qux');
+alter table t4 add index(vcol_varchar(64));
+repair table t4;
+Table Op Msg_type Msg_text
+test.t4 repair status OK
+repair table t4 extended;
+Table Op Msg_type Msg_text
+test.t4 repair status OK
+alter table t4 add index(vvcol_varchar(32));
+repair table t4;
+Table Op Msg_type Msg_text
+test.t4 repair status OK
+repair table t4 extended;
+Table Op Msg_type Msg_text
+test.t4 repair status OK
+drop table t4;
diff --git a/mysql-test/suite/vcol/r/not_supported.result b/mysql-test/suite/vcol/r/not_supported.result
new file mode 100644
index 00000000..37ce4865
--- /dev/null
+++ b/mysql-test/suite/vcol/r/not_supported.result
@@ -0,0 +1,57 @@
+connect con1, localhost, root;
+set lc_time_names = 'es_MX';
+set time_zone='+10:00';
+set div_precision_increment=20;
+create table t1 (a int, b int, v decimal(20,19) as (a/3));
+create table t2 (a int, b int, v int as (a+@a));
+drop table t2;
+create table t2 (a int, b int, v int as (a+@a) PERSISTENT);
+ERROR HY000: Function or expression '@a' cannot be used in the GENERATED ALWAYS AS clause of `v`
+create table t3_ok (a int, b int, v int as (a+@@error_count));
+create table t3 (a int, b int, v int as (a+@@error_count) PERSISTENT);
+ERROR HY000: Function or expression '@@error_count' cannot be used in the GENERATED ALWAYS AS clause of `v`
+create table t4 (a int, b int, v int as (@a:=a));
+drop table t4;
+create table t4 (a int, b int, v int as (@a:=a) PERSISTENT);
+ERROR HY000: Function or expression '@a' cannot be used in the GENERATED ALWAYS AS clause of `v`
+create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
+insert t1 (a,b) values (1,2);
+insert t8 (a,b) values (1234567890,2);
+select * from t1;
+a b v
+1 2 0.3333333333333333333
+select * from t8;
+a b v
+1234567890 2 2009-02-14 09:31:30
+disconnect con1;
+connection default;
+set time_zone='+1:00';
+flush tables;
+select * from t1;
+a b v
+1 2 0.3333333330000000000
+select * from t8;
+a b v
+1234567890 2 2009-02-14 00:31:30
+drop table t1, t3_ok, t8;
+#
+# Bug#33141966 - INCONSISTENT BEHAVIOR IF A COLUMN OF TYPE SERIAL IS SET AS GENERATED
+#
+create table t1 (a int, b serial as (a+1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'as (a+1))' at line 1
+#
+# End of 10.2 tests
+#
+create table t1 (a int, b real as (rand()), c real as (b) stored);
+ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
+create table t1 (a int, b real as (rand()), c real as (b) unique);
+ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
+create table t1 (a int auto_increment primary key,
+b int as (a+1), c int as (b+1) stored);
+ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
+create table t1 (a int auto_increment primary key,
+b int as (a+1), c int as (b+1) unique);
+ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c`
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/suite/vcol/r/partition.result b/mysql-test/suite/vcol/r/partition.result
new file mode 100644
index 00000000..d7c5052b
--- /dev/null
+++ b/mysql-test/suite/vcol/r/partition.result
@@ -0,0 +1,103 @@
+CREATE TABLE t1 (
+id INT NOT NULL,
+store_id INT NOT NULL,
+x INT GENERATED ALWAYS AS (id + store_id)
+)
+PARTITION BY RANGE (store_id) (
+PARTITION p0 VALUES LESS THAN (6),
+PARTITION p1 VALUES LESS THAN (11),
+PARTITION p2 VALUES LESS THAN (16),
+PARTITION p3 VALUES LESS THAN (21)
+);
+INSERT t1 (id, store_id) VALUES(1, 2), (3, 4), (3, 12), (4, 18);
+CREATE INDEX idx ON t1(x);
+SELECT x FROM t1;
+x
+3
+7
+15
+22
+DROP TABLE t1;
+create table t1 (i int, v int as (i) virtual)
+partition by range columns (i)
+subpartition by hash(v) subpartitions 3 (
+partition p1 values less than (3),
+partition pn values less than (maxvalue));
+insert t1 set i= 0;
+set statement sql_mode= '' for update t1 set i= 1, v= 2;
+Warnings:
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+drop table t1;
+#
+# MDEV-18734 ASAN heap-use-after-free in my_strnxfrm_simple_internal upon update on versioned partitioned table
+#
+# Cover queue_fix() in ha_partition::handle_ordered_index_scan()
+create or replace table t1 (
+x int auto_increment primary key,
+b text, v mediumtext as (b) virtual,
+index (v(10))
+) partition by range columns (x) (
+partition p1 values less than (3),
+partition p2 values less than (6),
+partition p3 values less than (9),
+partition p4 values less than (12),
+partition p5 values less than (15),
+partition p6 values less than (17),
+partition p7 values less than (19),
+partition p8 values less than (21),
+partition p9 values less than (23),
+partition p10 values less than (25),
+partition p11 values less than (27),
+partition p12 values less than (29),
+partition p13 values less than (31),
+partition p14 values less than (33),
+partition p15 values less than (35),
+partition pn values less than (maxvalue));
+insert into t1 (b) values
+(repeat('q', 8192)), (repeat('z', 8192)), (repeat('a', 8192)), (repeat('b', 8192)),
+(repeat('x', 8192)), (repeat('y', 8192));
+insert t1 (b) select b from t1;
+insert t1 (b) select b from t1;
+insert t1 (b) select b from t1;
+insert t1 (b) select b from t1;
+select x, left(b, 10), left(v, 10) from t1 where x > 30 and x < 60 order by v;
+x left(b, 10) left(v, 10)
+33 aaaaaaaaaa aaaaaaaaaa
+39 aaaaaaaaaa aaaaaaaaaa
+45 aaaaaaaaaa aaaaaaaaaa
+51 aaaaaaaaaa aaaaaaaaaa
+57 aaaaaaaaaa aaaaaaaaaa
+34 bbbbbbbbbb bbbbbbbbbb
+40 bbbbbbbbbb bbbbbbbbbb
+46 bbbbbbbbbb bbbbbbbbbb
+52 bbbbbbbbbb bbbbbbbbbb
+58 bbbbbbbbbb bbbbbbbbbb
+31 qqqqqqqqqq qqqqqqqqqq
+37 qqqqqqqqqq qqqqqqqqqq
+43 qqqqqqqqqq qqqqqqqqqq
+49 qqqqqqqqqq qqqqqqqqqq
+55 qqqqqqqqqq qqqqqqqqqq
+35 xxxxxxxxxx xxxxxxxxxx
+41 xxxxxxxxxx xxxxxxxxxx
+47 xxxxxxxxxx xxxxxxxxxx
+53 xxxxxxxxxx xxxxxxxxxx
+59 xxxxxxxxxx xxxxxxxxxx
+36 yyyyyyyyyy yyyyyyyyyy
+42 yyyyyyyyyy yyyyyyyyyy
+48 yyyyyyyyyy yyyyyyyyyy
+54 yyyyyyyyyy yyyyyyyyyy
+32 zzzzzzzzzz zzzzzzzzzz
+38 zzzzzzzzzz zzzzzzzzzz
+44 zzzzzzzzzz zzzzzzzzzz
+50 zzzzzzzzzz zzzzzzzzzz
+56 zzzzzzzzzz zzzzzzzzzz
+update t1 set b= 'bar' where v > 'a' limit 20;
+drop table t1;
+# Cover return_top_record() in ha_partition::handle_ordered_index_scan()
+create table t1 (x int primary key, b tinytext, v text as (b) virtual)
+partition by range columns (x) (
+partition p1 values less than (4),
+partition pn values less than (maxvalue));
+insert into t1 (x, b) values (1, ''), (2, ''), (3, 'a'), (4, 'b');
+update t1 set b= 'bar' where x > 0 order by v limit 2;
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/races.result b/mysql-test/suite/vcol/r/races.result
new file mode 100644
index 00000000..c46ed5ba
--- /dev/null
+++ b/mysql-test/suite/vcol/r/races.result
@@ -0,0 +1,16 @@
+create table t1 (f text, vf tinytext as (f), key (vf(64))) engine=innodb;
+insert t1 (f) values ('foo');
+flush tables;
+connect con1,localhost,root,,test;
+set debug_sync='TABLE_after_field_clone WAIT_FOR go';
+delete from t1;
+connection default;
+select * from t1;
+f vf
+foo foo
+set debug_sync='now SIGNAL go';
+connection con1;
+disconnect con1;
+connection default;
+drop table t1;
+set debug_sync='reset';
diff --git a/mysql-test/suite/vcol/r/range.result b/mysql-test/suite/vcol/r/range.result
new file mode 100644
index 00000000..5b081a5d
--- /dev/null
+++ b/mysql-test/suite/vcol/r/range.result
@@ -0,0 +1,9 @@
+create table t1 (pk int, i int, v int as (i*2) virtual, primary key (pk), key (v)) engine=myisam;
+insert into t1 (pk,i) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+create table t2 (a int, b int) engine=myisam;
+insert into t2 values (1,2),(2,4);
+select * from t1 inner join t2 on ( t2.b = t1.v or t2.a = t1.pk );
+pk i v a b
+1 1 2 1 2
+2 2 4 2 4
+drop table t1, t2;
diff --git a/mysql-test/suite/vcol/r/rpl_vcol.result b/mysql-test/suite/vcol/r/rpl_vcol.result
new file mode 100644
index 00000000..8dea4dd1
--- /dev/null
+++ b/mysql-test/suite/vcol/r/rpl_vcol.result
@@ -0,0 +1,26 @@
+SET @@session.default_storage_engine = 'InnoDB';
+include/master-slave.inc
+[connection master]
+connection master;
+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) GENERATED ALWAYS AS (`a` + 1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert into t1 values (2,default);
+select * from t1;
+a b
+1 2
+2 3
+connection slave;
+select * from t1;
+a b
+1 2
+2 3
+connection master;
+drop table t1;
+connection slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/vcol/r/update.result b/mysql-test/suite/vcol/r/update.result
new file mode 100644
index 00000000..0b0dd933
--- /dev/null
+++ b/mysql-test/suite/vcol/r/update.result
@@ -0,0 +1,179 @@
+create table t1 (a int, b int as (a+1), c int as (b+1) stored);
+insert t1 set a=1;
+select * from t1;
+a b c
+1 2 3
+update t1 set a=2;
+select * from t1;
+a b c
+2 3 4
+drop table t1;
+create table t1 (a int, c int as(a), p varchar(20) as(rtrim(y)), y char(20), index (p,c));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `c` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ `p` varchar(20) GENERATED ALWAYS AS (rtrim(`y`)) VIRTUAL,
+ `y` char(20) DEFAULT NULL,
+ KEY `p` (`p`,`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 (a,y) values(1, "yyy");
+update t1 set a = 100 where a = 1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 (
+a varchar(10000),
+b varchar(3000),
+c varchar(14000) generated always as (concat(a,b)) virtual,
+d varchar(5000) generated always as (b) virtual,
+e int(11) generated always as (10) virtual,
+h int(11) not null primary key,
+index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+create table t1 (
+a varchar(10000),
+b varchar(3000),
+c varchar(14000) generated always as (concat(a,b)) virtual,
+i varchar(5000) generated always as (b) virtual,
+d varchar(5000) generated always as (i) virtual,
+e int(11) generated always as (10) virtual,
+h int(11) not null primary key,
+index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+create table t1(a blob not null, b int, c varbinary (10) generated always as (a) virtual, unique (c(9)));
+insert t1 (a,b) values ('a', 1);
+replace t1 set a = 'a',b =1;
+insert t1 (a,b) values ('a', 1) on duplicate key update a='b', b=2;
+select * from t1;
+a b c
+b 2 b
+drop table t1;
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (9,0);
+create table t2 select * from t;
+update t, t2 set t.b=10 where t.a=t2.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c
+9 10 10
+drop table t, t2;
+create table t1 (a int, b int, c int, d int, e int);
+insert t1 values (1,2,3,4,5), (1,2,3,4,5);
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+create table t (a int primary key,
+b int, c blob as (b), index (c(57)),
+d blob, e blob as (d), index (e(57)))
+replace select * from t1;
+Warnings:
+Warning 1906 The value specified for generated column 'c' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'c' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+1 2 2 4 4
+update t set a=10, b=1, d=1;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 1 1 1 1
+replace t (a,b,d) values (10,2,2);
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 2 2 2 2
+insert t(a,b,d) values (10) on duplicate key update b=3;
+ERROR 21S01: Column count doesn't match value count at row 1
+insert t(a,b,d) values (10,2,2) on duplicate key update b=3, d=3;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 3 3 3 3
+replace t (a,b,d) select 10,4,4;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 4 4 4 4
+insert t(a,b,d) select 10,4,4 on duplicate key update b=5, d=5;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 5 5 5 5
+replace delayed t (a,b,d) values (10,6,6);
+flush tables t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 6 6 6 6
+insert delayed t(a,b,d) values (10,6,6) on duplicate key update b=7, d=7;
+flush tables t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 7 7 7 7
+load data infile 'MYSQLTEST_VARDIR/tmp/vblobs.txt' replace into table t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 8 8 8 8
+update t set a=11, b=9, d=9 where a>5;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 9 9 9 9
+create table t2 select * from t;
+update t, t2 set t.b=10, t.d=10 where t.a=t2.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 10 10 10 10
+update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 11 11 11 11
+drop table t, t1, t2;
+create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
+insert into t (f1,f2) values (1,1),(2,2);
+create view v as
+select a2.f1, a2.f2, a1.f3
+from t a1, t a2
+where a2.f3 <> 0
+with local check option;
+update v set f3 = 52;
+drop view v;
+drop table t;
diff --git a/mysql-test/suite/vcol/r/update_binlog.result b/mysql-test/suite/vcol/r/update_binlog.result
new file mode 100644
index 00000000..14aa50b7
--- /dev/null
+++ b/mysql-test/suite/vcol/r/update_binlog.result
@@ -0,0 +1,361 @@
+set binlog_row_image="FULL";
+set @@default_storage_engine="myisam";
+create table t1 (a int, b int as (a+1), c int as (b+1) stored);
+insert t1 set a=1;
+select * from t1;
+a b c
+1 2 3
+update t1 set a=2;
+select * from t1;
+a b c
+2 3 4
+drop table t1;
+create table t1 (a int, c int as(a), p varchar(20) as(rtrim(y)), y char(20), index (p,c));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `c` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ `p` varchar(20) GENERATED ALWAYS AS (rtrim(`y`)) VIRTUAL,
+ `y` char(20) DEFAULT NULL,
+ KEY `p` (`p`,`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 (a,y) values(1, "yyy");
+update t1 set a = 100 where a = 1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 (
+a varchar(10000),
+b varchar(3000),
+c varchar(14000) generated always as (concat(a,b)) virtual,
+d varchar(5000) generated always as (b) virtual,
+e int(11) generated always as (10) virtual,
+h int(11) not null primary key,
+index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+create table t1 (
+a varchar(10000),
+b varchar(3000),
+c varchar(14000) generated always as (concat(a,b)) virtual,
+i varchar(5000) generated always as (b) virtual,
+d varchar(5000) generated always as (i) virtual,
+e int(11) generated always as (10) virtual,
+h int(11) not null primary key,
+index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+create table t1(a blob not null, b int, c varbinary (10) generated always as (a) virtual, unique (c(9)));
+insert t1 (a,b) values ('a', 1);
+replace t1 set a = 'a',b =1;
+insert t1 (a,b) values ('a', 1) on duplicate key update a='b', b=2;
+select * from t1;
+a b c
+b 2 b
+drop table t1;
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (9,0);
+create table t2 select * from t;
+update t, t2 set t.b=10 where t.a=t2.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c
+9 10 10
+drop table t, t2;
+create table t1 (a int, b int, c int, d int, e int);
+insert t1 values (1,2,3,4,5), (1,2,3,4,5);
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+create table t (a int primary key,
+b int, c blob as (b), index (c(57)),
+d blob, e blob as (d), index (e(57)))
+replace select * from t1;
+Warnings:
+Warning 1906 The value specified for generated column 'c' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'c' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+1 2 2 4 4
+update t set a=10, b=1, d=1;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 1 1 1 1
+replace t (a,b,d) values (10,2,2);
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 2 2 2 2
+insert t(a,b,d) values (10) on duplicate key update b=3;
+ERROR 21S01: Column count doesn't match value count at row 1
+insert t(a,b,d) values (10,2,2) on duplicate key update b=3, d=3;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 3 3 3 3
+replace t (a,b,d) select 10,4,4;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 4 4 4 4
+insert t(a,b,d) select 10,4,4 on duplicate key update b=5, d=5;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 5 5 5 5
+replace delayed t (a,b,d) values (10,6,6);
+flush tables t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 6 6 6 6
+insert delayed t(a,b,d) values (10,6,6) on duplicate key update b=7, d=7;
+flush tables t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 7 7 7 7
+load data infile 'MYSQLTEST_VARDIR/tmp/vblobs.txt' replace into table t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 8 8 8 8
+update t set a=11, b=9, d=9 where a>5;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 9 9 9 9
+create table t2 select * from t;
+update t, t2 set t.b=10, t.d=10 where t.a=t2.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 10 10 10 10
+update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 11 11 11 11
+drop table t, t1, t2;
+create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
+insert into t (f1,f2) values (1,1),(2,2);
+create view v as
+select a2.f1, a2.f2, a1.f3
+from t a1, t a2
+where a2.f3 <> 0
+with local check option;
+update v set f3 = 52;
+drop view v;
+drop table t;
+set binlog_row_image="MINIMAL";
+create table t1 (a int, b int as (a+1), c int as (b+1) stored);
+insert t1 set a=1;
+select * from t1;
+a b c
+1 2 3
+update t1 set a=2;
+select * from t1;
+a b c
+2 3 4
+drop table t1;
+create table t1 (a int, c int as(a), p varchar(20) as(rtrim(y)), y char(20), index (p,c));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `c` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ `p` varchar(20) GENERATED ALWAYS AS (rtrim(`y`)) VIRTUAL,
+ `y` char(20) DEFAULT NULL,
+ KEY `p` (`p`,`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 (a,y) values(1, "yyy");
+update t1 set a = 100 where a = 1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 (
+a varchar(10000),
+b varchar(3000),
+c varchar(14000) generated always as (concat(a,b)) virtual,
+d varchar(5000) generated always as (b) virtual,
+e int(11) generated always as (10) virtual,
+h int(11) not null primary key,
+index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+create table t1 (
+a varchar(10000),
+b varchar(3000),
+c varchar(14000) generated always as (concat(a,b)) virtual,
+i varchar(5000) generated always as (b) virtual,
+d varchar(5000) generated always as (i) virtual,
+e int(11) generated always as (10) virtual,
+h int(11) not null primary key,
+index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+create table t1(a blob not null, b int, c varbinary (10) generated always as (a) virtual, unique (c(9)));
+insert t1 (a,b) values ('a', 1);
+replace t1 set a = 'a',b =1;
+insert t1 (a,b) values ('a', 1) on duplicate key update a='b', b=2;
+select * from t1;
+a b c
+b 2 b
+drop table t1;
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (9,0);
+create table t2 select * from t;
+update t, t2 set t.b=10 where t.a=t2.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c
+9 10 10
+drop table t, t2;
+create table t1 (a int, b int, c int, d int, e int);
+insert t1 values (1,2,3,4,5), (1,2,3,4,5);
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+create table t (a int primary key,
+b int, c blob as (b), index (c(57)),
+d blob, e blob as (d), index (e(57)))
+replace select * from t1;
+Warnings:
+Warning 1906 The value specified for generated column 'c' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'c' in table 't' has been ignored
+Warning 1906 The value specified for generated column 'e' in table 't' has been ignored
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+1 2 2 4 4
+update t set a=10, b=1, d=1;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 1 1 1 1
+replace t (a,b,d) values (10,2,2);
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 2 2 2 2
+insert t(a,b,d) values (10) on duplicate key update b=3;
+ERROR 21S01: Column count doesn't match value count at row 1
+insert t(a,b,d) values (10,2,2) on duplicate key update b=3, d=3;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 3 3 3 3
+replace t (a,b,d) select 10,4,4;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 4 4 4 4
+insert t(a,b,d) select 10,4,4 on duplicate key update b=5, d=5;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 5 5 5 5
+replace delayed t (a,b,d) values (10,6,6);
+flush tables t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 6 6 6 6
+insert delayed t(a,b,d) values (10,6,6) on duplicate key update b=7, d=7;
+flush tables t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 7 7 7 7
+load data infile 'MYSQLTEST_VARDIR/tmp/vblobs.txt' replace into table t;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+10 8 8 8 8
+update t set a=11, b=9, d=9 where a>5;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 9 9 9 9
+create table t2 select * from t;
+update t, t2 set t.b=10, t.d=10 where t.a=t2.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 10 10 10 10
+update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c d e
+11 11 11 11 11
+drop table t, t1, t2;
+create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
+insert into t (f1,f2) values (1,1),(2,2);
+create view v as
+select a2.f1, a2.f2, a1.f3
+from t a1, t a2
+where a2.f3 <> 0
+with local check option;
+update v set f3 = 52;
+drop view v;
+drop table t;
diff --git a/mysql-test/suite/vcol/r/upgrade.result b/mysql-test/suite/vcol/r/upgrade.result
new file mode 100644
index 00000000..5393a354
--- /dev/null
+++ b/mysql-test/suite/vcol/r/upgrade.result
@@ -0,0 +1,34 @@
+check table vcol_autoinc for upgrade;
+Table Op Msg_type Msg_text
+test.vcol_autoinc check Warning Function or expression 'AUTO_INCREMENT' cannot be used in the GENERATED ALWAYS AS clause of `pk`
+test.vcol_autoinc check status OK
+show create table vcol_autoinc;
+Table Create Table
+vcol_autoinc CREATE TABLE `vcol_autoinc` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `v3` int(11) GENERATED ALWAYS AS (`pk`) STORED,
+ PRIMARY KEY (`pk`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select * from vcol_autoinc;
+pk v3
+insert vcol_autoinc (pk) values (1);
+select * from vcol_autoinc;
+pk v3
+1 1
+drop table vcol_autoinc;
+check table t1 for upgrade;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+flush tables;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `Date` datetime(6) NOT NULL,
+ `Data` varbinary(2000) NOT NULL,
+ `a` varchar(100) GENERATED ALWAYS AS (column_get(`Data`,1 as char(100) charset latin1)) VIRTUAL,
+ PRIMARY KEY (`Date`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+ PARTITION BY RANGE (to_days(`Date`))
+(PARTITION `p20181029` VALUES LESS THAN (737361) ENGINE = MyISAM,
+ PARTITION `p20181128` VALUES LESS THAN (737391) ENGINE = MyISAM)
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_archive.result b/mysql-test/suite/vcol/r/vcol_archive.result
new file mode 100644
index 00000000..5c11e8bb
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_archive.result
@@ -0,0 +1,7 @@
+SET @@session.default_storage_engine = 'archive';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: ARCHIVE storage engine does not support generated columns
+create table t1 (a int not null);
+alter table t1 add column b int as (a+1);
+ERROR HY000: ARCHIVE storage engine does not support generated columns
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_blackhole.result b/mysql-test/suite/vcol/r/vcol_blackhole.result
new file mode 100644
index 00000000..0bbe439f
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_blackhole.result
@@ -0,0 +1,7 @@
+SET @@session.default_storage_engine = 'blackhole';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: BLACKHOLE storage engine does not support generated columns
+create table t1 (a int not null);
+alter table t1 add column b int as (a+1);
+ERROR HY000: BLACKHOLE storage engine does not support generated columns
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result
new file mode 100644
index 00000000..425aa1b1
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result
@@ -0,0 +1,251 @@
+SET @@session.default_storage_engine = 'MyISAM';
+# RAND()
+create or replace table t1 (b double as (rand()));
+create or replace table t1 (b double as (rand()) PERSISTENT);
+ERROR HY000: Function or expression 'rand()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# LOAD_FILE()
+create or replace table t1 (a varchar(64), b varchar(1024) as (load_file(a)));
+ERROR HY000: Function or expression 'load_file()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# CURDATE()
+create or replace table t1 (a datetime as (curdate()) PERSISTENT);
+ERROR HY000: Function or expression 'curdate()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# CURRENT_DATE(), CURRENT_DATE
+create or replace table t1 (a datetime as (current_date) PERSISTENT);
+ERROR HY000: Function or expression 'curdate()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+create or replace table t1 (a datetime as (current_date()) PERSISTENT);
+ERROR HY000: Function or expression 'curdate()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# CURRENT_TIME(), CURRENT_TIME
+create or replace table t1 (a datetime as (current_time) PERSISTENT);
+ERROR HY000: Function or expression 'curtime()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+create or replace table t1 (a datetime as (current_time()) PERSISTENT);
+ERROR HY000: Function or expression 'curtime()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP
+create or replace table t1 (a datetime as (current_timestamp()) PERSISTENT);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+create or replace table t1 (a datetime as (current_timestamp) PERSISTENT);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# CURTIME()
+create or replace table t1 (a datetime as (curtime()) PERSISTENT);
+ERROR HY000: Function or expression 'curtime()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# LOCALTIME(), LOCALTIME
+create or replace table t1 (a datetime, b varchar(10) as (localtime()) PERSISTENT);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create or replace table t1 (a datetime, b varchar(10) as (localtime) PERSISTENT);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6)
+create or replace table t1 (a datetime, b varchar(10) as (localtimestamp()) PERSISTENT);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create or replace table t1 (a datetime, b varchar(10) as (localtimestamp) PERSISTENT);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# NOW()
+create or replace table t1 (a datetime, b varchar(10) as (now()) PERSISTENT);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# SYSDATE()
+create or replace table t1 (a int, b varchar(10) as (sysdate()) PERSISTENT);
+ERROR HY000: Function or expression 'sysdate()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# UNIX_TIMESTAMP()
+create or replace table t1 (a datetime, b datetime as (unix_timestamp()) PERSISTENT);
+ERROR HY000: Function or expression 'unix_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# UTC_DATE()
+create or replace table t1 (a datetime, b datetime as (utc_date()) PERSISTENT);
+ERROR HY000: Function or expression 'utc_date()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# UTC_TIME()
+create or replace table t1 (a datetime, b datetime as (utc_time()) PERSISTENT);
+ERROR HY000: Function or expression 'utc_time()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# UTC_TIMESTAMP()
+create or replace table t1 (a datetime, b datetime as (utc_timestamp()) PERSISTENT);
+ERROR HY000: Function or expression 'utc_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# WEEK() - one argument version
+create or replace table t1 (a datetime, b datetime as (week(a)) PERSISTENT);
+ERROR HY000: Function or expression 'week()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# MATCH()
+create or replace table t1 (a varchar(32), b bool as (match a against ('sample text')) PERSISTENT);
+ERROR HY000: Function or expression 'match ... against()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# BENCHMARK()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3)));
+ERROR HY000: Function or expression 'benchmark()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# CHARSET()
+create or replace table t1 (a varchar(64), b varchar(64) as (charset(a)) PERSISTENT);
+# COERCIBILITY()
+create or replace table t1 (a varchar(64), b int as (coercibility(a)) PERSISTENT);
+# COLLATION()
+create or replace table t1 (a varchar(64), b varchar(64) as (collation(a)) PERSISTENT);
+# CONNECTION_ID()
+create or replace table t1 (a int as (connection_id()));
+create or replace table t1 (a int as (connection_id()) PERSISTENT);
+ERROR HY000: Function or expression 'connection_id()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# DATABASE()
+create or replace table t1 (a varchar(32) as (database()));
+create or replace table t1 (a varchar(1024), b varchar(1024) as (database()) PERSISTENT);
+ERROR HY000: Function or expression 'database()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# FOUND_ROWS()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (found_rows()));
+ERROR HY000: Function or expression 'found_rows()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# GET_LOCK()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10)));
+ERROR HY000: Function or expression 'get_lock()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# IS_FREE_LOCK()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a)));
+ERROR HY000: Function or expression 'is_free_lock()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# IS_USED_LOCK()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a)));
+ERROR HY000: Function or expression 'is_used_lock()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# LAST_INSERT_ID()
+create or replace table t1 (a int as (last_insert_id()));
+ERROR HY000: Function or expression 'last_insert_id()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# MASTER_POS_WAIT()
+create or replace table t1 (a varchar(32), b int as (master_pos_wait(a,0,2)));
+ERROR HY000: Function or expression 'master_pos_wait()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# NAME_CONST()
+create or replace table t1 (a varchar(32) as (name_const('test',1)));
+ERROR HY000: Function or expression 'name_const()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# RELEASE_LOCK()
+create or replace table t1 (a varchar(32), b int as (release_lock(a)));
+ERROR HY000: Function or expression 'release_lock()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# ROW_COUNT()
+create or replace table t1 (a int as (row_count()));
+ERROR HY000: Function or expression 'row_count()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# SCHEMA()
+create or replace table t1 (a varchar(32) as (schema()) PERSISTENT);
+ERROR HY000: Function or expression 'database()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# SESSION_USER()
+create or replace table t1 (a varchar(32) as (session_user()) PERSISTENT);
+ERROR HY000: Function or expression 'user()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# SLEEP()
+create or replace table t1 (a int, b int as (sleep(a)));
+ERROR HY000: Function or expression 'sleep()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# SYSTEM_USER()
+create or replace table t1 (a varchar(32) as (system_user()) PERSISTENT);
+ERROR HY000: Function or expression 'user()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# USER()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (user()) PERSISTENT);
+ERROR HY000: Function or expression 'user()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# UUID_SHORT()
+create or replace table t1 (a varchar(1024) as (uuid_short()) PERSISTENT);
+ERROR HY000: Function or expression 'uuid_short()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# UUID()
+create or replace table t1 (a varchar(1024) as (uuid()) PERSISTENT);
+ERROR HY000: Function or expression 'uuid()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+# VALUES()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (value(a)));
+ERROR HY000: Function or expression 'value()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# VERSION()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (version()) PERSISTENT);
+ERROR HY000: Function or expression 'version()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# ENCRYPT()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (encrypt(a)) PERSISTENT);
+# Stored procedures
+create procedure p1()
+begin
+select current_user();
+end //
+create function f1()
+returns int
+begin
+return 1;
+end //
+create or replace table t1 (a int as (p1()) PERSISTENT);
+ERROR HY000: Function or expression '`p1`()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+create or replace table t1 (a int as (f1()) PERSISTENT);
+ERROR HY000: Function or expression '`f1`()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+drop procedure p1;
+drop function f1;
+# Unknown functions
+create or replace table t1 (a int as (f1()) PERSISTENT);
+ERROR HY000: Function or expression '`f1`()' cannot be used in the GENERATED ALWAYS AS clause of `a`
+#
+# GROUP BY FUNCTIONS
+#
+# AVG()
+create or replace table t1 (a int, b int as (avg(a)));
+ERROR HY000: Function or expression 'avg()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# BIT_AND()
+create or replace table t1 (a int, b int as (bit_and(a)));
+ERROR HY000: Function or expression 'bit_and()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# BIT_OR()
+create or replace table t1 (a int, b int as (bit_or(a)));
+ERROR HY000: Function or expression 'bit_or()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# BIT_XOR()
+create or replace table t1 (a int, b int as (bit_xor(a)));
+ERROR HY000: Function or expression 'bit_xor()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# COUNT(DISTINCT)
+create or replace table t1 (a int, b int as (count(distinct a)));
+ERROR HY000: Function or expression 'count(distinct )' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# COUNT()
+create or replace table t1 (a int, b int as (count(a)));
+ERROR HY000: Function or expression 'count()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# GROUP_CONCAT()
+create or replace table t1 (a varchar(32), b int as (group_concat(a,'')));
+ERROR HY000: Function or expression 'group_concat()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# MAX()
+create or replace table t1 (a int, b int as (max(a)));
+ERROR HY000: Function or expression 'max()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# MIN()
+create or replace table t1 (a int, b int as (min(a)));
+ERROR HY000: Function or expression 'min()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# STD()
+create or replace table t1 (a int, b int as (std(a)));
+ERROR HY000: Function or expression 'std()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# STDDEV_POP()
+create or replace table t1 (a int, b int as (stddev_pop(a)));
+ERROR HY000: Function or expression 'std()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# STDDEV_SAMP()
+create or replace table t1 (a int, b int as (stddev_samp(a)));
+ERROR HY000: Function or expression 'stddev_samp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# STDDEV()
+create or replace table t1 (a int, b int as (stddev(a)));
+ERROR HY000: Function or expression 'std()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# SUM()
+create or replace table t1 (a int, b int as (sum(a)));
+ERROR HY000: Function or expression 'sum()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# VAR_POP()
+create or replace table t1 (a int, b int as (var_pop(a)));
+ERROR HY000: Function or expression 'variance()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# VAR_SAMP()
+create or replace table t1 (a int, b int as (var_samp(a)));
+ERROR HY000: Function or expression 'var_samp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+# VARIANCE()
+create or replace table t1 (a int, b int as (variance(a)));
+ERROR HY000: Function or expression 'variance()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+#
+# XML FUNCTIONS
+#
+# ExtractValue()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]')) PERSISTENT);
+# UpdateXML()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>')) PERSISTENT);
+#
+# Sub-selects
+#
+create or replace table t1 (a int);
+create or replace table t2 (a int, b int as (select count(*) from t1));
+ERROR HY000: Function or expression 'select ...' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop table t1;
+create or replace table t1 (a int, b int as ((select 1)));
+ERROR HY000: Function or expression 'select ...' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create or replace table t1 (a int, b int as (a+(select 1)));
+ERROR HY000: Function or expression 'select ...' cannot be used in the GENERATED ALWAYS AS clause of `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 or replace table t1 (a int, b int as (a+sub3(1)));
+ERROR HY000: Function or expression '`sub3`()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop function sub1;
+#
+# Long expression
+create or replace table t1 (a int, b varchar(300) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')));
+drop table t1;
+create or replace table t1 (a int, b varchar(16384) as (concat(a,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')));
+ERROR HY000: Expression in the GENERATED ALWAYS AS clause is too big
+#
+# Constant expression
+create or replace table t1 (a int as (PI()) PERSISTENT);
+drop table if exists t1;
+create table t1 (a timestamp, b varchar(255) as (date_format(a, '%w %a %m %b')) stored);
+ERROR HY000: Function or expression 'date_format()' cannot be used in the GENERATED ALWAYS AS clause of `b`
diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result
new file mode 100644
index 00000000..965091e7
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result
@@ -0,0 +1,146 @@
+SET @@session.default_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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL VIRTUAL GENERATED
+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) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL VIRTUAL GENERATED
+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) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL VIRTUAL GENERATED
+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) GENERATED ALWAYS AS (`a` MOD 2) STORED
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL STORED GENERATED
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) STORED
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) persistent;
+ERROR HY000: This is not yet supported for generated columns
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result
new file mode 100644
index 00000000..bab4e501
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result
@@ -0,0 +1,146 @@
+SET @@session.default_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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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 MariaDB 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) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL VIRTUAL GENERATED
+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) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL VIRTUAL GENERATED
+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) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL COMMENT 'my comment'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL VIRTUAL GENERATED
+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) GENERATED ALWAYS AS (`a` MOD 2) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES NULL STORED GENERATED
+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);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+create table t1 (a int, b int as (a % 2));
+alter table t1 modify b int as (a % 2) persistent;
+ERROR HY000: This is not yet supported for generated columns
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_csv.result b/mysql-test/suite/vcol/r/vcol_csv.result
new file mode 100644
index 00000000..f8a0941c
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_csv.result
@@ -0,0 +1,7 @@
+SET @@session.default_storage_engine = 'CSV';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: CSV storage engine does not support generated columns
+create table t1 (a int not null);
+alter table t1 add column b int as (a+1);
+ERROR HY000: CSV storage engine does not support generated columns
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_handler_aria.result b/mysql-test/suite/vcol/r/vcol_handler_aria.result
new file mode 100644
index 00000000..d2e6affc
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_handler_aria.result
@@ -0,0 +1,76 @@
+SET @@session.default_storage_engine = 'maria';
+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;
diff --git a/mysql-test/suite/vcol/r/vcol_handler_innodb.result b/mysql-test/suite/vcol/r/vcol_handler_innodb.result
new file mode 100644
index 00000000..c3358acd
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_handler_innodb.result
@@ -0,0 +1,76 @@
+SET @@session.default_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;
diff --git a/mysql-test/suite/vcol/r/vcol_handler_myisam.result b/mysql-test/suite/vcol/r/vcol_handler_myisam.result
new file mode 100644
index 00000000..3596ab1f
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_handler_myisam.result
@@ -0,0 +1,76 @@
+SET @@session.default_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;
diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result
new file mode 100644
index 00000000..6807f89f
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result
@@ -0,0 +1,673 @@
+SET @@session.default_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 ignore into t1 values (1,2,3);
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'c' in table 't1' has been 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 ignore into t1 (a,b) values (1,3), (2,4);
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'b' in table 't1' has been 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 ignore into t2 select * from t1;
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't2' has been ignored
+Warning 1906 The value specified for generated column 'c' in table 't2' has been 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 ignore into t2 (a,b) select a,b from t1;
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't2' has been ignored
+Warning 1906 The value specified for generated column 'b' in table 't2' has been 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 ignore t1 set c=3 where a=2;
+Warnings:
+Warning 1906 The value specified for generated column 'c' in table 't1' has been 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 ignore t1 set c=3 where b=-2;
+Warnings:
+Warning 1906 The value specified for generated column 'c' in table 't1' has been 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;
+#
+# MDEV-9093: Persistent computed column is not updated when
+# update query contains join
+#
+CREATE TABLE `t1` (
+`id` bigint(20) NOT NULL,
+`name` varchar(254) DEFAULT NULL,
+`name_hash` varchar(64) AS (sha1(name)) PERSISTENT,
+PRIMARY KEY (`id`)
+);
+insert into t1(id,name) values (2050, 'name1'),(2051, 'name2'),(2041, 'name3');
+create table t2 (id bigint);
+insert into t2 values (2050),(2051),(2041);
+select * from t1;
+id name name_hash
+2041 name3 1aefcd1b0f39da45fa1fd7236f683c907c15ef82
+2050 name1 9b46b0dd3a8083c070c3b9953bb5f3f95c5ab4da
+2051 name2 39ea84acf1fef629fef18a9c6f5799bba32ecc25
+update t1 join t2 using(id) set name = concat(name,
+'+1') where t1.id in (2051,2041);
+select * from t1;
+id name name_hash
+2041 name3+1 93c9096df48221428de46e146abc9f4f94bf7d2e
+2050 name1 9b46b0dd3a8083c070c3b9953bb5f3f95c5ab4da
+2051 name2+1 fd4f236320db3956a5ec073c5ec39707d7f05708
+drop table t1,t2;
+#
+# Test error handling with virtual columns
+#
+CREATE TABLE IF NOT EXISTS t1 (
+f1 DOUBLE,
+f2 DOUBLE NOT NULL DEFAULT '0',
+f3 DOUBLE,
+f4 DOUBLE NOT NULL DEFAULT '0',
+v1 DOUBLE AS ( ( f1 DIV ( f1 ) ) <= f2 ) VIRTUAL,
+v2 DOUBLE AS ( ( f2 DIV ( f2 ) ) <= f2 ) VIRTUAL,
+KEY (v2)
+);
+set sql_mode='strict_all_tables,error_for_division_by_zero';
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 0, 0, 0);
+ERROR 22012: Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 1, 1, 1);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+ERROR 22012: Division by 0
+INSERT IGNORE INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 1, 1, 1);
+select v1 from t1;
+v1
+1
+0
+NULL
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0,0,0,0), (2,2,2,2);
+ERROR 22012: Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (3,3,3,3), (4,4,4,4);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (5,5,5,5), (1,0,0,0);
+ERROR 22012: Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (6,6,0,0);
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT f3, f4, f3, f4 FROM t1;
+ERROR 22012: Division by 0
+select count(*) from t1;
+count(*)
+6
+DELETE FROM t1 WHERE v2 != f1 and f1 < 5;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+select count(*) from t1;
+count(*)
+3
+select * from t1;
+f1 f2 f3 f4 v1 v2
+1 1 1 1 1 1
+1 0 1 1 0 NULL
+6 6 0 0 1 1
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1;
+ERROR 23000: Column 'f2' cannot be null
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1 where f2 !=0;
+Warnings:
+Warning 1365 Division by 0
+UPDATE t1 SET f3 = v1 WHERE f2 = 2 AND v2 is null;
+Warnings:
+Warning 1365 Division by 0
+SELECT * FROM t1;
+f1 f2 f3 f4 v1 v2
+1 1 1 1 1 1
+1 0 1 1 0 NULL
+6 6 0 0 1 1
+1 1 10 10 1 1
+1 1 10 10 1 1
+Warnings:
+Warning 1365 Division by 0
+TRUNCATE TABLE t1;
+set sql_mode='error_for_division_by_zero';
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 0, 0, 0);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 1, 1, 1);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 1, 1, 1);
+select v1 from t1;
+v1
+NULL
+1
+0
+NULL
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0,0,0,0), (2,2,2,2);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (3,3,3,3), (4,4,4,4);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (5,5,5,5), (1,0,0,0);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (6,6,0,0);
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT f3, f4, f3, f4 FROM t1;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+select count(*) from t1;
+count(*)
+22
+DELETE FROM t1 WHERE v2 != f1 and f1 < 5;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+select count(*) from t1;
+count(*)
+15
+select * from t1;
+f1 f2 f3 f4 v1 v2
+0 0 0 0 NULL NULL
+1 1 1 1 1 1
+1 0 1 1 0 NULL
+0 0 0 0 NULL NULL
+5 5 5 5 1 1
+1 0 0 0 0 NULL
+6 6 0 0 1 1
+0 0 0 0 NULL NULL
+1 1 1 1 1 1
+1 1 1 1 1 1
+1 1 1 1 1 1
+0 0 0 0 NULL NULL
+5 5 5 5 1 1
+0 0 0 0 NULL NULL
+0 0 0 0 NULL NULL
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+UPDATE t1 SET f3 = v1 WHERE f2 = 2 AND v2 is null;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+drop table t1;
+set sql_mode=@@global.sql_mode;
diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result
new file mode 100644
index 00000000..43206dba
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result
@@ -0,0 +1,628 @@
+SET @@session.default_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 ignore into t1 values (1,2,3);
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'c' in table 't1' has been 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 ignore into t1 (a,b) values (1,3), (2,4);
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't1' has been ignored
+Warning 1906 The value specified for generated column 'b' in table 't1' has been 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 ignore into t2 select * from t1;
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't2' has been ignored
+Warning 1906 The value specified for generated column 'c' in table 't2' has been 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 ignore into t2 (a,b) select a,b from t1;
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't2' has been ignored
+Warning 1906 The value specified for generated column 'b' in table 't2' has been 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 ignore t1 set c=3 where a=2;
+Warnings:
+Warning 1906 The value specified for generated column 'c' in table 't1' has been 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 ignore t1 set c=3 where b=-2;
+Warnings:
+Warning 1906 The value specified for generated column 'c' in table 't1' has been 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;
+#
+# MDEV-9093: Persistent computed column is not updated when
+# update query contains join
+#
+CREATE TABLE `t1` (
+`id` bigint(20) NOT NULL,
+`name` varchar(254) DEFAULT NULL,
+`name_hash` varchar(64) AS (sha1(name)) PERSISTENT,
+PRIMARY KEY (`id`)
+);
+insert into t1(id,name) values (2050, 'name1'),(2051, 'name2'),(2041, 'name3');
+create table t2 (id bigint);
+insert into t2 values (2050),(2051),(2041);
+select * from t1;
+id name name_hash
+2050 name1 9b46b0dd3a8083c070c3b9953bb5f3f95c5ab4da
+2051 name2 39ea84acf1fef629fef18a9c6f5799bba32ecc25
+2041 name3 1aefcd1b0f39da45fa1fd7236f683c907c15ef82
+update t1 join t2 using(id) set name = concat(name,
+'+1') where t1.id in (2051,2041);
+select * from t1;
+id name name_hash
+2050 name1 9b46b0dd3a8083c070c3b9953bb5f3f95c5ab4da
+2051 name2+1 fd4f236320db3956a5ec073c5ec39707d7f05708
+2041 name3+1 93c9096df48221428de46e146abc9f4f94bf7d2e
+drop table t1,t2;
+#
+# Test error handling with virtual columns
+#
+CREATE TABLE IF NOT EXISTS t1 (
+f1 DOUBLE,
+f2 DOUBLE NOT NULL DEFAULT '0',
+f3 DOUBLE,
+f4 DOUBLE NOT NULL DEFAULT '0',
+v1 DOUBLE AS ( ( f1 DIV ( f1 ) ) <= f2 ) VIRTUAL,
+v2 DOUBLE AS ( ( f2 DIV ( f2 ) ) <= f2 ) VIRTUAL,
+KEY (v2)
+);
+set sql_mode='strict_all_tables,error_for_division_by_zero';
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 0, 0, 0);
+ERROR 22012: Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 1, 1, 1);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+ERROR 22012: Division by 0
+INSERT IGNORE INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 1, 1, 1);
+select v1 from t1;
+v1
+1
+0
+NULL
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0,0,0,0), (2,2,2,2);
+ERROR 22012: Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (3,3,3,3), (4,4,4,4);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (5,5,5,5), (1,0,0,0);
+ERROR 22012: Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (6,6,0,0);
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT f3, f4, f3, f4 FROM t1;
+ERROR 22012: Division by 0
+select count(*) from t1;
+count(*)
+13
+DELETE FROM t1 WHERE v2 != f1 and f1 < 5;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+select count(*) from t1;
+count(*)
+8
+select * from t1;
+f1 f2 f3 f4 v1 v2
+1 1 1 1 1 1
+1 0 1 1 0 NULL
+5 5 5 5 1 1
+6 6 0 0 1 1
+1 1 1 1 1 1
+1 1 1 1 1 1
+1 1 1 1 1 1
+5 5 5 5 1 1
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1;
+ERROR 23000: Column 'f2' cannot be null
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1 where f2 !=0;
+Warnings:
+Warning 1365 Division by 0
+UPDATE t1 SET f3 = v1 WHERE f2 = 2 AND v2 is null;
+Warnings:
+Warning 1365 Division by 0
+SELECT * FROM t1;
+f1 f2 f3 f4 v1 v2
+1 1 1 1 1 1
+1 0 1 1 0 NULL
+1 1 10 10 1 1
+1 1 10 10 1 1
+1 1 10 10 1 1
+5 5 5 5 1 1
+6 6 0 0 1 1
+1 1 1 1 1 1
+1 1 1 1 1 1
+1 1 1 1 1 1
+1 1 10 10 1 1
+1 1 10 10 1 1
+5 5 5 5 1 1
+1 1 10 10 1 1
+1 1 10 10 1 1
+1 1 10 10 1 1
+1 1 10 10 1 1
+Warnings:
+Warning 1365 Division by 0
+TRUNCATE TABLE t1;
+set sql_mode='error_for_division_by_zero';
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 0, 0, 0);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 1, 1, 1);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (1, 0, 1, 1);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0, 1, 1, 1);
+select v1 from t1;
+v1
+NULL
+1
+0
+NULL
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (0,0,0,0), (2,2,2,2);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (3,3,3,3), (4,4,4,4);
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (5,5,5,5), (1,0,0,0);
+Warnings:
+Warning 1365 Division by 0
+INSERT INTO t1 (f1, f2, f3, f4) VALUES (6,6,0,0);
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT f3, f4, f3, f4 FROM t1;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+select count(*) from t1;
+count(*)
+22
+DELETE FROM t1 WHERE v2 != f1 and f1 < 5;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+select count(*) from t1;
+count(*)
+15
+select * from t1;
+f1 f2 f3 f4 v1 v2
+0 0 0 0 NULL NULL
+1 1 1 1 1 1
+1 0 1 1 0 NULL
+0 0 0 0 NULL NULL
+5 5 5 5 1 1
+1 0 0 0 0 NULL
+6 6 0 0 1 1
+0 0 0 0 NULL NULL
+1 1 1 1 1 1
+1 1 1 1 1 1
+1 1 1 1 1 1
+0 0 0 0 NULL NULL
+5 5 5 5 1 1
+0 0 0 0 NULL NULL
+0 0 0 0 NULL NULL
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+INSERT INTO t1 ( f1, f2, f3, f4 ) SELECT v1, v2, 10,10 FROM t1;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+Warning 1048 Column 'f2' cannot be null
+Warning 1365 Division by 0
+UPDATE t1 SET f3 = v1 WHERE f2 = 2 AND v2 is null;
+Warnings:
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+Warning 1365 Division by 0
+drop table t1;
+set sql_mode=@@global.sql_mode;
diff --git a/mysql-test/suite/vcol/r/vcol_keys_aria.result b/mysql-test/suite/vcol/r/vcol_keys_aria.result
new file mode 100644
index 00000000..ef8cb3c7
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_keys_aria.result
@@ -0,0 +1,2 @@
+create table t1 (a int, b int as (a+1), c int, index(b)) engine=aria;
+ERROR HY000: Key/Index cannot be defined on a virtual generated column
diff --git a/mysql-test/suite/vcol/r/vcol_keys_innodb.result b/mysql-test/suite/vcol/r/vcol_keys_innodb.result
new file mode 100644
index 00000000..c07e00a5
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result
@@ -0,0 +1,286 @@
+SET @@session.default_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);
+drop table t1;
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ UNIQUE KEY `b` (`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES UNI NULL STORED GENERATED
+drop table t1;
+create table t1 (a int, b int as (a*2), unique key (b));
+drop table t1;
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ UNIQUE KEY `b` (`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES UNI NULL STORED GENERATED
+drop table t1;
+create table t1 (a int, b int as (a*2));
+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;
+# 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));
+drop table t1;
+create table t1 (a int, b int as (a*2), index (a,b));
+drop table t1;
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ KEY `b` (`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES MUL NULL STORED GENERATED
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ KEY `a` (`a`,`b`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES MUL NULL
+b int(11) YES NULL STORED GENERATED
+drop table t1;
+create table t1 (a int, b int as (a*2));
+alter table t1 add index (b);
+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;
+# 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 geometry 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 HY000: Incorrect arguments to SPATIAL INDEX
+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 generated 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 generated 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 generated 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 generated 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 generated 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 generated column
+drop table t1;
+create table t1 (a int, b int as (a+1), foreign key (b) references t2(a));
+ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
+create table t1 (a int, b int as (a+1));
+alter table t1 add foreign key (b) references t2(a);
+ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
+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
+create table t1 (a int, b timestamp as (now()), key (b));
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create table t1 (a int, b timestamp as (now()));
+alter table t1 add index (b);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop table t1;
+create table t1 (a int, b varchar(100) as (user()), key (b));
+ERROR HY000: Function or expression 'user()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create table t1 (a int, b varchar(100) as (user()));
+alter table t1 add index (b);
+ERROR HY000: Function or expression 'user()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop table t1;
+create table t1 (a int, b double as (rand()), key (b));
+ERROR HY000: Function or expression 'rand()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create table t1 (a int, b double as (rand()));
+alter table t1 add index (b);
+ERROR HY000: Function or expression 'rand()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop table t1;
+CREATE OR REPLACE TABLE t1 (
+f2 DOUBLE NOT NULL DEFAULT '0',
+f3 DOUBLE NOT NULL DEFAULT '0',
+f4 DOUBLE,
+f5 DOUBLE DEFAULT '0',
+v4 DOUBLE AS (IF(f4,f3,f2)) VIRTUAL,
+KEY (f5),
+KEY (v4)
+);
+INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,4,1,0),(5,7,NULL,0);
+INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f3, f5, f3 FROM t1;
+INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,0,NULL,1);
+INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f5, f5, f3 FROM t1;
+DELETE FROM t1 WHERE f5 = 1 OR v4 = 4 ORDER BY f5,v4 LIMIT 9;
+SELECT * from t1;
+f2 f3 f4 f5 v4
+5 7 NULL 0 5
+5 4 0 4 5
+5 7 0 7 5
+5 0 0 4 5
+5 0 0 7 5
+5 7 7 7 7
+5 1 1 0 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+d DECIMAL(63,0) NOT NULL DEFAULT 0,
+c VARCHAR(64) NOT NULL DEFAULT '',
+vd DECIMAL(63,0) AS (d) VIRTUAL,
+vc VARCHAR(2048) AS (c) VIRTUAL,
+pk BIGINT AUTO_INCREMENT,
+PRIMARY KEY(pk));
+INSERT INTO t1 (d,c) VALUES (0.5,'foo');
+Warnings:
+Note 1265 Data truncated for column 'd' at row 1
+SELECT * FROM t1 WHERE vc != 'bar' ORDER BY vd;
+d c vd vc pk
+1 foo 1 foo 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+pk BIGINT,
+c CHAR(64) NOT NULL DEFAULT '',
+vc CHAR(64) AS (c) VIRTUAL,
+PRIMARY KEY(pk),
+INDEX(vc(32))
+);
+DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
+DROP TABLE t1;
+#
+# MDEV-11737 Failing assertion: block->magic_n == MEM_BLOCK_MAGIC_N
+#
+CREATE TABLE t1 (i INT PRIMARY KEY, vi INT AS (i*2) VIRTUAL UNIQUE)
+ENGINE=InnoDB;
+CREATE TABLE t2 (i INT) ENGINE=InnoDB;
+ALTER TABLE t1 ADD COLUMN col INT;
+SELECT * FROM t1 WHERE vi < 2;
+i vi col
+DROP TABLE t1, t2;
+create table t1 (
+pk int auto_increment,
+col_varchar varchar(847) not null default '',
+col_int bigint(15) unsigned zerofill,
+col_datetime datetime(3) not null default '1900-01-01 00:00:00',
+col_time time(5) not null default '00:00:00',
+col_blob text,
+col_bit bit(34),
+col_year year,
+col_char char(10),
+col_dec decimal(18,9) not null default 0,
+col_enum enum('','a','b','c','d','e','f','foo','bar') not null default '',
+col_date date not null default '1900-01-01',
+col_timestamp timestamp(3) not null default '1971-01-01 00:00:00',
+vcol_datetime datetime as (truncate(col_datetime,0)) virtual,
+vcol_dec decimal(18,9) zerofill as (col_dec) virtual,
+vcol_bit bit(63) as (col_bit) virtual,
+vcol_char binary(51) as (col_char) virtual,
+vcol_timestamp timestamp(5) as (col_timestamp) virtual,
+vcol_enum enum('','a','b','c','d','e','f','foo','bar') as (col_enum) virtual,
+vcol_int tinyint(48) zerofill as (col_int) virtual,
+vcol_time time(4) as (col_time) virtual,
+vcol_varchar varbinary(3873) as (col_varchar) virtual,
+vcol_year year as (col_year) virtual,
+vcol_date date as (col_date) virtual,
+vcol_blob longtext as (col_blob) virtual,
+primary key(pk)
+) engine=innodb;
+insert into t1 (col_varchar,col_int,col_datetime,col_time,col_blob,col_bit,col_year,col_char,col_dec,col_enum,col_date,col_timestamp) values
+('foo',1,'2010-05-08 13:08:12.034783','18:32:14','foo',b'0111110101001001',1992,'f',0.2,'','1994-12-26','2019-01-11 00:00:00'),
+('bar',6,'1900-01-01 00:00:00','00:00:00','bar',b'10011000001101011000101',1985,'b',0.7,'','2028-04-06','1971-01-01 00:00:00');
+alter table t1 add index(vcol_datetime);
+drop table t1;
+create table t1 (
+pk int,
+col_blob mediumtext not null default '',
+vcol_blob tinyblob as (col_blob) virtual,
+col_char char(22) null,
+primary key(pk),
+index(col_char,vcol_blob(64))
+) engine=innodb;
+insert ignore into t1 (pk) values (1),(2);
+update t1 set col_char = 'foo' where pk = 1;
+drop table t1;
+create table t1 (
+id int not null primary key,
+a varchar(200),
+b varchar(200),
+c int,
+va char(200) generated always as (ucase(a)) virtual,
+vb char(200) generated always as (ucase(b)) virtual,
+key (c,va,vb)
+) engine=innodb;
+insert t1 (id,a,c) select seq,seq,seq from seq_1_to_330;
+select IF(@@innodb_sort_buffer_size < count(*)*200, 'GOOD', 'WRONG SIZE') from t1;
+IF(@@innodb_sort_buffer_size < count(*)*200, 'GOOD', 'WRONG SIZE')
+GOOD
+alter table t1 drop column va;
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_keys_myisam.result b/mysql-test/suite/vcol/r/vcol_keys_myisam.result
new file mode 100644
index 00000000..2e15c502
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result
@@ -0,0 +1,420 @@
+SET @@session.default_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);
+drop table t1;
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ UNIQUE KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES UNI NULL STORED GENERATED
+drop table t1;
+create table t1 (a int, b int as (a*2), unique key (b));
+drop table t1;
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ UNIQUE KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES UNI NULL STORED GENERATED
+drop table t1;
+create table t1 (a int, b int as (a*2));
+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;
+# 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));
+drop table t1;
+create table t1 (a int, b int as (a*2), index (a,b));
+drop table t1;
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ KEY `b` (`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b int(11) YES MUL NULL STORED GENERATED
+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) GENERATED ALWAYS AS (`a` * 2) STORED,
+ KEY `a` (`a`,`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+describe t1;
+Field Type Null Key Default Extra
+a int(11) YES MUL NULL
+b int(11) YES NULL STORED GENERATED
+drop table t1;
+create table t1 (a int, b int as (a*2));
+alter table t1 add index (b);
+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;
+# 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 geometry 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 HY000: Incorrect arguments to SPATIAL INDEX
+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 generated 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 generated 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 generated 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 generated 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 generated 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 generated 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
+create table t1 (a int, b timestamp as (now()), key (b));
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create table t1 (a int, b timestamp as (now()));
+alter table t1 add index (b);
+ERROR HY000: Function or expression 'current_timestamp()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop table t1;
+create table t1 (a int, b varchar(100) as (user()), key (b));
+ERROR HY000: Function or expression 'user()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create table t1 (a int, b varchar(100) as (user()));
+alter table t1 add index (b);
+ERROR HY000: Function or expression 'user()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop table t1;
+create table t1 (a int, b double as (rand()), key (b));
+ERROR HY000: Function or expression 'rand()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+create table t1 (a int, b double as (rand()));
+alter table t1 add index (b);
+ERROR HY000: Function or expression 'rand()' cannot be used in the GENERATED ALWAYS AS clause of `b`
+drop table t1;
+CREATE OR REPLACE TABLE t1 (
+f2 DOUBLE NOT NULL DEFAULT '0',
+f3 DOUBLE NOT NULL DEFAULT '0',
+f4 DOUBLE,
+f5 DOUBLE DEFAULT '0',
+v4 DOUBLE AS (IF(f4,f3,f2)) VIRTUAL,
+KEY (f5),
+KEY (v4)
+);
+INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,4,1,0),(5,7,NULL,0);
+INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f3, f5, f3 FROM t1;
+INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,0,NULL,1);
+INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f5, f5, f3 FROM t1;
+DELETE FROM t1 WHERE f5 = 1 OR v4 = 4 ORDER BY f5,v4 LIMIT 9;
+SELECT * from t1;
+f2 f3 f4 f5 v4
+5 7 NULL 0 5
+5 4 0 4 5
+5 7 0 7 5
+5 0 0 4 5
+5 0 0 7 5
+5 7 7 7 7
+5 1 1 0 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+d DECIMAL(63,0) NOT NULL DEFAULT 0,
+c VARCHAR(64) NOT NULL DEFAULT '',
+vd DECIMAL(63,0) AS (d) VIRTUAL,
+vc VARCHAR(2048) AS (c) VIRTUAL,
+pk BIGINT AUTO_INCREMENT,
+PRIMARY KEY(pk));
+INSERT INTO t1 (d,c) VALUES (0.5,'foo');
+Warnings:
+Note 1265 Data truncated for column 'd' at row 1
+SELECT * FROM t1 WHERE vc != 'bar' ORDER BY vd;
+d c vd vc pk
+1 foo 1 foo 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+pk BIGINT,
+c CHAR(64) NOT NULL DEFAULT '',
+vc CHAR(64) AS (c) VIRTUAL,
+PRIMARY KEY(pk),
+INDEX(vc(32))
+);
+DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
+DROP TABLE t1;
+#
+# Original test
+#
+create table t1 (a int, b int as (a+1), c int, index(b));
+insert t1 (a,c) values (0x7890abcd, 0x76543210);
+insert t1 (a,c) select seq, sin(seq)*10000 from seq_1_to_1000;
+explain select * from t1 where b=10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref b b 5 const 1
+select * from t1 where b=10;
+a b c
+9 10 4121
+
+MyISAM file: datadir/test/t1
+Record format: Fixed length
+Character set: latin1_swedish_ci (8)
+Data records: 1001 Deleted blocks: 0
+Recordlength: 9
+
+table description:
+Key Start Len Index Type
+1 10 4 multip. long NULL
+update t1 set a=20 where b=10;
+select * from t1 where b=10;
+a b c
+select * from t1 where b=21;
+a b c
+20 21 4121
+20 21 9129
+delete from t1 where b=21;
+select * from t1 where b=21;
+a b c
+alter table t1 add column d char(20) as (concat(a,c));
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+create index i on t1 (d);
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+check table t1 quick;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+check table t1 medium;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
+t1 1 b 1 b A 999 NULL NULL YES BTREE NO
+t1 1 i 1 d A 999 NULL NULL YES BTREE NO
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+delete from t1 where b=12;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
+t1 1 b 1 b A 998 NULL NULL YES BTREE NO
+t1 1 i 1 d A 998 NULL NULL YES BTREE NO
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored
+t1 1 b 1 b A 998 NULL NULL YES BTREE NO
+t1 1 i 1 d A 998 NULL NULL YES BTREE NO
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+repair table t1 quick;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+repair table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair warning Number of rows changed from 0 to 998
+test.t1 repair status OK
+select * from t1 where b=11;
+a b c d
+10 11 -5440 10-5440
+update t1 set a=30 where b=11;
+select * from t1 where b=11;
+a b c d
+select * from t1 where b=31;
+a b c d
+30 31 -5440 30-5440
+30 31 -9880 30-9880
+drop table t1;
+#
+# MDEV-11606 Server crashes in mi_make_key / sort_key_read
+#
+CREATE TABLE t1 (
+pk BIGINT AUTO_INCREMENT,
+col_date DATE NULL,
+col_datetime DATETIME(1) NULL,
+col_int TINYINT(13) UNSIGNED ZEROFILL NULL,
+col_varchar VARBINARY(2222) NULL,
+col_timestamp TIMESTAMP(2) NULL,
+col_bit BIT(64) NOT NULL DEFAULT 0,
+col_blob MEDIUMBLOB NULL,
+col_dec DECIMAL(10,9) ZEROFILL NOT NULL DEFAULT 0,
+col_time TIME(4) NULL,
+col_year YEAR NOT NULL DEFAULT '1970',
+col_char CHAR(129) NULL,
+col_enum SET('','a','b','c','d','e','f','foo','bar') NULL,
+vcol_dec DECIMAL(50,18) ZEROFILL AS (col_dec) VIRTUAL,
+vcol_bit BIT(48) AS (col_bit) VIRTUAL,
+vcol_char CHAR(224) AS (col_char) VIRTUAL,
+vcol_datetime DATETIME(4) AS (col_datetime) VIRTUAL,
+vcol_year YEAR AS (col_year) VIRTUAL,
+vcol_varchar VARBINARY(356) AS (col_varchar) VIRTUAL,
+vcol_blob MEDIUMBLOB AS (col_blob) VIRTUAL,
+vcol_timestamp TIMESTAMP(5) AS (col_timestamp) VIRTUAL,
+vcol_int BIGINT(46) AS (col_int) VIRTUAL,
+vcol_time TIME(1) AS (col_time) VIRTUAL,
+vcol_date DATE AS (col_date) VIRTUAL,
+vcol_enum SET('','a','b','c','d','e','f','foo','bar') AS (col_enum) VIRTUAL,
+UNIQUE(pk),
+PRIMARY KEY(pk)
+) ENGINE=MyISAM;
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+ALTER TABLE t1 ADD INDEX(col_enum,vcol_int);
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+ALTER TABLE t1 ADD INDEX(col_year);
+DROP TABLE t1;
+create table t1 (
+pk int primary key auto_increment,
+b bit default null,
+key(b)
+) engine=myisam;
+insert into t1 values (null, 0);
+repair table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+drop table t1;
+create table t1 ( id int primary key,
+hexid varchar(10) generated always as (hex(id)) stored,
+key (hexid)) engine=myisam;
+insert into t1 (id) select 100;
+select * from t1;
+id hexid
+100 64
+drop table t1;
+#
+# MDEV-15881 Assertion `is_valid_value_slow()' failed in Datetime::Datetime or corrupt data after ALTER with indexed persistent column
+#
+CREATE TABLE t1 (i INT, d1 DATE, d2 DATE NOT NULL, t TIMESTAMP, KEY(t)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'2023-03-16','2023-03-15','2012-12-12 12:12:12');
+ALTER TABLE t1 MODIFY t FLOAT AS (i) PERSISTENT;
+SELECT i, d1, d2 INTO OUTFILE 'load_t1' FROM t1;
+DELETE FROM t1;
+LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
+SELECT * FROM t1 WHERE d2 < d1;
+i d1 d2 t
+1 2023-03-16 2023-03-15 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+i INT DEFAULT NULL,
+d1 DATE DEFAULT NULL,
+d2 DATE NOT NULL,
+t FLOAT GENERATED ALWAYS AS (i) STORED,
+KEY (t)
+) ENGINE=MyISAM;
+LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
+SELECT * FROM t1 WHERE d2 < d1;
+i d1 d2 t
+1 2023-03-16 2023-03-15 1
+DROP TABLE t1;
+#
+# MDEV-20015 Assertion `!in_use->is_error()' failed in TABLE::update_virtual_field
+#
+create or replace table t1 (a int);
+insert into t1 (a) values (1), (1);
+create or replace table t2 (pk int, b int, c int as (b) virtual, primary key (pk), key(c));
+insert into t2 (pk) select a from t1;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+drop tables t1, t2;
diff --git a/mysql-test/suite/vcol/r/vcol_memory.result b/mysql-test/suite/vcol/r/vcol_memory.result
new file mode 100644
index 00000000..3284d973
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_memory.result
@@ -0,0 +1,7 @@
+SET @@session.default_storage_engine = 'memory';
+create table t1 (a int, b int as (a+1));
+ERROR HY000: MEMORY storage engine does not support generated columns
+create table t1 (a int not null);
+alter table t1 add column b int as (a+1);
+ERROR HY000: MEMORY storage engine does not support generated columns
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_merge.result b/mysql-test/suite/vcol/r/vcol_merge.result
new file mode 100644
index 00000000..2629c65f
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_merge.result
@@ -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: MRG_MyISAM storage engine does not support generated columns
+drop table t1,t2;
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
new file mode 100644
index 00000000..3bb06116
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -0,0 +1,579 @@
+create table t1 (a int, b int, v int as (a+1), index idx(b));
+insert into t1(a, b) values
+(4, 40), (3, 30), (5, 50), (7, 70), (8, 80), (2, 20), (1, 10);
+select * from t1 order by b;
+a b v
+1 10 2
+2 20 3
+3 30 4
+4 40 5
+5 50 6
+7 70 8
+8 80 9
+delete from t1 where v > 6 order by b limit 1;
+select * from t1 order by b;
+a b v
+1 10 2
+2 20 3
+3 30 4
+4 40 5
+5 50 6
+8 80 9
+update t1 set a=v order by b limit 1;
+select * from t1 order by b;
+a b v
+2 10 3
+2 20 3
+3 30 4
+4 40 5
+5 50 6
+8 80 9
+drop table t1;
+CREATE TABLE t1 (
+a int NOT NULL DEFAULT '0',
+v double AS ((1, a)) VIRTUAL
+);
+ERROR 21000: Operand should contain 1 column(s)
+CREATE TABLE t1 (
+a CHAR(255) BINARY NOT NULL DEFAULT 0,
+b CHAR(255) BINARY NOT NULL DEFAULT 0,
+v CHAR(255) BINARY AS (CONCAT(a,b)) VIRTUAL );
+INSERT INTO t1(a,b) VALUES ('4','7'), ('4','6');
+SELECT 1 AS C FROM t1 ORDER BY v;
+C
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1(a int, b int DEFAULT 0, v INT AS (b+10) PERSISTENT);
+INSERT INTO t1(a) VALUES (1);
+SELECT b, v FROM t1;
+b v
+0 10
+DROP TABLE t1;
+CREATE TABLE t1(a int DEFAULT 100, v int AS (a+1) PERSISTENT);
+INSERT INTO t1 () VALUES ();
+CREATE TABLE t2(a int DEFAULT 100 , v int AS (a+1));
+INSERT INTO t2 () VALUES ();
+SELECT a, v FROM t1;
+a v
+100 101
+SELECT a, v FROM t2;
+a v
+100 101
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+a datetime NOT NULL DEFAULT '2000-01-01',
+v boolean AS (a < '2001-01-01')
+);
+INSERT INTO t1(a) VALUES ('2002-02-15');
+INSERT INTO t1(a) VALUES ('2000-10-15');
+SELECT a, v FROM t1;
+a v
+2002-02-15 00:00:00 0
+2000-10-15 00:00:00 1
+SELECT a, v FROM t1;
+a v
+2002-02-15 00:00:00 0
+2000-10-15 00:00:00 1
+CREATE TABLE t2 (
+a datetime NOT NULL DEFAULT '2000-01-01',
+v boolean AS (a < '2001-01-01') PERSISTENT
+);
+INSERT INTO t2(a) VALUES ('2002-02-15');
+INSERT INTO t2(a) VALUES ('2000-10-15');
+SELECT * FROM t2;
+a v
+2002-02-15 00:00:00 0
+2000-10-15 00:00:00 1
+DROP TABLE t1, t2;
+CREATE TABLE t1 (
+a char(255), b char(255), c char(255), d char(255),
+v char(255) AS (CONCAT(c,d) ) VIRTUAL
+);
+INSERT INTO t1(a,b,c,d) VALUES ('w','x','y','z'), ('W','X','Y','Z');
+SELECT v FROM t1 ORDER BY CONCAT(a,b);
+v
+yz
+YZ
+DROP TABLE t1;
+CREATE TABLE t1 (f1 INTEGER, v1 INTEGER AS (f1) VIRTUAL);
+CREATE TABLE t2 AS SELECT v1 FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `v1` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1,t2;
+CREATE TABLE t1 (p int, a double NOT NULL, v double AS (ROUND(a,p)) VIRTUAL);
+INSERT IGNORE INTO t1 VALUES (0,1,0);
+Warnings:
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+INSERT IGNORE INTO t1 VALUES (NULL,0,0);
+Warnings:
+Warning 1906 The value specified for generated column 'v' in table 't1' has been ignored
+SELECT a, p, v, ROUND(a,p), ROUND(a,p+NULL) FROM t1;
+a p v ROUND(a,p) ROUND(a,p+NULL)
+1 0 1 1 NULL
+0 NULL NULL NULL NULL
+DROP TABLE t1;
+CREATE TABLE t1 (p int, a double NOT NULL);
+INSERT INTO t1(p,a) VALUES (0,1);
+INSERT INTO t1(p,a) VALUES (NULL,0);
+SELECT a, p, ROUND(a,p), ROUND(a,p+NULL) FROM t1;
+a p ROUND(a,p) ROUND(a,p+NULL)
+1 0 1 NULL
+0 NULL NULL NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a char(32), v char(32) CHARACTER SET ucs2 AS (a) VIRTUAL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(32) DEFAULT NULL,
+ `v` char(32) CHARACTER SET ucs2 COLLATE ucs2_general_ci GENERATED ALWAYS AS (`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (a int, b int as (a+1) VIRTUAL);
+SELECT table_schema, table_name, column_name, column_type, extra
+FROM information_schema.columns WHERE table_name = 't1';
+table_schema table_name column_name column_type extra
+test t1 a int(11)
+test t1 b int(11)
+SELECT table_schema, table_name, column_name, column_type, extra
+FROM information_schema.columns WHERE table_name = 't2';
+table_schema table_name column_name column_type extra
+test t2 a int(11)
+test t2 b int(11) VIRTUAL GENERATED
+DROP TABLE t1,t2;
+create table t1 (
+a int not null, b char(2) not null,
+c enum('Y','N') as (case when b = 'aa' then 'Y' else 'N' end) persistent
+);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` char(2) NOT NULL,
+ `c` enum('Y','N') GENERATED ALWAYS AS (case when `b` = 'aa' then 'Y' else 'N' end) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1(a,b) values (1,'bb'), (2,'aa'), (3,'cc');
+select * from t1;
+a b c
+1 bb N
+2 aa Y
+3 cc N
+create table t2 (
+a int, b int,
+c set("y","n")
+as (if(a=0,if(b=0,('n,n'),('n,y')),if(b=0,('y,n'),('y,y')))) persistent
+);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` set('y','n') GENERATED ALWAYS AS (if(`a` = 0,if(`b` = 0,'n,n','n,y'),if(`b` = 0,'y,n','y,y'))) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t2(a,b) values (7,0), (2,3), (0,1);
+select * from t2;
+a b c
+7 0 y,n
+2 3 y
+0 1 y,n
+drop table t1,t2;
+SET @old_debug= @@global.debug;
+SET @old_debug= @@global.debug;
+SET GLOBAL debug_dbug= "+d,write_delay_wakeup";
+CREATE TABLE t1 (a int,
+ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+tsv TIMESTAMP AS (ADDDATE(ts, INTERVAL 1 DAY)) VIRTUAL
+) ENGINE=MyISAM;
+# First test FLUSH TABLES
+INSERT INTO t1 (a,tsv) VALUES (1,DEFAULT);
+INSERT DELAYED INTO t1 (a,tsv) VALUES (2,DEFAULT);
+FLUSH TABLES;
+SELECT COUNT(*) > 0 FROM t1;
+COUNT(*) > 0
+1
+# Then test FLUSH TABLES t1;
+INSERT INTO t1 (a,tsv) VALUES (3,DEFAULT);
+INSERT DELAYED INTO t1 (a,tsv) VALUES (4,DEFAULT);
+FLUSH TABLES t1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+4
+# Then test FLUSH TABLES WITH READ LOCK;
+INSERT INTO t1 (a,tsv) VALUES (5,DEFAULT);
+INSERT DELAYED INTO t1 (a,tsv) VALUES (6,DEFAULT);
+FLUSH TABLES WITH READ LOCK;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+6
+set GLOBAL debug_dbug= @old_debug;
+unlock tables;
+DROP TABLE t1;
+#
+# MDEV-4823 Server crashes in Item_func_not::fix_fields on
+# creating a table with a virtual column using NOT
+#
+CREATE TABLE t1 ( f1 INT, v4 INT AS ( NOT f1 ) VIRTUAL );
+drop table t1;
+# end of 5.2 tests
+create table t1 (a int, b int);
+insert into t1 values (3, 30), (4, 20), (1, 20);
+create table t2 (c int, d int, v int as (d+1), index idx(c));
+insert into t2(c,d) values
+(20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
+(70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
+insert into t2(c,d) values
+(120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
+(170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
+set join_cache_level=6;
+explain
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ref idx idx 5 test.t1.b 2 Using where
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+a b c d v
+3 30 30 100 101
+4 20 20 100 101
+1 20 20 100 101
+set join_cache_level=default;
+drop table t1, t2;
+create table t1 (a bigint, b bigint as (a > '2'));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) DEFAULT NULL,
+ `b` bigint(20) GENERATED ALWAYS AS (`a` > 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 (a) values (1),(3);
+select * from t1;
+a b
+1 0
+3 1
+select * from t1;
+a b
+1 0
+3 1
+drop table t1;
+create table t1 (a bigint, b bigint as (a between 0 and 2));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) DEFAULT NULL,
+ `b` bigint(20) GENERATED ALWAYS AS (`a` between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 (a) values (1),(3);
+select * from t1;
+a b
+1 1
+3 0
+select * from t1;
+a b
+1 1
+3 0
+drop table t1;
+create table t1 (a char(10), b char(10) as (a between 0 and 2));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(10) DEFAULT NULL,
+ `b` char(10) GENERATED ALWAYS AS (`a` between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 (a) values (1),(3);
+select * from t1;
+a b
+1 1
+3 0
+select * from t1;
+a b
+1 1
+3 0
+drop table t1;
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL,
+`b` varchar(32) DEFAULT NULL,
+`c` int(11) AS (a MOD 10) VIRTUAL,
+`d` varchar(5) AS (LEFT(b,5)) PERSISTENT
+) ENGINE=MyISAM;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` varchar(32) DEFAULT NULL,
+ `c` int(11) GENERATED ALWAYS AS (`a` MOD 10) VIRTUAL,
+ `d` varchar(5) GENERATED ALWAYS AS (left(`b`,5)) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+show columns from t1;
+Field Type Null Key Default Extra
+a int(11) NO NULL
+b varchar(32) YES NULL
+c int(11) YES NULL VIRTUAL GENERATED
+d varchar(5) YES NULL STORED GENERATED
+show full columns from t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+a int(11) NULL NO NULL #
+b varchar(32) latin1_swedish_ci YES NULL #
+c int(11) NULL YES NULL VIRTUAL GENERATED #
+d varchar(5) latin1_swedish_ci YES NULL STORED GENERATED #
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,NULL);
+UPDATE IGNORE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+Warnings:
+Warning 1906 The value specified for generated column 'd' in table 't1' has been ignored
+INSERT IGNORE INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+Warnings:
+Warning 1906 The value specified for generated column 'd' in table 't1' has been ignored
+set sql_mode='strict_all_tables';
+UPDATE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+ERROR HY000: The value specified for generated column 'd' in table 't1' has been ignored
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+ERROR HY000: The value specified for generated column 'd' in table 't1' has been ignored
+drop table t1;
+#
+# MDEV-5611: self-referencing virtual column
+#
+create table t1 (a int, b int as (b is null) virtual);
+ERROR 01000: Expression for field `b` is referring to uninitialized field `b`
+create table t1 (a int as (1+1), b int as (a is null) virtual);
+drop table t1;
+# end of 5.3 tests
+create table t1 (v1 varchar(255) as (c1) persistent, c1 varchar(50)) collate=latin1_general_ci;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v1` varchar(255) GENERATED ALWAYS AS (`c1`) STORED,
+ `c1` varchar(50) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
+drop table t1;
+set sql_mode='no_zero_date';
+create table t1 (
+ts timestamp not null default current_timestamp,
+tsv timestamp as (adddate(ts, interval 1 day)) virtual
+);
+drop table t1;
+set sql_mode=default;
+#
+# MDEV-11819 NO_ZERO_IN_DATE: Incorrect generated column value
+#
+SET sql_mode='NO_ZERO_IN_DATE';
+CREATE TABLE t1
+(
+a datetime DEFAULT NULL,
+b datetime DEFAULT NULL,
+c time GENERATED ALWAYS AS (timediff(`a`,`b`)) VIRTUAL
+);
+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_mode=DEFAULT;
+#
+# MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
+#
+SHOW TABLES;
+Tables_in_test
+t1
+SHOW CREATE TABLE t1;
+ERROR HY000: Incorrect information in file: './test/t1.frm'
+ALTER TABLE t1;
+ERROR HY000: Incorrect information in file: './test/t1.frm'
+#
+# End of 5.5 tests
+#
+#
+# End of 10.0 tests
+#
+#
+# MDEV-8441 Bad SHOW CREATE TABLE output for a table with a virtual column
+#
+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 GENERATED ALWAYS AS (cast(`a` as datetime)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a DATETIME, b TIMESTAMP AS (TIMESTAMP(a)),c TIMESTAMP);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` datetime DEFAULT NULL,
+ `b` timestamp GENERATED ALWAYS AS (cast(`a` as datetime)) VIRTUAL,
+ `c` timestamp NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+#
+# MDEV-8839 COLUMN_GET() produces warnings with no data
+#
+SET @aaa= COLUMN_CREATE('price', _binary 0xF0F1F2F3F4F5F6F7);
+SELECT COLUMN_GET(@aaa, 'price' AS DECIMAL) aaa;
+aaa
+0
+Warnings:
+Warning 1918 Encountered illegal value '\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7' when converting to DECIMAL
+SELECT COLUMN_GET(@aaa, 'price' AS INT) aaa;
+aaa
+0
+Warnings:
+Warning 1918 Encountered illegal value '\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7' when converting to INT
+SELECT COLUMN_GET(@aaa, 'price' AS DOUBLE) aaa;
+aaa
+0
+Warnings:
+Warning 1918 Encountered illegal value '\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7' when converting to DOUBLE
+#
+# MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
+#
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (
+a INT NOT NULL DEFAULT 10,
+b INT AS (a+1) VIRTUAL
+) ENGINE=MyISAM;
+INSERT INTO t1 (b) VALUES (10);
+ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
+INSERT INTO t1 (b) VALUES (DEFAULT(a));
+ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
+INSERT INTO t1 (b) VALUES (DEFAULT);
+INSERT INTO t1 VALUES (10,10);
+ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
+INSERT INTO t1 VALUES (10,DEFAULT(a));
+ERROR HY000: The value specified for generated column 'b' in table 't1' has been ignored
+INSERT INTO t1 VALUES (10, DEFAULT);
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# End of 10.1 tests
+#
+#
+# MDEV-16518 MYSQL57_GENERATED_FIELD: The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
+#
+SHOW TABLES;
+Tables_in_test
+t1
+SHOW CREATE TABLE t1;
+ERROR HY000: Incorrect information in file: './test/t1.frm'
+ALTER TABLE t1;
+ERROR HY000: Incorrect information in file: './test/t1.frm'
+#
+# MDEV-19771 REPLACE on table with virtual_field can cause crash in set_ok_status()
+
+create or replace table t1 (pk int primary key, col_bit bit(15) default null,
+vcol_bit bit(10) GENERATED ALWAYS AS (`col_bit`) VIRTUAL);
+replace INTO `t1` (`pk`,col_bit) VALUES (99,1000);
+select pk, col_bit+0, vcol_bit+0 from t1;
+pk col_bit+0 vcol_bit+0
+99 1000 1000
+replace INTO `t1` (`pk`,col_bit) VALUES (99,10000);
+select pk, col_bit+0, vcol_bit+0 from t1;
+pk col_bit+0 vcol_bit+0
+99 10000 1023
+REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
+ERROR 22001: Data too long for column 'vcol_bit' at row 1
+drop table t1;
+#
+# MDEV-17837 REPLACE on table with virtual_field can cause crash in set_ok_status()
+#
+SET @old_sql_mode=@@sql_mode;
+SET sql_mode= STRICT_ALL_TABLES;
+CREATE TABLE t1 (
+pk INT,
+i TINYINT,
+vi TINYINT AS (i+1) PERSISTENT,
+PRIMARY KEY(pk)
+);
+INSERT INTO t1 (pk,i) VALUES (1,1);
+TRUNCATE TABLE t1;
+INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
+Warnings:
+Warning 1264 Out of range value for column 'vi' at row 1
+REPLACE INTO t1 (pk,i) VALUES (1,2);
+ERROR 22003: Out of range value for column 'vi' at row 1
+DROP TABLE t1;
+SET @sql_mode=@old_sql_mode;
+#
+# MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
+# 10.2+ specific part
+#
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (
+a INT NOT NULL DEFAULT 10,
+b INT AS (a+1) VIRTUAL
+) ENGINE=MyISAM;
+EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING DEFAULT;
+EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING IGNORE;
+INSERT INTO t1 (b) VALUES (DEFAULT);
+INSERT INTO t1 (b) VALUES (IGNORE);
+SELECT * FROM t1;
+a b
+10 11
+10 11
+10 11
+10 11
+DELETE FROM t1;
+EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(10,?)' USING DEFAULT;
+EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(11,?)' USING IGNORE;
+INSERT INTO t1 VALUES (12,DEFAULT);
+INSERT INTO t1 VALUES (13,IGNORE);
+SELECT * FROM t1;
+a b
+10 11
+11 12
+12 13
+13 14
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# CONTEXT_ANALYSIS_ONLY_VCOL_EXPR
+#
+call mtr.add_suppression("Charset id.*trying to replace");
+create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci,
+v1 char(1) character set ucs2 collate ucs2_test_ci as (c1),
+v2 int as (c1 = 'b'),
+v3 int as (v1 = 'b'));
+insert into t1 (c1) values ('a');
+select * from t1 where v1 = 'b';
+c1 v1 v2 v3
+a a 1 1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` char(1) CHARACTER SET ucs2 COLLATE ucs2_test_ci DEFAULT NULL,
+ `v1` char(1) CHARACTER SET ucs2 COLLATE ucs2_test_ci GENERATED ALWAYS AS (`c1`) VIRTUAL,
+ `v2` int(11) GENERATED ALWAYS AS (`c1` = 'b') VIRTUAL,
+ `v3` int(11) GENERATED ALWAYS AS (`v1` = 'b') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+#
+# End of 10.2 tests
+#
+#
+# RAND is session func
+#
+create table t1 (a int, b float default rand(1));
+insert into t1 (a) values (1);
+insert into t1 (a) values (2);
+insert into t1 (a) values (3);
+select * from t1;
+a b
+1 0.405404
+2 0.405404
+3 0.405404
+drop table t1;
+#
+# End of 10.3 tests
+#
+#
+# MDEV-31112 vcol circular references lead to stack overflow
+#
+create table t (a int, c int as (a));
+alter table t alter column c drop default;
+alter table t modify column a int as (c) stored;
+ERROR 01000: Expression for field `a` is referring to uninitialized field `c`
+drop table t;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result b/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result
new file mode 100644
index 00000000..93d912a1
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result
@@ -0,0 +1,258 @@
+SET @@session.default_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: This is not yet supported for generated columns
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) STORED
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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: This is not yet supported for generated columns
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 COLLATE=latin1_swedish_ci
+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 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (dayofyear(`b`)) VIRTUAL,
+ `b` datetime DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (dayofyear(`b`)) STORED,
+ `b` datetime DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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,0)) 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) GENERATED ALWAYS AS (week(`b`,1)) STORED
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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,0)));
+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) GENERATED ALWAYS AS (week(`b`,1)) VIRTUAL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+#
+# MDEV-6103 - Adding/removing non-materialized virtual column triggers
+# table recreation
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
+ALTER TABLE t1 ADD COLUMN b INT AS (a + 1) VIRTUAL;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+ALTER TABLE t1 DROP COLUMN b;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result b/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result
new file mode 100644
index 00000000..e0a009d4
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result
@@ -0,0 +1,258 @@
+SET @@session.default_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: This is not yet supported for generated columns
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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: This is not yet supported for generated columns
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` MOD 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 COLLATE=latin1_swedish_ci
+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 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (dayofyear(`b`)) VIRTUAL,
+ `b` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (dayofyear(`b`)) STORED,
+ `b` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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,0)) 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) GENERATED ALWAYS AS (week(`b`,1)) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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,0)));
+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) GENERATED ALWAYS AS (week(`b`,1)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+#
+# MDEV-6103 - Adding/removing non-materialized virtual column triggers
+# table recreation
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
+ALTER TABLE t1 ADD COLUMN b INT AS (a + 1) VIRTUAL;
+affected rows: 10
+info: Records: 10 Duplicates: 0 Warnings: 0
+ALTER TABLE t1 DROP COLUMN b;
+affected rows: 10
+info: Records: 10 Duplicates: 0 Warnings: 0
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/r/vcol_partition_innodb.result b/mysql-test/suite/vcol/r/vcol_partition_innodb.result
new file mode 100644
index 00000000..c25fc7b2
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_partition_innodb.result
@@ -0,0 +1,89 @@
+SET @@session.default_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);
+insert into t1 (a) values ('2007-01-02');
+select * from t1;
+a b
+2005-01-01 2005
+2006-01-01 2006
+2007-01-01 2007
+2007-01-02 2007
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 1 16384
+p2 3 16384
+# 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
+2007-01-02 2006
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 2 16384
+p2 2 16384
+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 partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p1 0 16384
+p2 1 16384
+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
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 0 16384
+p1 1 16384
+p2 1 16384
+# 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
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 1 16384
+p1 1 16384
+p2 0 16384
+drop table t1;
+create table t1 (a int, b datetime as (now())) partition by hash(b+1) partitions 3;
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+create table t1 (a int, b varchar(100) as (user())) partition by hash(b+1) partitions 3;
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+create table t1 (a int, b double as (rand())) partition by hash(b+1) partitions 3;
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
diff --git a/mysql-test/suite/vcol/r/vcol_partition_myisam.result b/mysql-test/suite/vcol/r/vcol_partition_myisam.result
new file mode 100644
index 00000000..a7733ddf
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_partition_myisam.result
@@ -0,0 +1,89 @@
+SET @@session.default_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);
+insert into t1 (a) values ('2007-01-02');
+select * from t1;
+a b
+2005-01-01 2005
+2006-01-01 2006
+2007-01-01 2007
+2007-01-02 2007
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 1 7
+p2 3 21
+# 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
+2007-01-02 2006
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 2 14
+p2 2 14
+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 partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p1 0 0
+p2 1 9
+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
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 0 0
+p1 1 7
+p2 1 7
+# 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
+select partition_name,table_rows,data_length from information_schema.partitions where table_name = 't1';
+partition_name table_rows data_length
+p0 1 7
+p1 1 7
+p2 0 0
+drop table t1;
+create table t1 (a int, b datetime as (now())) partition by hash(b+1) partitions 3;
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+create table t1 (a int, b varchar(100) as (user())) partition by hash(b+1) partitions 3;
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+create table t1 (a int, b double as (rand())) partition by hash(b+1) partitions 3;
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result
new file mode 100644
index 00000000..40308b6e
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result
@@ -0,0 +1,270 @@
+SET @@session.default_storage_engine = 'InnoDB';
+SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent=0;
+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),(5),(4),(7);
+# 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
+# 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 index condition
+# 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
+# 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
+1 PRIMARY t3 eq_ref c c 5 test.t1.b 1 Using index
+# 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 t3 range c c 5 NULL 2 Using where; Using index
+1 PRIMARY t1 ref c c 5 test.t3.c 1
+# 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
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+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
+set optimizer_switch=@tmp_optimizer_switch;
+###
+### 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 range NULL c 5 NULL 6 Using index for group-by
+###
+### 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 index condition
+# 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 2 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 6 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 2 Using index condition
+# 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 2 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 2 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 6 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 6 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 2 Using index condition; 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 6 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 2 Using index condition
+# 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
+SET GLOBAL innodb_stats_persistent=@save_stats_persistent;
diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result
new file mode 100644
index 00000000..05f86347
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result
@@ -0,0 +1,515 @@
+SET @@session.default_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),(5),(4),(7);
+# 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 1 Using index condition
+# 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
+# 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
+1 PRIMARY t3 eq_ref c c 5 test.t1.b 1 Using index
+# 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 t3 range c c 5 NULL 2 Using where; Using index
+1 PRIMARY t1 ref c c 5 test.t3.c 2
+# 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
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+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
+set optimizer_switch=@tmp_optimizer_switch;
+###
+### 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 range NULL c 5 NULL 6 Using index for group-by
+###
+### 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 index condition
+# 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 2 Using index condition
+# 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 6 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 2 Using index condition
+# 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 2 Using index condition; 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 6 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 2 Using index condition; 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 6 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 2 Using index condition; 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 6 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 2 Using index condition
+# 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
+#
+# Bug #806057: join with USING over a virtual column
+#
+CREATE TABLE t1 (b int);
+INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154);
+CREATE TABLE t2 (a int, b int AS (a) VIRTUAL);
+INSERT IGNORE INTO t2 VALUES (187,187), (9,9), (187,187);
+Warnings:
+Warning 1906 The value specified for generated column 'b' in table 't2' has been ignored
+Warning 1906 The value specified for generated column 'b' in table 't2' has been ignored
+Warning 1906 The value specified for generated column 'b' in table 't2' has been ignored
+EXPLAIN EXTENDED
+SELECT * FROM t1 JOIN t2 USING (b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`b` = `test`.`t2`.`b`
+SELECT * FROM t1 JOIN t2 USING (b);
+b a
+EXPLAIN EXTENDED
+SELECT * FROM t1 NATURAL JOIN t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`b` = `test`.`t2`.`b`
+SELECT * FROM t1 NATURAL JOIN t2;
+b a
+DROP TABLE t1,t2;
+create table t1 (
+pk integer auto_increment,
+bi integer not null,
+vi integer generated always as (bi) persistent,
+bc varchar(1) not null,
+vc varchar(2) generated always as (concat(bc, bc)) persistent,
+primary key (pk),
+key (vi, vc));
+insert t1 (bi, bc) values (0, 'x'), (0, 'n'), (1, 'w'), (7, 's'), (0, 'a'), (4, 'd'), (1, 'w'), (1, 'j'), (1, 'm'), (4, 'k'), (7, 't'), (4, 'k'), (2, 'e'), (0, 'i'), (1, 't'), (6, 'z'), (3, 'c'), (6, 'i'), (8, 'v');
+create table t2 (
+pk integer auto_increment,
+bi integer not null,
+vi integer generated always as (bi) persistent,
+bc varchar(257) not null,
+vc varchar(2) generated always as (concat(bc, bc)) persistent,
+primary key (pk),
+key (vi, vc));
+insert t2 (bi, bc) values (1, 'c'), (8, 'm'), (9, 'd'), (6, 'y'), (1, 't'), (6, 'd'), (2, 's'), (4, 'r'), (8, 'm'), (4, 'b'), (4, 'x'), (7, 'g'), (4, 'p'), (1, 'q'), (9, 'w'), (4, 'd'), (8, 'e'), (4, 'b'), (8, 'y');
+explain # should be using join buffer
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL vi 10 NULL 19 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 19 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 index NULL PRIMARY 4 NULL 19 Using where; Using index; Using join buffer (incremental, BNL join)
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+vi
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+2
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+6
+6
+6
+6
+7
+7
+8
+8
+8
+8
+9
+9
+drop table t2,t1;
+create table t1 (
+pk integer auto_increment,
+bi integer not null,
+vi integer generated always as (bi) virtual,
+bc varchar(1) not null,
+vc varchar(2) generated always as (concat(bc, bc)),
+primary key (pk),
+key (vi, vc));
+insert t1 (bi, bc) values (0, 'x'), (0, 'n'), (1, 'w'), (7, 's'), (0, 'a'), (4, 'd'), (1, 'w'), (1, 'j'), (1, 'm'), (4, 'k'), (7, 't'), (4, 'k'), (2, 'e'), (0, 'i'), (1, 't'), (6, 'z'), (3, 'c'), (6, 'i'), (8, 'v');
+create table t2 (
+pk integer auto_increment,
+bi integer not null,
+vi integer generated always as (bi) virtual,
+bc varchar(257) not null,
+vc varchar(2) generated always as (concat(bc, bc)),
+primary key (pk),
+key (vi, vc));
+insert t2 (bi, bc) values (1, 'c'), (8, 'm'), (9, 'd'), (6, 'y'), (1, 't'), (6, 'd'), (2, 's'), (4, 'r'), (8, 'm'), (4, 'b'), (4, 'x'), (7, 'g'), (4, 'p'), (1, 'q'), (9, 'w'), (4, 'd'), (8, 'e'), (4, 'b'), (8, 'y');
+explain # should be using join buffer
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL vi 10 NULL 19 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 19 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 index NULL PRIMARY 4 NULL 19 Using where; Using index; Using join buffer (incremental, BNL join)
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+vi
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+2
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+6
+6
+6
+6
+7
+7
+8
+8
+8
+8
+9
+9
+drop table t2,t1;
diff --git a/mysql-test/suite/vcol/r/vcol_sql_mode.result b/mysql-test/suite/vcol/r/vcol_sql_mode.result
new file mode 100644
index 00000000..fdbc8c6a
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_sql_mode.result
@@ -0,0 +1,434 @@
+#
+# Start of 10.2 tests
+#
+#
+# MDEV-18156 Assertion `0' failed or `btr_validate_index(index, 0, false)' in row_upd_sec_index_entry or error code 126: Index is corrupted upon DELETE with PAD_CHAR_TO_FULL_LENGTH
+#
+#
+# PAD_CHAR_TO_FULL_LENGTH + various virtual column data types
+#
+CREATE TABLE t1 (a CHAR(5), v CHAR(5) AS (a) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` char(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v INT AS (a) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v TIME AS (a) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (c CHAR(8), v BINARY(8) AS (c), KEY(v));
+ERROR HY000: Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v BIT(64) AS (a) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (a) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (a) VIRTUAL, KEY(v(100)));
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# PAD_CHAR_TO_FULL_LENGTH + TRIM resolving dependency
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RTRIM(a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (RTRIM(a)) VIRTUAL, KEY(v(100)));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` text GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL,
+ KEY `v` (`v`(100))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING ' ' FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (trim(trailing ' ' from `a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (TRIM(TRAILING ' ' FROM a)) VIRTUAL, KEY(v(100)));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` text GENERATED ALWAYS AS (trim(trailing ' ' from `a`)) VIRTUAL,
+ KEY `v` (`v`(100))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH ' ' FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (trim(both ' ' from `a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (TRIM(BOTH ' ' FROM a)) VIRTUAL, KEY(v(100)));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` text GENERATED ALWAYS AS (trim(both ' ' from `a`)) VIRTUAL,
+ KEY `v` (`v`(100))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING NULL FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (trim(trailing NULL from `a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH NULL FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (trim(both NULL from `a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+# PAD_CHAR_TO_FULL_LENGTH + TRIM not resolving dependency
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(LEADING ' ' FROM a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'trim(leading ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(leading ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (TRIM(LEADING ' ' FROM a)) VIRTUAL, KEY(v(100)));
+ERROR HY000: Function or expression 'trim(leading ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(leading ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING '' FROM a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'trim(trailing '' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(trailing '' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH '' FROM a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'trim(both '' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(both '' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING 'x' FROM a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'trim(trailing 'x' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(trailing 'x' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH 'x' FROM a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'trim(both 'x' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(both 'x' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (
+a CHAR(5),
+v VARCHAR(5) AS (TRIM(TRAILING ' ' FROM a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'trim(trailing ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(trailing ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (
+a CHAR(5),
+v VARCHAR(5) AS (TRIM(BOTH ' ' FROM a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'trim(both ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(both ' ' from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# PAD_CHAR_TO_FULL_LENGTH + TRIM(... non_constant FROM a)
+CREATE TABLE t1 (
+a CHAR(5),
+b CHAR(5),
+v TEXT AS (TRIM(TRAILING b FROM a)) VIRTUAL, KEY(v(100)));
+ERROR HY000: Function or expression 'trim(trailing `b` from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'trim(trailing `b` from `a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# PAD_CHAR_TO_FULL_LENGTH + RPAD resolving dependency
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,5,' ')) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rpad(`a`,5,' ')) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,6,' ')) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rpad(`a`,6,' ')) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,6,NULL)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rpad(`a`,6,NULL)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,NULL,' ')) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rpad(`a`,NULL,' ')) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+# PAD_CHAR_TO_FULL_LENGTH + RPAD not resolving dependency
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,4,' ')) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'rpad(`a`,4,' ')' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'rpad(`a`,4,' ')' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (
+a CHAR(5),
+b CHAR(5),
+v VARCHAR(5) AS (RPAD(a,NULL,b)) VIRTUAL,
+KEY(v)
+);
+ERROR HY000: Function or expression 'rpad(`a`,NULL,`b`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'rpad(`a`,NULL,`b`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# PAD_CHAR_TO_FULL_LENGTH + comparison
+CREATE TABLE t1 (a CHAR(5), v INT AS (a='a') VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` int(11) GENERATED ALWAYS AS (`a` = 'a') VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (
+a CHAR(5) CHARACTER SET latin1 COLLATE latin1_nopad_bin,
+v INT AS (a='a') VIRTUAL, KEY(v)
+);
+ERROR HY000: Function or expression '`a` = 'a'' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a` = 'a'' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# PAD_CHAR_TO_FULL_LENGTH + LIKE
+CREATE TABLE t1 (a CHAR(5), v INT AS (a LIKE 'a%') VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` int(11) GENERATED ALWAYS AS (`a` like 'a%') VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v INT AS (a LIKE NULL) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` int(11) GENERATED ALWAYS AS (`a` like NULL) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), v INT AS (a LIKE 'a') VIRTUAL, KEY(v));
+ERROR HY000: Function or expression '`a` like 'a'' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a` like 'a'' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# PAD_CHAR_TO_FULL_LENGTH + LENGTH(char_column) = hard dependency
+CREATE TABLE t1 (a CHAR(5), v INT AS (LENGTH(a)) VIRTUAL, KEY(v));
+ERROR HY000: Function or expression 'octet_length(`a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'octet_length(`a`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+#
+# Testing NO_UNSIGNED_SUBTRACTION
+#
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c INT GENERATED ALWAYS AS (a-b) VIRTUAL,
+KEY (c)
+);
+ERROR HY000: Function or expression '`a` - `b`' cannot be used in the GENERATED ALWAYS AS clause of `c`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a` - `b`' cannot be used in the GENERATED ALWAYS AS clause of `c`
+Warning 1105 Expression depends on the @@sql_mode value NO_UNSIGNED_SUBTRACTION
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c INT GENERATED ALWAYS AS (CAST(a AS SIGNED)-b) VIRTUAL,
+KEY (c)
+);
+ERROR HY000: Function or expression 'cast(`a` as signed) - `b`' cannot be used in the GENERATED ALWAYS AS clause of `c`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'cast(`a` as signed) - `b`' cannot be used in the GENERATED ALWAYS AS clause of `c`
+Warning 1105 Expression depends on the @@sql_mode value NO_UNSIGNED_SUBTRACTION
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c INT GENERATED ALWAYS AS (a-CAST(b AS SIGNED)) VIRTUAL,
+KEY (c)
+);
+ERROR HY000: Function or expression '`a` - cast(`b` as signed)' cannot be used in the GENERATED ALWAYS AS clause of `c`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a` - cast(`b` as signed)' cannot be used in the GENERATED ALWAYS AS clause of `c`
+Warning 1105 Expression depends on the @@sql_mode value NO_UNSIGNED_SUBTRACTION
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c INT GENERATED ALWAYS AS (CAST(a AS SIGNED)-CAST(b AS SIGNED)) VIRTUAL,
+KEY (c)
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(10) unsigned DEFAULT NULL,
+ `b` int(10) unsigned DEFAULT NULL,
+ `c` int(11) GENERATED ALWAYS AS (cast(`a` as signed) - cast(`b` as signed)) VIRTUAL,
+ KEY `c` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c INT GENERATED ALWAYS AS (CAST(a AS DECIMAL(20,0))-CAST(b AS DECIMAL(20,0))) VIRTUAL,
+KEY (c)
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(10) unsigned DEFAULT NULL,
+ `b` int(10) unsigned DEFAULT NULL,
+ `c` int(11) GENERATED ALWAYS AS (cast(`a` as decimal(20,0)) - cast(`b` as decimal(20,0))) VIRTUAL,
+ KEY `c` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+#
+# Comnination: PAD_CHAR_TO_FULL_LENGTH + NO_UNSIGNED_SUBTRACTION
+#
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c CHAR(5),
+v VARCHAR(5) GENERATED ALWAYS AS (RPAD(c,a-b,' ')) VIRTUAL,
+KEY (v)
+);
+ERROR HY000: Function or expression 'rpad(`c`,`a` - `b`,' ')' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'rpad(`c`,`a` - `b`,' ')' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value NO_UNSIGNED_SUBTRACTION
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c CHAR(5),
+v VARCHAR(5) GENERATED ALWAYS AS (RPAD(c,CAST(a AS DECIMAL(20,1))-b,' ')) VIRTUAL,
+KEY (v)
+);
+ERROR HY000: Function or expression 'rpad(`c`,cast(`a` as decimal(20,1)) - `b`,' ')' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression 'rpad(`c`,cast(`a` as decimal(20,1)) - `b`,' ')' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# ALTER TABLE ADD KEY(vcol_depending_on_sql_mode) --> error
+CREATE TABLE t1 (
+a INT UNSIGNED,
+b INT UNSIGNED,
+c CHAR(5),
+v VARCHAR(5) GENERATED ALWAYS AS (c) VIRTUAL
+);
+ALTER TABLE t1 ADD KEY(v);
+ERROR HY000: Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE INDEX v ON t1 (v);
+ERROR HY000: Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+DROP TABLE t1;
+# A virtual column on the second position in an index - cannot depend on sql_mode
+CREATE TABLE t1 (id int, a CHAR(5), v TEXT AS (a) VIRTUAL, KEY(id, v(100)));
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+# A persisten virtual column cannot depend on sql_mode
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (a) PERSISTENT);
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RTRIM(a)) PERSISTENT);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+#
+# End of 10.2 tests
+#
diff --git a/mysql-test/suite/vcol/r/vcol_sql_mode_datetime.result b/mysql-test/suite/vcol/r/vcol_sql_mode_datetime.result
new file mode 100644
index 00000000..3033ffb6
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_sql_mode_datetime.result
@@ -0,0 +1,113 @@
+#
+# Start of 10.4 tests
+#
+#
+# MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
+#
+SET sql_mode=DEFAULT;
+# OK: same FSP + virtual index
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(4) AS (t) VIRTUAL,
+KEY(v,d)
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+KEY(v,d)
+);
+DROP TABLE t1;
+# OK: lower FSP + no virtual index
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(3) AS (t) VIRTUAL
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
+);
+DROP TABLE t1;
+# NOT OK: lower FSP + virtual index
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(3) AS (t) VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression '`t`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(3) AS (COALESCE(t)) VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression 'coalesce(`t`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression ''2001-01-01 10:20:30.1234'' cannot be used in the GENERATED ALWAYS AS clause of `v`
+# OK: lower FSP + ROUND + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(3) AS (ROUND(t,3)) VIRTUAL,
+KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+t d v
+2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.050
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+# OK: lower FSP + TRUNCATE + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+t DATETIME(4),
+d DATETIME,
+v DATETIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
+KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+t d v
+2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.049
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# MDEV-20423 Assertion `0' failed or `btr_validate_index(index, 0, false)' in row_upd_sec_index_entry or error code 126: Index is corrupted upon DELETE with TIME_ROUND_FRACTIONAL
+#
+CREATE TABLE t1 (
+a DATETIME(6),
+v VARCHAR(30) GENERATED ALWAYS AS (CAST(a AS DATETIME(3))) VIRTUAL,
+KEY (v)
+);
+ERROR HY000: Function or expression 'cast(`a` as datetime(3))' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+a DATETIME(6),
+v VARCHAR(30) GENERATED ALWAYS AS (TRUNCATE(a,3)) VIRTUAL,
+KEY (v)
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+a DATETIME(6),
+v VARCHAR(30) GENERATED ALWAYS AS (ROUND(a,3)) VIRTUAL,
+KEY (v)
+);
+DROP TABLE t1;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/suite/vcol/r/vcol_sql_mode_time.result b/mysql-test/suite/vcol/r/vcol_sql_mode_time.result
new file mode 100644
index 00000000..300b9172
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_sql_mode_time.result
@@ -0,0 +1,113 @@
+#
+# Start of 10.4 tests
+#
+#
+# MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
+#
+SET sql_mode=DEFAULT;
+# OK: same FSP + virtual index
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(4) AS (t) VIRTUAL,
+KEY(v,d)
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(4) AS ('10:20:30.1234') VIRTUAL,
+KEY(v,d)
+);
+DROP TABLE t1;
+# OK: lower FSP + no virtual index
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(3) AS (t) VIRTUAL
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
+);
+DROP TABLE t1;
+# NOT OK: lower FSP + virtual index
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(3) AS (t) VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression '`t`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(3) AS (COALESCE(t)) VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression 'coalesce(`t`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression ''2001-01-01 10:20:30.1234'' cannot be used in the GENERATED ALWAYS AS clause of `v`
+# OK: lower FSP + ROUND + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(3) AS (ROUND(t,3)) VIRTUAL,
+KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
+SELECT * FROM t1;
+t d v
+12:44:34.0496 21:27:53 12:44:34.050
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = CURRENT_TIME;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+# OK: lower FSP + TRUNCATE + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+t TIME(4),
+d TIME,
+v TIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
+KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
+SELECT * FROM t1;
+t d v
+12:44:34.0496 21:27:53 12:44:34.049
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = CURRENT_TIME;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# MDEV-20423 Assertion `0' failed or `btr_validate_index(index, 0, false)' in row_upd_sec_index_entry or error code 126: Index is corrupted upon DELETE with TIME_ROUND_FRACTIONAL
+#
+CREATE TABLE t1 (
+a TIME(6),
+v VARCHAR(30) GENERATED ALWAYS AS (CAST(a AS TIME(3))) VIRTUAL,
+KEY (v)
+);
+ERROR HY000: Function or expression 'cast(`a` as time(3))' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+a TIME(6),
+v VARCHAR(30) GENERATED ALWAYS AS (TRUNCATE(a,3)) VIRTUAL,
+KEY (v)
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+a TIME(6),
+v VARCHAR(30) GENERATED ALWAYS AS (ROUND(a,3)) VIRTUAL,
+KEY (v)
+);
+DROP TABLE t1;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/suite/vcol/r/vcol_sql_mode_timestamp.result b/mysql-test/suite/vcol/r/vcol_sql_mode_timestamp.result
new file mode 100644
index 00000000..df1cee04
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_sql_mode_timestamp.result
@@ -0,0 +1,107 @@
+#
+# Start of 10.4 tests
+#
+#
+# MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
+#
+SET sql_mode=DEFAULT;
+# OK: same FSP + virtual index
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(4) AS (t) VIRTUAL,
+KEY(v,d)
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+KEY(v,d)
+);
+DROP TABLE t1;
+# OK: lower FSP + no virtual index
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(3) AS (t) VIRTUAL
+);
+DROP TABLE t1;
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
+);
+DROP TABLE t1;
+# NOT OK: lower FSP + virtual index
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(3) AS (t) VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression '`t`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(3) AS (COALESCE(t)) VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression 'coalesce(`t`)' cannot be used in the GENERATED ALWAYS AS clause of `v`
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+KEY(v,d)
+);
+ERROR HY000: Function or expression ''2001-01-01 10:20:30.1234'' cannot be used in the GENERATED ALWAYS AS clause of `v`
+# OK: lower FSP + ROUND + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(3) AS (ROUND(t,3)) VIRTUAL,
+KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+t d v
+2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.050
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+# OK: lower FSP + TRUNCATE + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+t TIMESTAMP(4),
+d DATETIME,
+v TIMESTAMP(3) AS (TRUNCATE(t,3)) VIRTUAL,
+KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+t d v
+2006-03-01 12:44:34.0496 2029-10-10 21:27:53 2006-03-01 12:44:34.049
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# MDEV-20639 ASAN SEGV in get_prefix upon modifying base column type with existing indexed virtual column
+#
+CREATE TABLE t1 (
+a TIMESTAMP,
+b TIMESTAMP AS (a) VIRTUAL,
+KEY (b)
+);
+ALTER TABLE t1 MODIFY a BLOB FIRST;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `b`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `b`
+Warning 1105 Expression depends on the @@sql_mode value TIME_ROUND_FRACTIONAL
+DROP TABLE t1;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result b/mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result
new file mode 100644
index 00000000..1890e090
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result
@@ -0,0 +1,345 @@
+call mtr.add_suppression("Table rebuild required");
+#
+# Opening a Maria-10.2.26 table with a stored VARCHAR column
+#
+# Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+FLUSH TABLES;
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 ADD b INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+FLUSH TABLES;
+ALTER TABLE t1 ADD c INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+DROP TABLE t1;
+#
+# Fixing a Maria-10.2.26 table with a stored VARCHAR column
+#
+# Fixing by dropping the generated stored column
+# Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+ALTER TABLE t1 DROP v;
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SELECT * FROM t1;
+a
+1
+2
+3
+DROP TABLE t1;
+# Fixing by altering the generation expression of the stored column
+# Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS (RTRIM(a)) PERSISTENT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t1;
+#
+# Opening a Maria-10.2.26 table with a virtual VARCHAR column
+#
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+FLUSH TABLES;
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 ADD b INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+FLUSH TABLES;
+ALTER TABLE t1 ADD c INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+DROP TABLE t1;
+#
+# Fixing a Maria-10.2.26 table with a virtual VARCHAR column
+#
+# Fixing by dropping the virtual column
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 DROP v;
+SELECT * FROM t1;
+a
+1
+2
+3
+DROP TABLE t1;
+# Fixing by dropping a key on a virtual column, using ALTER TABLE
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 DROP KEY v;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+DROP TABLE t1;
+# Fixing by dropping a key on a virtual column, using DROP INDEX
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+DROP INDEX v ON t1;
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+DROP TABLE t1;
+# Fixing by altering the generation expression of a virtual column
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS(RTRIM(a)) VIRTUAL;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Upgrading a Maria-10.2.26 table with a stored column
+#
+# Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+DROP TABLE t1;
+#
+# Upgrading a Maria-10.2.26 table with a virtual column
+#
+# Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result
new file mode 100644
index 00000000..99d8dea3
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result
@@ -0,0 +1,2956 @@
+SET @@session.default_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) GENERATED ALWAYS AS (abs(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (format(acos(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1, default);
+insert ignore 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 GENERATED ALWAYS AS (format(asin(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (0.2, default);
+insert ignore 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 GENERATED ALWAYS AS (format(atan(`a`,`b`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-2,2,default);
+insert ignore 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 GENERATED ALWAYS AS (format(atan(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-2,default);
+insert ignore 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 GENERATED ALWAYS AS (format(atan(`a`,`b`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-2,2,default);
+insert ignore 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) GENERATED ALWAYS AS (ceiling(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1.23,default);
+insert ignore 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) GENERATED ALWAYS AS (conv(`a`,`b`,`c`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('a',16,2,default);
+insert ignore 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 GENERATED ALWAYS AS (format(cos(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (format(cot(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (12,default);
+insert ignore into t1 values (1,default);
+select * from t1;
+a b
+12 -1.572673
+1 0.642093
+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 GENERATED ALWAYS AS (crc32(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('MySQL',default);
+insert ignore 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 GENERATED ALWAYS AS (format(degrees(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (format(PI(),6),default);
+insert ignore 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 GENERATED ALWAYS AS (`a` / 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (format(exp(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (2,default);
+insert ignore 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 GENERATED ALWAYS AS (floor(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1.23,default);
+insert ignore 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 GENERATED ALWAYS AS (format(ln(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (2,default);
+insert ignore into t1 values (-2,default);
+Warnings:
+Warning 1365 Division by 0
+select * from t1;
+a b
+2 0.693147
+-2 NULL
+Warnings:
+Warning 1365 Division by 0
+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 GENERATED ALWAYS AS (format(log(`a`,`b`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (2,65536,default);
+insert ignore into t1 values (10,100,default);
+insert into t1 values (1,100,default);
+Warnings:
+Warning 1365 Division by 0
+select * from t1;
+a b c
+2 65536 16
+10 100 2
+1 100 NULL
+Warnings:
+Warning 1365 Division by 0
+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 GENERATED ALWAYS AS (format(log(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (2,default);
+insert ignore into t1 values (-2,default);
+Warnings:
+Warning 1365 Division by 0
+select * from t1;
+a b
+2 0.693147
+-2 NULL
+Warnings:
+Warning 1365 Division by 0
+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 GENERATED ALWAYS AS (format(log2(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (65536,default);
+insert ignore into t1 values (-100,default);
+Warnings:
+Warning 1365 Division by 0
+select * from t1;
+a b
+65536 16
+-100 NULL
+Warnings:
+Warning 1365 Division by 0
+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 GENERATED ALWAYS AS (format(log10(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (2,default);
+insert ignore into t1 values (100,default);
+insert into t1 values (-100,default);
+Warnings:
+Warning 1365 Division by 0
+select * from t1;
+a b
+2 0.30103
+100 2
+-100 NULL
+Warnings:
+Warning 1365 Division by 0
+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 GENERATED ALWAYS AS (`a` - 1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` MOD 10) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` MOD 10) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (conv(`a`,10,8)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (format(pi() * `a` * `a`,6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` + 1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (pow(`a`,2)) VIRTUAL,
+ `c` int(11) GENERATED ALWAYS AS (pow(`a`,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default,default);
+insert ignore 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 GENERATED ALWAYS AS (format(radians(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (round(`a`,0)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-1.23,default);
+insert ignore 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) GENERATED ALWAYS AS (round(`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1.298,1,default);
+insert ignore 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) GENERATED ALWAYS AS (sign(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-32,default);
+insert ignore 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 GENERATED ALWAYS AS (format(sin(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (format(sqrt(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (4,default);
+insert ignore 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 GENERATED ALWAYS AS (format(tan(`a`),6)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (format(PI(),6),default);
+insert ignore 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 GENERATED ALWAYS AS (`a` * 3) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (0,default);
+insert ignore 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 GENERATED ALWAYS AS (truncate(`a`,4)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1.223,default);
+insert ignore 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 GENERATED ALWAYS AS (-`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (ascii(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2',default);
+insert ignore 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) GENERATED ALWAYS AS (conv(`a`,10,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (bit_length(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (char_length(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (char(`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (char_length(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (concat_ws(',',`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (concat(`a`,',',`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (elt(`c`,`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('value1','value2',1,default);
+insert ignore 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) GENERATED ALWAYS AS (export_set(`a`,'1','0','',10)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (field('aa',`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('aa','bb',default);
+insert ignore 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) GENERATED ALWAYS AS (find_in_set(`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('aa','aa,bb,cc',default);
+insert ignore 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) GENERATED ALWAYS AS (format(`a`,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (hex(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (hex(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (insert(`a`,octet_length(`a`),octet_length(`b`),`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (locate(`b`,`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('foobarbar,','bar',default);
+insert ignore 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) GENERATED ALWAYS AS (lcase(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (left(`a`,5)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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' escape '!'));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(10) DEFAULT NULL,
+ `b` tinyint(1) GENERATED ALWAYS AS (`a` like 'H%!o' escape '!') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('Hello',default);
+insert ignore 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) GENERATED ALWAYS AS (locate('bar',`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (lcase(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (lpad(`a`,4,' ')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('MySQL',default);
+insert ignore 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) GENERATED ALWAYS AS (ltrim(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (' MySQL',default);
+insert ignore 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) GENERATED ALWAYS AS (make_set(`c`,`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('a','b',1,default);
+insert ignore 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) GENERATED ALWAYS AS (substr(`a`,1,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` not like 'H%o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('Hello',default);
+insert ignore 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) GENERATED ALWAYS AS (!(`a` regexp 'H.+o')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('Hello',default);
+insert ignore 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) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (ord(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (locate('bar',`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (quote(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` regexp 'H.+o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('Hello',default);
+insert ignore 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) GENERATED ALWAYS AS (repeat(`a`,3)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (replace(`a`,'aa','bb')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (reverse(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (right(`a`,4)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` regexp 'H.+o') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('Hello',default);
+insert ignore 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) GENERATED ALWAYS AS (rpad(`a`,4,'??')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (soundex(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (soundex(`a`) = soundex(`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('Hello','Hello',default);
+insert ignore 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) GENERATED ALWAYS AS (concat(`a`,space(5))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (strcmp(`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('Hello','Hello', default);
+insert ignore 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) GENERATED ALWAYS AS (substr(`a`,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (substring_index(`a`,'.',2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (substr(`a`,2,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (trim(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (ucase(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (unhex(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (ucase(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (case `a` when NULL then 'asd' when 'b' then 'B' else `a` end) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (NULL,default);
+insert ignore 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) GENERATED ALWAYS AS (if(`a` = 1,`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,2,default);
+insert ignore 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) GENERATED ALWAYS AS (ifnull(`a`,'DEFAULT')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (NULL,'adf',default);
+insert ignore 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) GENERATED ALWAYS AS (nullif(`a`,'DEFAULT')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('DEFAULT',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` > 0 and `a` < 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-1,default);
+insert ignore 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) GENERATED ALWAYS AS (cast(`a` as char charset binary)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('11',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` & 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (~`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` | 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` ^ 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` DIV 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` <=> `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` = `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('a','b',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` >= `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('a','b',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` > `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('a','b',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` is not null) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` is null) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` << 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` <= `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('b','a',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` < `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('b','a',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` not between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (-1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` <> `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('b','a',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` <> `b`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('b','a',default);
+insert ignore 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) GENERATED ALWAYS AS (`a` > 5 or `a` < 3) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` >> 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (8,default);
+insert ignore 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) GENERATED ALWAYS AS (`a` xor 5) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (0,default);
+insert ignore 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 GENERATED ALWAYS AS (`a` + interval 1 month) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (addtime(`a`,'02:00:00')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (convert_tz(`a`,'MET','UTC')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (`a` + interval 1 month) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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_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 GENERATED ALWAYS AS (`a` - interval 1 month) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (cast(`a` as date)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (to_days(`a`) - to_days('2000-01-01')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (dayofmonth(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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;
+# 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) GENERATED ALWAYS AS (dayofmonth(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (dayofweek(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (dayofyear(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (extract(year from `a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 DEFAULT NULL,
+ `b` datetime GENERATED ALWAYS AS (from_days(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 time_zone='UTC';
+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 DEFAULT NULL,
+ `b` datetime GENERATED ALWAYS AS (from_unixtime(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1196440219,default);
+select * from t1;
+a b
+1196440219 2007-11-30 16:30:19
+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 GENERATED ALWAYS AS (hour(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (last_day(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2003-02-05',default);
+insert ignore into t1 values ('2003-02-32',default);
+Warnings:
+Warning 1265 Data truncated 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 GENERATED ALWAYS AS (makedate(`a`,1)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (maketime(`a`,1,3)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (microsecond(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2009-12-31 12:00:00.123456',default);
+insert ignore 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) GENERATED ALWAYS AS (minute(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (month(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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;
+# 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) GENERATED ALWAYS AS (period_add(`a`,2)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (period_diff(`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (quarter(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 DEFAULT NULL,
+ `b` time GENERATED ALWAYS AS (sec_to_time(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (second(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (str_to_date(`a`,'%m/%d/%Y')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (`a` - interval 1 month) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (subtime(`a`,'02:00:00')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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_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 GENERATED ALWAYS AS (time_to_sec(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (cast(`a` as time)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (timediff(`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (cast(`a` as datetime)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (`a` + interval 1 minute) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 NULL DEFAULT NULL,
+ `b` timestamp NULL DEFAULT NULL,
+ `c` mediumtext GENERATED ALWAYS AS (timestampdiff(MONTH,`a`,`b`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (to_days(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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,0)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` datetime DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (week(`a`,0)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (weekday(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (week(`a`,3)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (year(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (yearweek(`a`,0)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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 GENERATED ALWAYS AS (cast(`a` as unsigned)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore into t1 values (-1,default);
+Warnings:
+Note 1105 Cast to unsigned converted negative integer to it's positive complement
+select * from t1;
+a b
+1 1
+-1 18446744073709551615
+Warnings:
+Note 1105 Cast to unsigned converted negative integer to it's positive complement
+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 GENERATED ALWAYS AS (cast(`a` as unsigned)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (1,default);
+insert ignore into t1 values (-1,default);
+Warnings:
+Note 1105 Cast to unsigned converted negative integer to it's positive complement
+select * from t1;
+a b
+1 1
+-1 18446744073709551615
+Warnings:
+Note 1105 Cast to unsigned converted negative integer to it's positive complement
+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) GENERATED ALWAYS AS (aes_encrypt(aes_decrypt(`a`,'adf'),'adf')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (bit_count(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values (5,default);
+select * from t1;
+a b
+5 2
+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) GENERATED ALWAYS AS (uncompress(compress(`a`))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (decode(encode(`a`,'abc'),'abc')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (ifnull(`a`,default(`a`))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (inet_ntoa(inet_aton(`a`))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (md5(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (old_password(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (password(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (sha(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (sha(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (uncompressed_length(compress(repeat(`a`,30)))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('a',default);
+select * from t1;
+a b
+a 30
+drop table t1;
+set sql_warnings = 0;
+# MONTHNAME()
+set sql_warnings = 1;
+create table t1 (a date, b varchar(100) as (monthname(a)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` date DEFAULT NULL,
+ `b` varchar(100) GENERATED ALWAYS AS (monthname(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2010-10-10',default);
+select * from t1;
+a b
+2010-10-10 October
+drop table t1;
+set sql_warnings = 0;
+# DAYNAME()
+set sql_warnings = 1;
+create table t1 (a date, b varchar(100) as (dayname(a)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` date DEFAULT NULL,
+ `b` varchar(100) GENERATED ALWAYS AS (dayname(`a`)) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2011-11-11',default);
+select * from t1;
+a b
+2011-11-11 Friday
+drop table t1;
+set sql_warnings = 0;
+# DATE_FORMAT()
+set sql_warnings = 1;
+create table t1 (a date, b varchar(100) as (date_format(a, '%W %a %M %b')));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` date DEFAULT NULL,
+ `b` varchar(100) GENERATED ALWAYS AS (date_format(`a`,'%W %a %M %b')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2012-12-12',default);
+select * from t1;
+a b
+2012-12-12 Wednesday Wed December Dec
+drop table t1;
+set sql_warnings = 0;
+# DATE_FORMAT() STORED
+set sql_warnings = 1;
+create table t1 (a date, b varchar(100) as (date_format(a, '%W %a %M %b', 'de_DE')) STORED);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` date DEFAULT NULL,
+ `b` varchar(100) GENERATED ALWAYS AS (date_format(`a`,'%W %a %M %b','de_DE')) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2012-12-12',default);
+select * from t1;
+a b
+2012-12-12 Mittwoch Mi Dezember Dez
+drop table t1;
+set sql_warnings = 0;
+# CURRENT_USER()
+set sql_warnings = 1;
+create table t1 (a char, b varchar(32) as (current_user()));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(1) DEFAULT NULL,
+ `b` varchar(32) GENERATED ALWAYS AS (current_user()) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('a', default);
+select * from t1;
+a b
+a root@localhost
+drop table t1;
+set sql_warnings = 0;
+# TIME_FORMAT()
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(10) as (time_format(a,"%H.%i.%S")));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` datetime DEFAULT NULL,
+ `b` varchar(10) GENERATED ALWAYS AS (time_format(`a`,'%H.%i.%S')) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2001-01-01 02:03:04',default);
+select * from t1;
+a b
+2001-01-01 02:03:04 02.03.04
+drop table t1;
+set sql_warnings = 0;
+# TIME_FORMAT() STORED
+set sql_warnings = 1;
+create table t1 (a datetime, b varchar(10) as (time_format(a,"%H.%i.%S")) STORED);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` datetime DEFAULT NULL,
+ `b` varchar(10) GENERATED ALWAYS AS (time_format(`a`,'%H.%i.%S')) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t1 values ('2001-01-01 02:03:04',default);
+select * from t1;
+a b
+2001-01-01 02:03:04 02.03.04
+drop table t1;
+set sql_warnings = 0;
diff --git a/mysql-test/suite/vcol/r/vcol_syntax.result b/mysql-test/suite/vcol/r/vcol_syntax.result
new file mode 100644
index 00000000..7725d59f
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_syntax.result
@@ -0,0 +1,240 @@
+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) GENERATED ALWAYS AS (`a` + 1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` + 1) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS AS (`a` + 1) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+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) GENERATED ALWAYS 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) GENERATED ALWAYS 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) GENERATED ALWAYS AS ("a" + 1) STORED
+)
+drop table t1;
+set session sql_mode=@OLD_SQL_MODE;
+#
+# MDEV-25091 CREATE TABLE: field references qualified by a wrong table name succeed
+#
+create table t2 (x int);
+create table t1 (x int, y int generated always as (t2.x));
+ERROR HY000: Function or expression 't2.x' cannot be used in the GENERATED ALWAYS AS clause of `y`
+create table t1 (x int, y int check (y > t2.x));
+ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `y`
+create table t1 (x int, y int default t2.x);
+ERROR HY000: Function or expression 't2.x' cannot be used in the DEFAULT clause of `y`
+create table t1 (x int, check (t2.x > 0));
+ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `CONSTRAINT_1`
+create table t1 (x int);
+alter table t1 add column y int generated always as (t2.x);
+ERROR HY000: Function or expression 't2.x' cannot be used in the GENERATED ALWAYS AS clause of `y`
+alter table t1 add column y int check (z > t2.x);
+ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `y`
+alter table t1 add column y int default t2.x;
+ERROR HY000: Function or expression 't2.x' cannot be used in the DEFAULT clause of `y`
+alter table t1 add constraint check (t2.x > 0);
+ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `CONSTRAINT_1`
+create or replace table t1 (x int, y int generated always as (t1.x));
+create or replace table t1 (x int, y int check (y > t1.x));
+create or replace table t1 (x int, y int default t1.x);
+create or replace table t1 (x int, check (t1.x > 0));
+create or replace table t1 (x int, y int generated always as (test.t1.x));
+create or replace table t1 (x int, y int check (y > test.t1.x));
+create or replace table t1 (x int, y int default test.t1.x);
+create or replace table t1 (x int, check (test.t1.x > 0));
+drop tables t1, t2;
+create table t1 (x int, y int generated always as (test2.t1.x));
+ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the GENERATED ALWAYS AS clause of `y`
+create table t1 (x int, y int check (y > test2.t1.x));
+ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the CHECK clause of `y`
+create table t1 (x int, y int default test2.t1.x);
+ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the DEFAULT clause of `y`
+create table t1 (x int, check (test2.t1.x > 0));
+ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the CHECK clause of `CONSTRAINT_1`
+#
+# MDEV-25672 table alias from previous statement interferes later commands
+#
+create table t1 (a int, v_a int generated always as (a));
+update t1 as x set a = 1;
+alter table t1 force;
+drop table t1;
+create table t1 (
+id int not null auto_increment primary key,
+order_date_time datetime not null,
+order_date date generated always as (convert(order_date_time, date)),
+language_id binary(16) null
+);
+update t1 as tx set order_date= null;
+alter table t1 modify column language_id binary(16) not null;
+drop table t1;
+#
+# MDEV-24176 Server crashes after insert in the table with virtual column generated using date_format() and if()
+#
+create table t1 (d1 date not null, d2 date not null,
+gd text as (concat(d1,if(d1 <> d2, date_format(d2, 'to %y-%m-%d '), ''))) );
+insert into t1(d1,d2) values
+('2020-09-01','2020-09-01'),('2020-05-01','2020-09-01');
+select * from t1;
+d1 d2 gd
+2020-09-01 2020-09-01 2020-09-01
+2020-05-01 2020-09-01 2020-05-01to 20-09-01
+drop table t1;
+# MDEV-25772 (duplicate) and LOCK TABLES case
+create table t1 (d1 datetime , v_d1 tinyint(1) as (d1 < curdate()));
+insert into t1 (d1) values ('2021-09-11 08:38:23'), ('2021-09-01 08:38:23');
+lock tables t1 write;
+select * from t1 where v_d1=1;
+d1 v_d1
+2021-09-11 08:38:23 1
+2021-09-01 08:38:23 1
+select * from t1;
+d1 v_d1
+2021-09-11 08:38:23 1
+2021-09-01 08:38:23 1
+unlock tables;
+drop table t1;
+# MDEV-26432 (duplicate)
+create table t1 (v2 int, v1 int as ((user() like 'x'))) ;
+select 1 from t1 where v1=1 ;
+1
+select * from t1;
+v2 v1
+drop table t1;
+create table t1 (v2 int as ( user () like 'x'));
+select 1 from t1 order by v2 ;
+1
+alter table t1 add i int;
+drop table t1;
+# MDEV-26437 (duplicate)
+create table v0 (v2 int not null,
+v1 bigint as (case 'x' when current_user() then v2 end));
+select v2 as v3 from v0 where v1 like 'x' escape 'x';
+v3
+insert into v0 (v2) values (-128);
+drop table v0;
+create table t1 (vi int as (case 'x' when current_user() then 1 end));
+select 1 from t1 where vi=1;
+1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `vi` int(11) GENERATED ALWAYS AS (case 'x' when current_user() then 1 end) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
+create table t1 (vi int as (case 'x' when current_user() then 1 end));
+select 1 from t1 where vi=1;
+1
+select 1 from t1 where vi=1;
+1
+drop table t1;
+# MDEV-28092 (duplicate)
+create table t1 (b timestamp, a int as (1 in (dayofmonth (b between 'x' and current_user) = b)));
+insert into t1(b) values ('2022-03-17 14:55:37');
+select 1 from t1 x natural join t1;
+1
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: 'x'
+Warning 1292 Truncated incorrect datetime value: 'root@localhost'
+Warning 1292 Truncated incorrect datetime value: 'x'
+Warning 1292 Truncated incorrect datetime value: 'root@localhost'
+drop table t1;
+# MDEV-28089 (duplicate)
+create table t1 (a int , b date as (1 in ('x' ,(database () = 'x' is null) ))) ;
+select b from t1;
+b
+select a from t1 order by 'x' = b;
+a
+drop table t1;
+create table t1 (a int , b date as (1 in ('x' ,(database ()) ))) ;
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: 'x'
+Warning 1292 Truncated incorrect DECIMAL value: 'test'
+select b from t1;
+b
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: 'x'
+Warning 1292 Truncated incorrect DECIMAL value: 'test'
+select a from t1 order by 'x' = b;
+a
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: 'x'
+Warning 1292 Truncated incorrect DECIMAL value: 'test'
+drop table t1;
+#
+# MDEV-31319 Assertion const_item_cache == true failed in Item_func::fix_fields
+#
+create table t (f1 int, f2 int, fv int generated always as (case user() when 'foo' or 'bar' then f1 else f2 end) virtual);
+select * from t;
+f1 f2 fv
+insert into t (f1,f2) values(1,1);
+select * from t;
+f1 f2 fv
+1 1 1
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: 'root@localhost'
+Warning 1292 Truncated incorrect DOUBLE value: 'foo'
+Warning 1292 Truncated incorrect DOUBLE value: 'bar'
+create table tmp as select * from information_schema.tables where table_name = 't';
+select * from t;
+f1 f2 fv
+1 1 1
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: 'root@localhost'
+Warning 1292 Truncated incorrect DOUBLE value: 'foo'
+Warning 1292 Truncated incorrect DOUBLE value: 'bar'
+drop table t, tmp;
+#
+# MDEV-29357 Assertion (fixed) in Item_func_dayname on INSERT
+#
+set sql_mode='';
+create table t (c1 blob ,c2 int,c3 char(10) as (dayname (c2)));
+create trigger tr before insert on t for each row set new.c2=0;
+insert into t values (0, 0, 0);
+Warnings:
+Warning 1906 The value specified for generated column 'c3' in table 't' has been ignored
+Warning 1292 Incorrect datetime value: '0' for column `test`.`t`.`c2` at row 1
+Warning 1292 Incorrect datetime value: '0' for column `test`.`t`.`c2` at row 1
+insert into t values (1, 1, 1);
+Warnings:
+Warning 1906 The value specified for generated column 'c3' in table 't' has been ignored
+Warning 1292 Incorrect datetime value: '1' for column `test`.`t`.`c2` at row 1
+Warning 1292 Incorrect datetime value: '0' for column `test`.`t`.`c2` at row 1
+drop trigger tr;
+drop table t;
diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
new file mode 100644
index 00000000..c4f6e0c5
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_innodb.result
@@ -0,0 +1,316 @@
+SET @@session.default_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;
+#
+# MDEV-3845 values of virtual columns are not computed for triggers
+#
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b INTEGER UNSIGNED GENERATED ALWAYS AS (a) VIRTUAL
+);
+CREATE TABLE t2 (c INTEGER UNSIGNED NOT NULL);
+CREATE TRIGGER t1_ins_aft
+AFTER INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (NEW.b);
+END |
+CREATE TRIGGER t1_del_bef
+BEFORE DELETE
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (OLD.b);
+END |
+INSERT INTO t1 (a) VALUES (1), (2), (3);
+SELECT * FROM t2;
+c
+1
+2
+3
+DELETE FROM t1;
+SELECT * FROM t2;
+c
+1
+2
+3
+1
+2
+3
+DROP TRIGGER t1_ins_aft;
+DROP TRIGGER t1_del_bef;
+DROP TABLE t1,t2;
+create table t1 (i int, t time not null, vt time(4) as (t) virtual);
+create trigger trg before update on t1 for each row set @a = 1;
+insert ignore into t1 (i) values (1);
+Warnings:
+Warning 1364 Field 't' doesn't have a default value
+drop table t1;
+#
+# Examine the number of times triggers are recalculated for updates
+#
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b CHAR(10) NULL DEFAULT NULL,
+c blob NULL DEFAULT NULL,
+blob_a blob GENERATED ALWAYS AS (last_value(@a:=@a+1,a)) VIRTUAL,
+blob_b blob GENERATED ALWAYS AS (last_value(@b:=@b+1,b)) VIRTUAL,
+blob_c blob GENERATED ALWAYS AS (last_value(@c:=@c+1,c)) VIRTUAL
+);
+CREATE TRIGGER t1_ins
+BEFORE INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL THEN
+SET NEW.b="generated before insert";
+END IF;
+END |
+CREATE TRIGGER t1_update
+BEFORE UPDATE
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL or NEW.c IS NULL THEN
+SET NEW.b="generated before update";
+SET NEW.c="generated before update";
+END IF;
+END |
+# Inserts
+set @a=0,@b=0,@c=0;
+insert into t1 (a) values(1);
+insert into t1 (a,b) values(2, "*2*");
+insert into t1 (a,b,c) values(3, "*3*", "**3**");
+insert into t1 (a,c) values(4, "**4**");
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+8 8 8
+select a,b,c from t1;
+a b c
+1 generated NULL
+2 *2* NULL
+3 *3* **3**
+4 generated **4**
+select @a,@b,@c;
+@a @b @c
+8 8 8
+select a,b,c,blob_a from t1;
+a b c blob_a
+1 generated NULL 1
+2 *2* NULL 2
+3 *3* **3** 3
+4 generated **4** 4
+select @a,@b,@c;
+@a @b @c
+12 8 8
+# updates
+set @a=0,@b=0,@c=0;
+update t1 set a=a+100 where a=1;
+update t1 set a=a+100, b="*102*" where a=2;
+update t1 set a=a+100, b=NULL where a=3;
+update t1 set a=a+100, b="invisible", c=NULL where a=4;
+select @a,@b,@c;
+@a @b @c
+0 0 0
+select * from t1;
+a b c blob_a blob_b blob_c
+101 generated generated before update 101 generated generated before update
+102 generated generated before update 102 generated generated before update
+103 generated generated before update 103 generated generated before update
+104 generated generated before update 104 generated generated before update
+drop trigger t1_ins;
+drop trigger t1_update;
+drop table t1;
+SET sql_mode = DEFAULT;
+#
+# Same test, but with virtual keys
+#
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b CHAR(10) NULL DEFAULT NULL,
+c blob NULL DEFAULT NULL,
+blob_a blob GENERATED ALWAYS AS (a) VIRTUAL,
+blob_b blob GENERATED ALWAYS AS (RTRIM(b)) VIRTUAL,
+blob_c blob GENERATED ALWAYS AS (c) VIRTUAL,
+key (a),
+key (blob_a(10)),
+key (blob_b(10)),
+key (blob_c(10))
+);
+CREATE TRIGGER t1_ins
+BEFORE INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL THEN
+SET NEW.b="generated before insert";
+END IF;
+END |
+CREATE TRIGGER t1_update
+BEFORE UPDATE
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL or NEW.c IS NULL THEN
+SET NEW.b="generated before update";
+SET NEW.c="generated before update";
+END IF;
+END |
+# Inserts
+insert into t1 (a) values(1);
+insert into t1 (a,b) values(2, "*2*");
+insert into t1 (a,b,c) values(3, "*3*", "**3**");
+insert into t1 (a,c) values(4, "**4**");
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select a,b,c from t1;
+a b c
+1 generated NULL
+2 *2* NULL
+3 *3* **3**
+4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select a,b,c,blob_a from t1;
+a b c blob_a
+1 generated NULL 1
+2 *2* NULL 2
+3 *3* **3** 3
+4 generated **4** 4
+select @a,@b,@c;
+@a @b @c
+4 4 4
+# updates
+update t1 set a=a+100 where a=1;
+update t1 set a=a+100, b="*102*" where a=2;
+update t1 set a=a+100, b=NULL where a=3;
+update t1 set a=a+100, b="invisible", c=NULL where a=4;
+select * from t1;
+a b c blob_a blob_b blob_c
+101 generated generated before update 101 generated generated before update
+102 generated generated before update 102 generated generated before update
+103 generated generated before update 103 generated generated before update
+104 generated generated before update 104 generated generated before update
+drop trigger t1_ins;
+drop trigger t1_update;
+drop table t1;
+SET sql_mode = DEFAULT;
diff --git a/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
new file mode 100644
index 00000000..467e7f8b
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_trigger_sp_myisam.result
@@ -0,0 +1,316 @@
+SET @@session.default_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;
+#
+# MDEV-3845 values of virtual columns are not computed for triggers
+#
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b INTEGER UNSIGNED GENERATED ALWAYS AS (a) VIRTUAL
+);
+CREATE TABLE t2 (c INTEGER UNSIGNED NOT NULL);
+CREATE TRIGGER t1_ins_aft
+AFTER INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (NEW.b);
+END |
+CREATE TRIGGER t1_del_bef
+BEFORE DELETE
+ON t1
+FOR EACH ROW
+BEGIN
+INSERT INTO t2 (c) VALUES (OLD.b);
+END |
+INSERT INTO t1 (a) VALUES (1), (2), (3);
+SELECT * FROM t2;
+c
+1
+2
+3
+DELETE FROM t1;
+SELECT * FROM t2;
+c
+1
+2
+3
+1
+2
+3
+DROP TRIGGER t1_ins_aft;
+DROP TRIGGER t1_del_bef;
+DROP TABLE t1,t2;
+create table t1 (i int, t time not null, vt time(4) as (t) virtual);
+create trigger trg before update on t1 for each row set @a = 1;
+insert ignore into t1 (i) values (1);
+Warnings:
+Warning 1364 Field 't' doesn't have a default value
+drop table t1;
+#
+# Examine the number of times triggers are recalculated for updates
+#
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b CHAR(10) NULL DEFAULT NULL,
+c blob NULL DEFAULT NULL,
+blob_a blob GENERATED ALWAYS AS (last_value(@a:=@a+1,a)) VIRTUAL,
+blob_b blob GENERATED ALWAYS AS (last_value(@b:=@b+1,b)) VIRTUAL,
+blob_c blob GENERATED ALWAYS AS (last_value(@c:=@c+1,c)) VIRTUAL
+);
+CREATE TRIGGER t1_ins
+BEFORE INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL THEN
+SET NEW.b="generated before insert";
+END IF;
+END |
+CREATE TRIGGER t1_update
+BEFORE UPDATE
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL or NEW.c IS NULL THEN
+SET NEW.b="generated before update";
+SET NEW.c="generated before update";
+END IF;
+END |
+# Inserts
+set @a=0,@b=0,@c=0;
+insert into t1 (a) values(1);
+insert into t1 (a,b) values(2, "*2*");
+insert into t1 (a,b,c) values(3, "*3*", "**3**");
+insert into t1 (a,c) values(4, "**4**");
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+8 8 8
+select a,b,c from t1;
+a b c
+1 generated NULL
+2 *2* NULL
+3 *3* **3**
+4 generated **4**
+select @a,@b,@c;
+@a @b @c
+8 8 8
+select a,b,c,blob_a from t1;
+a b c blob_a
+1 generated NULL 1
+2 *2* NULL 2
+3 *3* **3** 3
+4 generated **4** 4
+select @a,@b,@c;
+@a @b @c
+12 8 8
+# updates
+set @a=0,@b=0,@c=0;
+update t1 set a=a+100 where a=1;
+update t1 set a=a+100, b="*102*" where a=2;
+update t1 set a=a+100, b=NULL where a=3;
+update t1 set a=a+100, b="invisible", c=NULL where a=4;
+select @a,@b,@c;
+@a @b @c
+0 0 0
+select * from t1;
+a b c blob_a blob_b blob_c
+101 generated generated before update 101 generated generated before update
+102 generated generated before update 102 generated generated before update
+103 generated generated before update 103 generated generated before update
+104 generated generated before update 104 generated generated before update
+drop trigger t1_ins;
+drop trigger t1_update;
+drop table t1;
+SET sql_mode = DEFAULT;
+#
+# Same test, but with virtual keys
+#
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1 (
+a INTEGER UNSIGNED NULL DEFAULT NULL,
+b CHAR(10) NULL DEFAULT NULL,
+c blob NULL DEFAULT NULL,
+blob_a blob GENERATED ALWAYS AS (a) VIRTUAL,
+blob_b blob GENERATED ALWAYS AS (RTRIM(b)) VIRTUAL,
+blob_c blob GENERATED ALWAYS AS (c) VIRTUAL,
+key (a),
+key (blob_a(10)),
+key (blob_b(10)),
+key (blob_c(10))
+);
+CREATE TRIGGER t1_ins
+BEFORE INSERT
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL THEN
+SET NEW.b="generated before insert";
+END IF;
+END |
+CREATE TRIGGER t1_update
+BEFORE UPDATE
+ON t1
+FOR EACH ROW
+BEGIN
+IF NEW.b IS NULL or NEW.c IS NULL THEN
+SET NEW.b="generated before update";
+SET NEW.c="generated before update";
+END IF;
+END |
+# Inserts
+insert into t1 (a) values(1);
+insert into t1 (a,b) values(2, "*2*");
+insert into t1 (a,b,c) values(3, "*3*", "**3**");
+insert into t1 (a,c) values(4, "**4**");
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select * from t1;
+a b c blob_a blob_b blob_c
+1 generated NULL 1 generated NULL
+2 *2* NULL 2 *2* NULL
+3 *3* **3** 3 *3* **3**
+4 generated **4** 4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select a,b,c from t1;
+a b c
+1 generated NULL
+2 *2* NULL
+3 *3* **3**
+4 generated **4**
+select @a,@b,@c;
+@a @b @c
+4 4 4
+select a,b,c,blob_a from t1;
+a b c blob_a
+1 generated NULL 1
+2 *2* NULL 2
+3 *3* **3** 3
+4 generated **4** 4
+select @a,@b,@c;
+@a @b @c
+4 4 4
+# updates
+update t1 set a=a+100 where a=1;
+update t1 set a=a+100, b="*102*" where a=2;
+update t1 set a=a+100, b=NULL where a=3;
+update t1 set a=a+100, b="invisible", c=NULL where a=4;
+select * from t1;
+a b c blob_a blob_b blob_c
+101 generated generated before update 101 generated generated before update
+102 generated generated before update 102 generated generated before update
+103 generated generated before update 103 generated generated before update
+104 generated generated before update 104 generated generated before update
+drop trigger t1_ins;
+drop trigger t1_update;
+drop table t1;
+SET sql_mode = DEFAULT;
diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result
new file mode 100644
index 00000000..53ef6e07
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result
@@ -0,0 +1,286 @@
+SET @@session.default_storage_engine = 'InnoDB';
+SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent=0;
+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#1 */ 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 6
+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 6
+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
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
+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
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
+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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+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;
+SET optimizer_switch=@save_optimizer_switch;
+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` 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 44000: CHECK OPTION failed `test`.`v1`
+insert ignore into v1 (a) values (2),(3),(0);
+Warnings:
+Warning 1369 CHECK OPTION failed `test`.`v1`
+Warning 1369 CHECK OPTION failed `test`.`v1`
+select * from t1;
+a b c
+1 -1 -1
+0 0 0
+drop view v1;
+drop table t1;
+SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent;
diff --git a/mysql-test/suite/vcol/r/vcol_view_myisam.result b/mysql-test/suite/vcol/r/vcol_view_myisam.result
new file mode 100644
index 00000000..9c0dcba2
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_view_myisam.result
@@ -0,0 +1,283 @@
+SET @@session.default_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#1 */ 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 6
+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 6
+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
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
+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
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
+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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+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;
+SET optimizer_switch=@save_optimizer_switch;
+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` 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 44000: CHECK OPTION failed `test`.`v1`
+insert ignore into v1 (a) values (2),(3),(0);
+Warnings:
+Warning 1369 CHECK OPTION failed `test`.`v1`
+Warning 1369 CHECK OPTION failed `test`.`v1`
+select * from t1;
+a b c
+1 -1 -1
+0 0 0
+drop view v1;
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/wrong_arena.result b/mysql-test/suite/vcol/r/wrong_arena.result
new file mode 100644
index 00000000..99136e73
--- /dev/null
+++ b/mysql-test/suite/vcol/r/wrong_arena.result
@@ -0,0 +1,89 @@
+#
+# MDEV-9690 concurrent queries with virtual columns crash in temporal code
+#
+create table t1 (a datetime,
+# get_datetime_value
+b int as (a > 1), # Arg_comparator
+c int as (a in (1,2,3)), # in_datetime
+d int as ((a,a) in ((1,1),(2,1),(NULL,1))), # cmp_item_datetime
+# other issues
+e int as ((a,1) in ((1,1),(2,1),(NULL,1))) # cmp_item_row::alloc_comparators()
+);
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '1'
+Warning 1292 Truncated incorrect datetime value: '2'
+Warning 1292 Truncated incorrect datetime value: '3'
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` datetime DEFAULT NULL,
+ `b` int(11) GENERATED ALWAYS AS (`a` > 1) VIRTUAL,
+ `c` int(11) GENERATED ALWAYS AS (`a` in (1,2,3)) VIRTUAL,
+ `d` int(11) GENERATED ALWAYS AS ((`a`,`a`) in ((1,1),(2,1),(NULL,1))) VIRTUAL,
+ `e` int(11) GENERATED ALWAYS AS ((`a`,1) in ((1,1),(2,1),(NULL,1))) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '1'
+Warning 1292 Truncated incorrect datetime value: '2'
+Warning 1292 Truncated incorrect datetime value: '3'
+connect con1, localhost, root;
+insert t1 (a) values ('2010-10-10 10:10:10');
+select * from t1;
+a b c d e
+2010-10-10 10:10:10 1 0 0 NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '1'
+Warning 1292 Truncated incorrect datetime value: '1'
+Warning 1292 Truncated incorrect datetime value: '2'
+Warning 1292 Truncated incorrect datetime value: '1'
+Warning 1292 Truncated incorrect datetime value: '1'
+Warning 1292 Truncated incorrect datetime value: '2'
+disconnect con1;
+connection default;
+select * from t1;
+a b c d e
+2010-10-10 10:10:10 1 0 0 NULL
+drop table t1;
+connect con1, localhost, root;
+create table t1 (a datetime,
+b datetime as (least(a,1)) # Item_func_min_max::get_date
+);
+insert t1 (a) values ('2010-10-10 10:10:10');
+select * from t1;
+a b
+2010-10-10 10:10:10 0000-00-00 00:00:00
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '1'
+disconnect con1;
+connection default;
+select * from t1;
+a b
+2010-10-10 10:10:10 0000-00-00 00:00:00
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '1'
+drop table t1;
+#
+# MDEV-13435 Crash when selecting virtual columns generated using JSON functions
+#
+create table t1 (
+id int not null ,
+js varchar(1000) not null,
+t time AS (cast(json_value(json_extract(js,concat('$.singleDay."', dayname(curdate()),'"')),'$.start') as time)) virtual);
+insert into t1(id,js) values (0, '{"default" : {"start": "00:00:00", "end":"23:59:50"}}');
+select * from t1;
+id js t
+0 {"default" : {"start": "00:00:00", "end":"23:59:50"}} NULL
+drop table t1;
+#
+# MDEV-26281 ASAN use-after-poison when complex conversion is involved in blob
+#
+create table t1 (v2 blob as ('a' is null), a1 int, a char(1) as (cast(a1 in (0,current_user() is null) as char(16777216) )));
+insert ignore into t1 values ('x','x',v2) ;
+Warnings:
+Warning 1906 The value specified for generated column 'v2' in table 't1' has been ignored
+Warning 1366 Incorrect integer value: 'x' for column `test`.`t1`.`a1` at row 1
+Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored
+drop table t1;
+#
+# End of 10.2 tests
+#
diff --git a/mysql-test/suite/vcol/t/alter_inplace-9045.test b/mysql-test/suite/vcol/t/alter_inplace-9045.test
new file mode 100644
index 00000000..57723e6f
--- /dev/null
+++ b/mysql-test/suite/vcol/t/alter_inplace-9045.test
@@ -0,0 +1,32 @@
+#
+# MDEV-9045 Inconsistent handling of "ALGORITHM=INPLACE" with PERSISTENT generated columns
+#
+--source include/have_innodb.inc
+
+create table t1(id int auto_increment primary key, handle int, data bigint not null default 0) engine = innodb;
+insert into t1(handle) values(12),(54),(NULL);
+select *, md5(handle) from t1;
+alter table t1 add index handle(handle), algorithm=inplace;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 add column hash varchar(32) as (md5(handle)) persistent, algorithm=inplace;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 add column hash varchar(32) as (md5(handle)) persistent, add unique index hash(hash), algorithm=inplace;
+alter table t1 add column hash varchar(32) as (md5(handle)) persistent, add unique index hash(hash), algorithm=copy;
+select * from t1;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 modify column hash varchar(32) as (md5(handle+1)) persistent, algorithm=inplace;
+alter table t1 modify column hash varchar(32) as (md5(handle+1)) persistent, algorithm=copy;
+select * from t1;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 modify column handle int not null, algorithm=inplace;
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+alter table t1 modify column handle int not null, algorithm=copy;
+select * from t1;
+alter table t1 drop index handle, algorithm=inplace;
+create index data on t1(data) algorithm=inplace;
+alter table t1 drop column data, algorithm=inplace;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 add column sha varchar(32) as (sha1(handle)) persistent, algorithm=inplace;
+alter table t1 add column sha varchar(32), algorithm=inplace;
+alter table t1 drop column hash, algorithm=inplace;
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/binlog.test b/mysql-test/suite/vcol/t/binlog.test
new file mode 100644
index 00000000..edf0a895
--- /dev/null
+++ b/mysql-test/suite/vcol/t/binlog.test
@@ -0,0 +1,83 @@
+--source include/have_innodb.inc
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+#
+# MDEV-15243
+# Server crashes in in Field_blob::pack upon REPLACE into view with virtual
+# columns with binlog enabled
+#
+
+CREATE TABLE t1 (
+ pk SERIAL,
+ vcol_date DATE AS (col_date) PERSISTENT,
+ vcol_int INT AS (col_int) VIRTUAL,
+ vcol_year YEAR AS (col_year) PERSISTENT,
+ vcol_blob BLOB AS (col_blob) VIRTUAL,
+ col_date DATE,
+ col_int INT NULL,
+ col_blob BLOB NULL,
+ col_year YEAR,
+ PRIMARY KEY(pk)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 (col_date,col_int,col_blob,col_year) VALUES ('2010-04-24',5,'foo',1981);
+SET SQL_MODE='';
+
+set binlog_row_image="FULL";
+CREATE VIEW v1 AS SELECT * FROM t1;
+REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1982 FROM t1;
+select col_date,col_int,col_blob,col_year from v1;
+sync_slave_with_master;
+select col_date,col_int,col_blob,col_year from v1;
+connection master;
+DROP VIEW v1;
+set binlog_row_image="MINIMAL";
+CREATE VIEW v1 AS SELECT * FROM t1;
+REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1983 FROM t1;
+select col_date,col_int,col_blob,col_year from v1;
+sync_slave_with_master;
+select col_date,col_int,col_blob,col_year from v1;
+connection master;
+DROP VIEW v1;
+set @@binlog_row_image="NOBLOB";
+CREATE VIEW v1 AS SELECT * FROM t1;
+REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1984 FROM t1;
+select col_date,col_int,col_blob,col_year from v1;
+sync_slave_with_master;
+select col_date,col_int,col_blob,col_year from v1;
+connection master;
+DROP VIEW v1;
+set @@binlog_row_image=default;
+
+DROP TABLE t1;
+SET SQL_MODE=default;
+
+# MDEV-24782
+# ASAN use-after-poison in Field::pack_int / THD::binlog_update_row
+
+CREATE TABLE t1 (pk INT, a VARCHAR(3), b VARCHAR(1) AS (a) VIRTUAL, PRIMARY KEY (pk));
+INSERT IGNORE INTO t1 (pk, a) VALUES (1,'foo'),(2,'bar');
+--error ER_DATA_TOO_LONG
+REPLACE INTO t1 (pk) VALUES (2);
+UPDATE IGNORE t1 SET a = NULL;
+
+# Cleanup
+DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-18166 ASSERT_COLUMN_MARKED_FOR_READ failed on tables with vcols
+--echo #
+
+SET SESSION binlog_row_image= noblob;
+CREATE TEMPORARY TABLE t1 SELECT UUID();
+show create table t1;
+CREATE TABLE t2 (a INT PRIMARY KEY, b TEXT, c INT GENERATED ALWAYS AS(b));
+INSERT INTO t2 (a,b) VALUES (1,1);
+
+SET SESSION binlog_row_image= default;
+DROP TABLE t2;
+
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/vcol/t/charsets.test b/mysql-test/suite/vcol/t/charsets.test
new file mode 100644
index 00000000..72f9b7a3
--- /dev/null
+++ b/mysql-test/suite/vcol/t/charsets.test
@@ -0,0 +1,19 @@
+#
+# vcol definition, table charset, current connection charset
+#
+set names utf8;
+create table t1 (
+ a int,
+ b varchar(100) as (if(a,collation('й'),hex('ю')))
+) character set koi8r;
+insert t1 (a) values (0),(1);
+select * from t1;
+set names latin1;
+select * from t1;
+flush tables;
+select * from t1;
+set names koi8r;
+select * from t1;
+flush tables;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/cross_db.test b/mysql-test/suite/vcol/t/cross_db.test
new file mode 100644
index 00000000..5a8ee547
--- /dev/null
+++ b/mysql-test/suite/vcol/t/cross_db.test
@@ -0,0 +1,12 @@
+--source include/default_charset.inc
+
+#
+# MDEV-13209 Cross-database operation with virtual columns fails
+#
+
+create database mysqltest1;
+create table mysqltest1.t1 (i int, j int as (i) persistent);
+show create table mysqltest1.t1;
+alter table mysqltest1.t1 add index (i);
+show create table mysqltest1.t1;
+drop database mysqltest1;
diff --git a/mysql-test/suite/vcol/t/delayed.test b/mysql-test/suite/vcol/t/delayed.test
new file mode 100644
index 00000000..62065abd
--- /dev/null
+++ b/mysql-test/suite/vcol/t/delayed.test
@@ -0,0 +1,5 @@
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (10,1);
+replace delayed t (a,b) values (10,5);
+check table t;
+drop table t;
diff --git a/mysql-test/suite/vcol/t/index.test b/mysql-test/suite/vcol/t/index.test
new file mode 100644
index 00000000..b93c337f
--- /dev/null
+++ b/mysql-test/suite/vcol/t/index.test
@@ -0,0 +1,97 @@
+--source include/have_innodb.inc
+--source include/have_log_bin.inc
+
+--echo #
+--echo # Test table with a key that consists of indirect virtual fields
+--echo #
+
+CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=myisam;
+insert into t1 (a) values (1),(2),(3);
+update t1 set a=5 where a=3;
+delete from t1 where a=1;
+select * from t1;
+select * from t1 where c=7;
+check table t1;
+select * from t1;
+drop table t1;
+
+CREATE TABLE t1 (a int, b int as (a+1) virtual, c int as (b+1) virtual, index(c)) engine=innodb;
+insert into t1 (a) values (1),(2),(3);
+update t1 set a=5 where a=3;
+delete from t1 where a=1;
+select * from t1;
+select * from t1 where c=7;
+check table t1;
+select * from t1;
+drop table t1;
+
+--echo #
+--echo # MDEV-15114
+--echo # ASAN heap-use-after-free in mem_heap_dup or
+--echo # dfield_data_is_binary_equal
+--echo #
+
+CREATE TABLE t1 (
+ pk INT,
+ extra tinyint,
+ c TEXT,
+ vc LONGTEXT AS (c) VIRTUAL,
+ i INT,
+ PRIMARY KEY(pk),
+ UNIQUE(i),
+ INDEX(vc(64))
+) ENGINE=InnoDB;
+
+INSERT INTO t1 (pk,extra, c, i) VALUES (1, 10, REPEAT('foo ',15000),0);
+REPLACE INTO t1 (pk,extra, c,i) SELECT pk,extra+10, c,i FROM t1;
+select pk, extra, left(c, 10), length(c), left(vc,10), length(vc), extra from t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Update of deleted row with binary logging enabled
+--echo #
+
+SET BINLOG_FORMAT=row;
+
+CREATE TABLE t1 (
+ pk INT,
+ c TEXT,
+ vc LONGTEXT AS (c) VIRTUAL,
+ i INT,
+ PRIMARY KEY(pk),
+ UNIQUE(i),
+ INDEX(vc(64))
+) ENGINE=InnoDB;
+
+INSERT INTO t1 (pk,c,i) VALUES (1,REPEAT('foo ',15000),10);
+INSERT INTO t1 (pk,c,i) VALUES (2,REPEAT('bar ',15000),11);
+
+--connect (c1,localhost,root,,)
+--connection c1
+begin;
+DELETE from t1 WHERE pk=1;
+--connection default
+--send update t1 set pk=1 where pk=2
+--connection c1
+commit;
+--connection default
+--reap
+select pk, left(c, 10), length(c), i from t1;
+drop table t1;
+disconnect c1;
+
+#
+# MDEV-16961 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed upon concurrent DELETE and DDL with virtual blob column
+#
+
+CREATE TABLE t1 (b BLOB, vb TEXT AS (b) PERSISTENT, KEY(vb(64))) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES ('foo');
+--connect (con1,localhost,root,,test)
+--send CREATE TABLE t2 LIKE t1
+--connection default
+DELETE FROM t1;
+--connection con1
+--reap
+--disconnect con1
+--connection default
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/vcol/t/innodb_autoinc_vcol.test b/mysql-test/suite/vcol/t/innodb_autoinc_vcol.test
new file mode 100644
index 00000000..d499a06c
--- /dev/null
+++ b/mysql-test/suite/vcol/t/innodb_autoinc_vcol.test
@@ -0,0 +1,9 @@
+--source include/have_innodb.inc
+
+create table t1 (c2 int as (1+1), c1 int primary key auto_increment) engine=innodb;
+insert into t1(c1) values (null),(null),(null);
+select * from t1;
+alter table t1 auto_increment = 3;
+show create table t1;
+drop table t1;
+
diff --git a/mysql-test/suite/vcol/t/innodb_virtual_fk.test b/mysql-test/suite/vcol/t/innodb_virtual_fk.test
new file mode 100644
index 00000000..cab43914
--- /dev/null
+++ b/mysql-test/suite/vcol/t/innodb_virtual_fk.test
@@ -0,0 +1,115 @@
+source include/have_innodb.inc;
+set default_storage_engine=innodb;
+
+#
+# MDEV-13708 Crash with indexed virtual columns and FK cascading deletes
+#
+
+create table t1 (id int primary key, id2 int as (id) virtual, key id2 (id2));
+create table t2 (id int key, constraint fk_id foreign key (id) references t1 (id) on delete cascade);
+insert into t1 (id) values (1), (2);
+insert into t2 (id) values (1), (2);
+delete from t1;
+select * from t1;
+select * from t2;
+drop table t2;
+drop table t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-18114 Foreign Key Constraint actions don't affect Virtual Column
+--echo #
+create table t1 (id int primary key);
+
+# note that RESTRICT, NO ACTION, and DELETE CASCADE are fine
+# because they don't change values of referenced columns
+
+# virtual indexed
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update cascade);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete set null);
+create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update set null);
+
+# stored
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete set null);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update set null);
+
+# stored indirect
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete set null);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update set null);
+
+# default
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete cascade);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update cascade);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete set null);
+create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update set null);
+
+# field check
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete set null);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update set null);
+
+# table check
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete set null);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update set null);
+
+# table check indirect
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update restrict);
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update no action);
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update cascade);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete set null);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update set null);
+
+drop table if exists t2, t1;
+
+--echo #
+--echo # MDEV-31853 Assertion failure in Column_definition::check_vcol_for_key upon adding FK
+--echo #
+create table t (a int, b int, c int generated always as (a), key(b), key(c));
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t add foreign key (a) references t (b) on update set null, algorithm=nocopy;
+alter table t add foreign key (a) references t (b);
+show create table t;
+drop table t;
+
+--echo #
+--echo # End of 10.5 tests
+--echo #
diff --git a/mysql-test/suite/vcol/t/load_data.test b/mysql-test/suite/vcol/t/load_data.test
new file mode 100644
index 00000000..1b662818
--- /dev/null
+++ b/mysql-test/suite/vcol/t/load_data.test
@@ -0,0 +1,15 @@
+#
+# MDEV-7968 Virtual column set to NULL using load data infile
+#
+create table t1 ( c1 varchar(10), c2 varchar(10), c3 int );
+insert into t1 values ("a" , "b", 1), ("a" , "b", 2);
+create table t2 like t1 ;
+alter table t2 add column c4 bigint unsigned as (CONV(LEFT(MD5(concat(c1,c2,c3)), 16), 16, 10)) persistent unique key;
+--disable_ps2_protocol
+select * into outfile 't1.csv' from t1;
+--enable_ps2_protocol
+load data infile 't1.csv' ignore into table t2 ;
+select * from t2;
+insert into t2 (c1,c2,c3) values ("a" , "b", 4);
+select * from t2;
+drop table t1, t2;
diff --git a/mysql-test/suite/vcol/t/mrr.test b/mysql-test/suite/vcol/t/mrr.test
new file mode 100644
index 00000000..d7772ba5
--- /dev/null
+++ b/mysql-test/suite/vcol/t/mrr.test
@@ -0,0 +1,13 @@
+CREATE TABLE t1 (
+ pk INT AUTO_INCREMENT PRIMARY KEY,
+ col_int_nokey INT NULL,
+ col_int_key INT AS (col_int_nokey) VIRTUAL,
+ KEY (col_int_key)
+);
+INSERT INTO t1 (col_int_nokey)
+VALUES (0), (5), (4), (3), (7), (42), (5), (0), (3);
+SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1;
+set optimizer_switch='index_condition_pushdown=off';
+SELECT * FROM t1 WHERE col_int_key IN (3, 4) ORDER BY 1;
+SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/t/myisam_repair_prefix_varchar.test b/mysql-test/suite/vcol/t/myisam_repair_prefix_varchar.test
new file mode 100644
index 00000000..f35512c5
--- /dev/null
+++ b/mysql-test/suite/vcol/t/myisam_repair_prefix_varchar.test
@@ -0,0 +1,131 @@
+#
+# MDEV-11605 Assertion `(longlong) thd->status_var.local_memory_used >= 0 || !debug_assert_on_not_freed_memory' failed in my_malloc_size_cb_func
+#
+create table t4 (
+ pk bigint auto_increment,
+ col_int smallint(48) not null default 0,
+ col_datetime datetime(6) null,
+ col_enum set('','a','b','c','d','e','f','foo','bar') null,
+ col_dec decimal(65,38) unsigned zerofill null,
+ col_bit bit(26) null,
+ col_year year null,
+ col_datetime2 datetime(6) null,
+ col_date date null,
+ col_char binary(242) not null default '',
+ col_time time(1) null,
+ col_blob tinytext null,
+ col_varchar varchar(1855) not null default '',
+ vcol_varchar varchar(2116) as (col_varchar) virtual,
+ vvcol_varchar varchar(2116) as (vcol_varchar) virtual,
+ primary key(pk)
+ ) engine=myisam;
+
+insert into t4 (col_int,col_datetime,col_enum,col_dec,col_bit,col_year,col_datetime2,col_date,col_char,col_time,col_blob,col_varchar) values
+ (9,NULL,'',0.2,b'10100001',2026,NULL,'1988-08-27','bar','14:20:46.009603','bar','bar'),
+ (6,'2013-06-27 15:21:27.016500','',0.1,b'01000100',1983,'2014-03-26 03:00:53.052916','2000-09-04','','22:30:46.061648','bar','bar'),
+ (156,'2017-04-04 00:00:00','',0.8,NULL,1992,'1991-10-18 17:41:54.030689',NULL,'f','16:58:37.037585','z','a'),
+ (7,'1979-05-14 19:13:18.060777',NULL,0.4,b'0',1994,'1900-01-01 00:00:00','2030-01-06','bar','03:24:01.010412','bar','bar'),
+ (5,'1975-08-06 00:00:02.061160','',0.7,b'01',1996,'1982-06-10 13:09:15.005717','2008-04-23','bar',NULL,'bar','bar'),
+ (14,'2029-05-19 07:56:57.028948','',0.0,NULL,1973,'1900-01-01 00:00:00','2006-03-01','p','20:58:23.064148','v','a'),
+ (23,NULL,'',NULL,b'011111111000',2014,'2004-06-19 17:20:37.029214','1974-06-26','bar','14:55:15.000814','m','bar'),
+ (6,NULL,'',0.6,b'1100100011011101001111',1986,'2014-07-01 03:01:16.043826','2020-01-15','z','04:57:32.018208','bar','g'),
+ (2,'1987-03-12 05:18:40.006865','',0.6,b'001001001011000011001',2012,NULL,'2020-04-21','','20:45:31.021923','k','t'),
+ (1,'1993-05-23 10:37:22.054985','',0.4,b'01001',NULL,'1997-08-16 02:35:53.002484','2001-12-09','bar','07:36:35.044493','','s'),
+ (9,'2020-11-17 01:09:54.053312','',0.7,b'0',2022,'1900-01-01 00:00:00','2026-05-12','bar','21:41:10.040515','bar','bar'),
+ (1,'2025-04-21 16:08:16.033559','',0.4,b'0000',1991,'2013-03-14 09:03:02.016013',NULL,'bar','23:22:08.056231','c','bar'),
+ (4,NULL,'',0.5,b'101000000',2023,'1900-01-01 00:00:00','1991-05-26','bar','08:23:51.037917','bar',''),
+ (5,'2035-09-13 00:00:00','',0.4,b'1110100001001111',2027,'2001-01-13 19:20:36.044577','2019-04-03','foo','08:18:11.001097','','bar'),
+ (6,'1975-08-15 21:42:22.049174','',0.3,b'010010010101',2032,NULL,'2023-01-21','bar','22:08:23.001364','bar','bar'),
+ (4,'2013-05-01 00:00:00','',0.3,b'011101010000110000',2021,'2030-07-16 00:00:00','2027-12-07','e','10:09:49.061627','bar','bar'),
+ (2,'2035-06-20 22:55:45.008894','',0.8,b'11000',2034,'1983-12-20 07:27:43.035034','1986-09-12','bar','19:02:29.013068','bar','foo'),
+ (0,NULL,'',0.1,b'01111010100011',2029,'1978-01-08 00:00:00','1974-12-16','','03:44:02.034839','bar','foo'),
+ (1,'1983-11-04 19:04:57.035319','',0.8,b'100001110100110001010',2001,NULL,'1981-05-05','f','00:00:00','bar','bar'),
+ (5,NULL,'',0.7,b'0011110001101',NULL,NULL,'1999-07-28','bar','20:33:42.039257','x','r'),
+ (3,NULL,'',0.9,b'00110110111',2019,'2008-12-27 00:00:00','2012-03-14','bar','19:12:32.062124','bar','bar'),
+ (8,NULL,'',0.9,b'001011001111',1977,'1995-02-20 00:00:00','1985-02-04','bar','23:08:10.014396','bar','bar'),
+ (0,NULL,NULL,0.9,b'01',2001,'2011-03-16 22:54:22.026461',NULL,'foo','07:07:55.017714','z','m'),
+ (8,'2027-08-03 00:00:00','',0.2,b'110001',2035,'2011-06-24 15:58:37.049649','2028-11-21','qux','16:37:54.001939','d','f'),
+ (2,'1900-01-01 00:00:00','',0.1,b'10',2015,'1973-11-22 15:34:01.047131','2010-08-18','foo','17:43:20.056086','bar','b'),
+ (7,NULL,'',0.7,b'00100100',1974,'1983-04-16 15:00:17.003592',NULL,'qux','00:00:00','bar','foo'),
+ (7,'1980-05-10 20:47:46.049712','',0.0,NULL,2010,'1900-01-01 00:00:00','1974-06-01','foo','08:34:02.056752','bar','qux'),
+ (0,'2029-01-10 19:49:58.002777',NULL,0.4,b'1100',2026,'2007-11-24 04:06:32.038008','1980-02-20','foo','06:01:30.019582','qux','bar'),
+ (8,'2010-01-04 12:54:59.003789','',0.8,b'01001110111010111',1971,'2010-01-17 06:56:30.006700','2007-09-21','u','13:31:53.061759','bar','foo'),
+ (1,'1976-11-17 00:00:00','',0.0,b'00010001011101',2034,'1976-11-08 21:18:21.053929','2029-04-19','','00:38:43.046200','qux','bar'),
+ (4,'1991-06-12 16:01:19.007026','',0.4,b'110111010100101111011001',1997,'2004-03-07 18:06:41.050645',NULL,'','17:23:17.056960','o',''),
+ (4,'2021-12-14 20:59:31.062969',NULL,0.8,b'01100001010111011101000101',NULL,'2034-04-17 02:55:45.046064',NULL,'bar','10:28:15.003445','n','foo'),
+ (85,'1998-09-24 21:01:37.043422','',0.3,b'1001001001111010',1997,'2033-03-23 12:54:48.043906','2030-10-10','r','08:12:29.026018','d','foo'),
+ (5,'2031-11-20 00:00:00','',0.1,b'11010011111',2011,'1989-07-07 16:45:29.060242',NULL,'qux','05:12:14.002326','foo','bar'),
+ (9,'1900-01-01 00:00:00','',0.3,b'0100010',2035,'1900-01-01 00:00:00','1982-12-04','bar',NULL,NULL,'qux'),
+ (8,'2024-11-03 23:31:40.058574','',0.2,b'11001101110101100100001011',2027,'1977-12-18 00:00:00','1972-01-13','tqvbj','16:27:36.004472','qux','f'),
+ (1,'1976-01-06 23:32:58.038263','',0.6,NULL,2020,'2029-03-08 18:36:33.010902','1900-01-01','qux','19:36:37.015269','e','bar'),
+ (9,'1900-01-01 00:00:00','',0.1,b'010010111101111110000',1993,'2000-10-27 16:52:51.015854','1974-12-22','qux','05:46:08.055789','i','bar'),
+ (6,'1900-01-01 00:00:00','',0.0,b'00',2010,'2009-06-09 18:30:10.054617',NULL,'qux','01:36:44.033940','bar',''),
+ (6,'2006-04-13 05:21:03.061942','',0.0,b'0000101101100011010000111',1971,'2032-04-05 16:01:44.056007',NULL,'r','01:08:36.007948',NULL,'bar'),
+ (8,'2001-03-27 10:39:48.064273','',0.2,b'1000111100100100110',2021,'2016-11-21 07:09:28.035220','2020-01-08','qux','21:33:51.036722','','bar'),
+ (6,'2009-11-26 00:00:00','',0.0,b'0000110010001010110111',2009,'2034-02-16 11:01:29.027539','2009-04-12','q','12:01:56.032072','bar','qux'),
+ (2,'1990-03-12 07:26:22.053357','',0.7,b'0110',2002,'1975-12-13 03:14:35.064214','2015-05-04','foo','18:17:43.065361','qux','bar'),
+ (3,'1900-01-01 00:00:00','',0.8,b'0',1990,'2004-03-24 17:19:30.055335','2005-01-21','bar','07:08:14.014929','b','b'),
+ (7,'2012-12-18 00:00:00','',0.5,NULL,1981,'1981-02-17 15:47:55.041049','1989-09-26','bar','09:00:19.031063','t','foo'),
+ (3,'1981-12-09 10:10:34.008107','',0.8,NULL,1976,NULL,'1980-01-20','foo','00:00:00','qux','bar'),
+ (2,'2006-06-05 03:56:10.030366','',0.5,b'001000101000100000100',1996,'1998-08-17 00:00:00','1994-02-11','bar','20:55:21.044208',NULL,'foo'),
+ (4,'1900-01-01 00:00:00',NULL,0.4,b'00111000011000001010000',1980,NULL,NULL,'e','09:37:44.034108','','k'),
+ (2,'2018-03-01 21:14:08.062101','',0.2,b'00001101011101000',1985,'2022-06-09 17:17:31.039498','1900-01-01','bar','00:00:00','j','qux'),
+ (1,'2018-05-06 20:12:14.043515',NULL,NULL,b'1100100000100001101011',NULL,'2020-12-20 11:46:57.017685','1973-04-20','qux','00:00:00','','bar'),
+ (8,'1985-07-12 02:16:53.034909',NULL,0.3,b'10111000100110110101',1997,'1985-11-07 23:07:06.015091','2007-01-08','z','04:14:58.038324','bar','x'),
+ (5,'2027-09-21 16:28:36.016865','',0.9,NULL,1986,'2013-11-16 07:22:14.009509','1900-01-01','qux','16:19:03.023217','bar','d'),
+ (1,'1900-01-01 00:00:00','',0.5,b'010101',2007,'1987-03-23 01:34:02.040253','2004-01-24','bar','00:00:00','qux','t'),
+ (0,NULL,'',0.3,b'10111010001110111011',2030,NULL,'2007-11-17','qux','14:16:15.008674','bar','foo'),
+ (5,'1900-01-01 00:00:00','',0.3,b'1',2004,'1978-03-06 00:00:00','2003-07-08','','09:33:46.000325','','bar'),
+ (207,'2019-10-05 19:24:40.063253','',NULL,b'1010111000110110110000',1977,'1992-01-07 15:50:41.043085','2003-10-24','d','12:50:19.026611','qux','bar'),
+ (1,'2012-07-01 23:30:29.042644','',0.8,b'01111010111001001101',1974,'1976-03-16 00:00:00','2006-01-09','qux','22:22:44.040748','','bar'),
+ (2,'1995-06-21 00:00:00','',0.9,b'000101001100100',2022,'2006-09-23 00:00:00',NULL,'bar','06:13:27.061694','v','qux'),
+ (1,'1900-01-01 00:00:00',NULL,0.8,b'000000001000',2027,'2028-03-20 08:34:05.027629','1999-09-28','bar','01:39:33.047138','foo','qux'),
+ (5,'1996-06-01 05:23:35.020694','',0.9,b'1111001111001110001011001',1996,'1973-12-13 05:51:14.039856','1993-04-13','','20:24:00.040657','foo','bar'),
+ (8,'2000-02-18 12:32:03.020086','',0.3,b'0000111010',2010,'1972-09-12 01:43:50.058850',NULL,'qux','23:12:01.017030','bar','x'),
+ (8,'1992-05-27 02:39:01.058236','',0.7,b'011101110',2032,NULL,'1998-04-03','h','12:22:12.041362','p','bar'),
+ (7,'1900-01-01 00:00:00','',0.3,b'10111111110011010111',1989,'1998-06-08 00:00:00','1993-02-10','qux','12:44:43.060254','h','bar'),
+ (164,'2034-08-09 10:48:51.053786',NULL,0.0,b'00100111',1973,'2026-01-13 19:29:43.039915','2022-03-01','bar','11:51:54.036462','','qux'),
+ (0,'2030-02-22 18:02:11.043075','',0.8,b'011000111111011111111100',2001,'2030-02-09 15:46:56.055798','2026-03-20','bar','10:31:58.002654','q','qux'),
+ (7,'2009-11-19 06:26:11.008028','',0.8,NULL,2004,'2009-07-05 00:00:00','2014-04-22','t','05:45:36.023615',NULL,'u'),
+ (1,'1987-04-17 04:16:29.007028','',0.5,b'00',1976,'1900-01-01 00:00:00','2023-12-07','foo','22:25:07.010419','qux','bar'),
+ (6,NULL,'',0.6,b'0',2003,'2025-04-15 11:19:34.034736','2010-06-20','qux','00:00:00','bar','foo'),
+ (2,'2025-03-26 07:09:22.012297','',0.5,b'00110000001110111110',2033,'1974-03-16 18:35:58.062140','1982-04-07','qux','18:50:57.025695',NULL,'z'),
+ (4,'2032-12-08 13:05:51.020675','',0.4,b'11001001100011',NULL,'1983-08-26 11:47:49.027635','2019-07-08','qux','00:00:00','','x'),
+ (0,'1972-12-10 00:00:00','',NULL,b'00000100010110100000',1978,'1990-12-28 15:20:43.027572','2008-02-23','r','17:48:05.030363','foo','bar'),
+ (6,'1900-01-01 00:00:00',NULL,0.9,b'111000001101010',2026,'1997-08-09 00:00:00','1900-01-01','c','00:00:00','','qux'),
+ (6,NULL,'',0.5,b'011110001001',2010,'1900-01-01 00:00:00','2018-01-11','foo','00:00:00','qux','bar'),
+ (9,'2000-11-10 06:31:29.024423','',0.7,NULL,2004,'1900-01-01 00:00:00','1972-04-10','qux','22:50:18.046302','foo','bar'),
+ (0,'2008-02-11 00:00:00','',0.3,b'111010011',NULL,'1976-10-02 06:40:56.017017','1900-01-01','q','12:50:11.001180',NULL,'foo'),
+ (6,'2032-01-13 00:00:00',NULL,0.7,b'0101110010010110011001000',2006,NULL,'2015-06-08','bar','00:27:52.030995','qux','foo'),
+ (5,NULL,'',0.2,b'101100101000',1993,'2008-03-26 00:00:00','2023-03-25','bar','17:51:32.035040','foo','qux'),
+ (0,NULL,NULL,NULL,b'01110000111011010101',2020,'1988-02-20 19:30:16.015815','2027-02-07','bar','11:18:36.020832','qux','foo'),
+ (8,'1990-02-04 11:52:45.035803','',0.2,b'1',2034,'2014-06-28 16:58:27.046952','2020-12-05','bar','08:36:43.060728','','qux'),
+ (1,NULL,'',0.7,b'110010010111110100110001',2002,'2019-06-19 03:39:03.040619','2001-08-28','bar','01:59:24.036052','foo','qux'),
+ (6,'2003-09-12 14:34:37.035049','',0.3,b'110010',2029,NULL,'2025-11-09','bar','18:51:11.041328','d',''),
+ (9,NULL,'',NULL,b'00010',2005,'2027-07-12 23:36:51.053942','2000-06-04','qux','13:46:39.062130','bar',''),
+ (5,'2035-12-19 04:59:44.044122','',0.8,b'110011011010010101101100',2000,'1980-06-16 02:14:18.040078','1900-01-01','j',NULL,'qux','c'),
+ (4,'1978-06-11 18:53:14.037991','',0.4,b'00000',NULL,'2018-03-13 18:56:39.056433','2020-12-07','foo','17:58:15.029684','bar','y'),
+ (2,NULL,'',0.2,b'100101110010101',1976,'2017-06-12 18:40:22.011803','2021-11-01','qux','15:16:59.059052','foo','bar'),
+ (5,'2017-08-07 01:53:34.056737','',0.1,b'1110101100',1979,'1900-01-01 00:00:00','1900-01-01','foo','03:13:31.046205','bar',REPEAT('a',1693)),
+ (7,'2022-09-25 03:36:08.040842','',0.7,b'11010111110001010',2026,NULL,'2018-04-15','bar','16:08:47.004044','','qux'),
+ (5,'1988-04-05 07:40:37.041464','',0.6,b'101110100110110',NULL,'2011-08-08 02:23:59.013723','2020-01-28','qux','00:00:00','foo','y'),
+ (6,NULL,NULL,0.7,b'1100001',1995,NULL,'2026-02-01','',NULL,'o','qux'),
+ (9,'1985-05-13 00:00:00','',0.5,b'1110101011010100101110',1973,'1975-04-08 00:00:00','2006-09-22','qux','13:43:19.008905','foo','bar'),
+ (7,'2032-07-23 00:00:00','',0.6,b'10100100011110110100',1985,'1997-02-22 02:04:16.040238','1971-05-24','y','10:27:41.006741','i','qux'),
+ (1,'1900-01-01 00:00:00','',0.5,NULL,2013,'2002-09-28 00:00:00','2025-03-17','o','13:27:32.040813','','y'),
+ (8,'2014-08-03 10:02:33.055574','',0.0,b'1',1992,NULL,'1978-12-27','x','10:58:03.022898','foo',''),
+ (9,'2011-05-25 00:00:00','',0.8,b'11001001000011100',2019,NULL,'2003-10-06','qux','00:00:00',NULL,'bar'),
+ (8,'1900-01-01 00:00:00','',0.0,b'101101000010100011011111',2000,'2005-05-18 00:00:00','1995-07-13','bar','13:19:40.057958','foo',''),
+ (4,NULL,'',0.8,b'011011',1972,NULL,'2008-04-16','b','00:00:00','bar','foo'),
+ (8,'2005-07-21 07:54:38.040060','',0.5,b'100',2003,'1900-01-01 00:00:00','1994-09-03','qux','02:36:25.048212','','b'),
+ (7,'2002-07-03 01:08:02.012450','',0.5,b'101100010001101101',1990,'1974-04-15 02:53:22.018939','2002-02-12','','10:40:14.031253','w','c'),
+ (174,'2029-09-28 01:08:52.004131','',NULL,b'001001000011',1976,'2034-12-11 02:11:04.035857','2005-07-18','qux','00:00:00','xd','bar'),
+ (255,'2004-02-02 06:53:55.023459',NULL,NULL,b'111010100',1982,'1983-12-17 00:00:00','2003-12-20','bar','01:23:47.001055','t','qux');
+
+alter table t4 add index(vcol_varchar(64));
+repair table t4;
+repair table t4 extended;
+alter table t4 add index(vvcol_varchar(32));
+repair table t4;
+repair table t4 extended;
+drop table t4;
diff --git a/mysql-test/suite/vcol/t/not_supported.test b/mysql-test/suite/vcol/t/not_supported.test
new file mode 100644
index 00000000..d58b207a
--- /dev/null
+++ b/mysql-test/suite/vcol/t/not_supported.test
@@ -0,0 +1,66 @@
+#
+# MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor
+#
+
+# the following functions must not be supported in persistent columns.
+# but for compatibility reasons it won't be done in a GA version,
+# we'll only fix most critical issues (inconsistent results, crashes)
+
+connect (con1, localhost, root);
+
+set lc_time_names = 'es_MX';
+set time_zone='+10:00';
+set div_precision_increment=20;
+
+create table t1 (a int, b int, v decimal(20,19) as (a/3));
+create table t2 (a int, b int, v int as (a+@a)); drop table t2;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t2 (a int, b int, v int as (a+@a) PERSISTENT);
+create table t3_ok (a int, b int, v int as (a+@@error_count));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t3 (a int, b int, v int as (a+@@error_count) PERSISTENT);
+create table t4 (a int, b int, v int as (@a:=a)); drop table t4;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t4 (a int, b int, v int as (@a:=a) PERSISTENT);
+create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
+
+insert t1 (a,b) values (1,2);
+insert t8 (a,b) values (1234567890,2);
+
+select * from t1;
+select * from t8;
+
+disconnect con1;
+connection default;
+set time_zone='+1:00';
+flush tables;
+
+select * from t1;
+select * from t8;
+
+drop table t1, t3_ok, t8;
+
+--echo #
+--echo # Bug#33141966 - INCONSISTENT BEHAVIOR IF A COLUMN OF TYPE SERIAL IS SET AS GENERATED
+--echo #
+--error ER_PARSE_ERROR
+create table t1 (a int, b serial as (a+1));
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b real as (rand()), c real as (b) stored);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int, b real as (rand()), c real as (b) unique);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int auto_increment primary key,
+ b int as (a+1), c int as (b+1) stored);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int auto_increment primary key,
+ b int as (a+1), c int as (b+1) unique);
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/suite/vcol/t/partition.test b/mysql-test/suite/vcol/t/partition.test
new file mode 100644
index 00000000..408990b2
--- /dev/null
+++ b/mysql-test/suite/vcol/t/partition.test
@@ -0,0 +1,80 @@
+#
+# test keyread on an indexed vcol
+#
+--source include/have_partition.inc
+
+CREATE TABLE t1 (
+ id INT NOT NULL,
+ store_id INT NOT NULL,
+ x INT GENERATED ALWAYS AS (id + store_id)
+)
+PARTITION BY RANGE (store_id) (
+ PARTITION p0 VALUES LESS THAN (6),
+ PARTITION p1 VALUES LESS THAN (11),
+ PARTITION p2 VALUES LESS THAN (16),
+ PARTITION p3 VALUES LESS THAN (21)
+);
+INSERT t1 (id, store_id) VALUES(1, 2), (3, 4), (3, 12), (4, 18);
+CREATE INDEX idx ON t1(x);
+SELECT x FROM t1;
+DROP TABLE t1;
+
+#
+# MDEV-15626 Assertion on update virtual column in partitioned table
+#
+create table t1 (i int, v int as (i) virtual)
+partition by range columns (i)
+subpartition by hash(v) subpartitions 3 (
+ partition p1 values less than (3),
+ partition pn values less than (maxvalue));
+insert t1 set i= 0;
+set statement sql_mode= '' for update t1 set i= 1, v= 2;
+drop table t1;
+
+--echo #
+--echo # MDEV-18734 ASAN heap-use-after-free in my_strnxfrm_simple_internal upon update on versioned partitioned table
+--echo #
+--echo # Cover queue_fix() in ha_partition::handle_ordered_index_scan()
+create or replace table t1 (
+ x int auto_increment primary key,
+ b text, v mediumtext as (b) virtual,
+ index (v(10))
+) partition by range columns (x) (
+ partition p1 values less than (3),
+ partition p2 values less than (6),
+ partition p3 values less than (9),
+ partition p4 values less than (12),
+ partition p5 values less than (15),
+ partition p6 values less than (17),
+ partition p7 values less than (19),
+ partition p8 values less than (21),
+ partition p9 values less than (23),
+ partition p10 values less than (25),
+ partition p11 values less than (27),
+ partition p12 values less than (29),
+ partition p13 values less than (31),
+ partition p14 values less than (33),
+ partition p15 values less than (35),
+ partition pn values less than (maxvalue));
+insert into t1 (b) values
+(repeat('q', 8192)), (repeat('z', 8192)), (repeat('a', 8192)), (repeat('b', 8192)),
+(repeat('x', 8192)), (repeat('y', 8192));
+
+insert t1 (b) select b from t1;
+insert t1 (b) select b from t1;
+insert t1 (b) select b from t1;
+insert t1 (b) select b from t1;
+
+select x, left(b, 10), left(v, 10) from t1 where x > 30 and x < 60 order by v;
+update t1 set b= 'bar' where v > 'a' limit 20;
+
+drop table t1;
+
+--echo # Cover return_top_record() in ha_partition::handle_ordered_index_scan()
+create table t1 (x int primary key, b tinytext, v text as (b) virtual)
+partition by range columns (x) (
+ partition p1 values less than (4),
+ partition pn values less than (maxvalue));
+insert into t1 (x, b) values (1, ''), (2, ''), (3, 'a'), (4, 'b');
+update t1 set b= 'bar' where x > 0 order by v limit 2;
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/races.test b/mysql-test/suite/vcol/t/races.test
new file mode 100644
index 00000000..1bf4e43d
--- /dev/null
+++ b/mysql-test/suite/vcol/t/races.test
@@ -0,0 +1,22 @@
+#
+# MDEV-17349 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed on concurrent SELECT and DELETE after RENAME from table with index on virtual column
+#
+source include/have_innodb.inc;
+source include/have_debug_sync.inc;
+create table t1 (f text, vf tinytext as (f), key (vf(64))) engine=innodb;
+insert t1 (f) values ('foo');
+flush tables;
+connect con1,localhost,root,,test;
+set debug_sync='TABLE_after_field_clone WAIT_FOR go';
+send delete from t1;
+connection default;
+let $wait_condition= select state like 'debug sync point%' from information_schema.processlist;
+source include/wait_condition.inc;
+select * from t1;
+set debug_sync='now SIGNAL go';
+connection con1;
+reap;
+disconnect con1;
+connection default;
+drop table t1;
+set debug_sync='reset';
diff --git a/mysql-test/suite/vcol/t/range.test b/mysql-test/suite/vcol/t/range.test
new file mode 100644
index 00000000..a4593d8b
--- /dev/null
+++ b/mysql-test/suite/vcol/t/range.test
@@ -0,0 +1,10 @@
+#
+# MDEV-11518 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in Field_long::val_int()
+#
+create table t1 (pk int, i int, v int as (i*2) virtual, primary key (pk), key (v)) engine=myisam;
+insert into t1 (pk,i) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+create table t2 (a int, b int) engine=myisam;
+insert into t2 values (1,2),(2,4);
+select * from t1 inner join t2 on ( t2.b = t1.v or t2.a = t1.pk );
+drop table t1, t2;
+
diff --git a/mysql-test/suite/vcol/t/rpl_vcol.test b/mysql-test/suite/vcol/t/rpl_vcol.test
new file mode 100644
index 00000000..d893ebac
--- /dev/null
+++ b/mysql-test/suite/vcol/t/rpl_vcol.test
@@ -0,0 +1,70 @@
+################################################################################
+# 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.default_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
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/vcol/t/update.test b/mysql-test/suite/vcol/t/update.test
new file mode 100644
index 00000000..6065f926
--- /dev/null
+++ b/mysql-test/suite/vcol/t/update.test
@@ -0,0 +1,129 @@
+#
+# Test how UPDATE detects what columns need to be read (or generated) in a row
+#
+# stored column depends on virtual column depends on updated column.
+# this tests TABLE::mark_virtual_columns_for_write()
+#
+create table t1 (a int, b int as (a+1), c int as (b+1) stored);
+insert t1 set a=1;
+select * from t1;
+update t1 set a=2;
+select * from t1;
+drop table t1;
+#
+# one keypart is virtual, the other keypart is updated
+# this tests TABLE::mark_columns_needed_for_update()
+#
+create table t1 (a int, c int as(a), p varchar(20) as(rtrim(y)), y char(20), index (p,c));
+show create table t1;
+insert into t1 (a,y) values(1, "yyy");
+update t1 set a = 100 where a = 1;
+check table t1;
+drop table t1;
+
+#
+# note: prefix keys below
+#
+create table t1 (
+ a varchar(10000),
+ b varchar(3000),
+ c varchar(14000) generated always as (concat(a,b)) virtual,
+ d varchar(5000) generated always as (b) virtual,
+ e int(11) generated always as (10) virtual,
+ h int(11) not null primary key,
+ index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+
+create table t1 (
+ a varchar(10000),
+ b varchar(3000),
+ c varchar(14000) generated always as (concat(a,b)) virtual,
+ i varchar(5000) generated always as (b) virtual,
+ d varchar(5000) generated always as (i) virtual,
+ e int(11) generated always as (10) virtual,
+ h int(11) not null primary key,
+ index(c(100), d(20)));
+insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
+update t1 set a = repeat(cast(1 as char), 2000);
+drop table t1;
+#
+# UPDATE disguised as INSERT
+#
+create table t1(a blob not null, b int, c varbinary (10) generated always as (a) virtual, unique (c(9)));
+insert t1 (a,b) values ('a', 1);
+replace t1 set a = 'a',b =1;
+insert t1 (a,b) values ('a', 1) on duplicate key update a='b', b=2;
+select * from t1;
+drop table t1;
+
+#
+# multi-UPDATE and const tables
+#
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (9,0);
+create table t2 select * from t;
+update t, t2 set t.b=10 where t.a=t2.a;
+check table t; select * from t;
+drop table t, t2;
+
+#
+# blobs
+# This tests BLOB_VALUE_ORPHANAGE
+#
+create table t1 (a int, b int, c int, d int, e int);
+insert t1 values (1,2,3,4,5), (1,2,3,4,5);
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+create table t (a int primary key,
+ b int, c blob as (b), index (c(57)),
+ d blob, e blob as (d), index (e(57)))
+ replace select * from t1;
+check table t; select * from t;
+update t set a=10, b=1, d=1;
+check table t; select * from t;
+replace t (a,b,d) values (10,2,2);
+check table t; select * from t;
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+insert t(a,b,d) values (10) on duplicate key update b=3;
+insert t(a,b,d) values (10,2,2) on duplicate key update b=3, d=3;
+check table t; select * from t;
+replace t (a,b,d) select 10,4,4;
+check table t; select * from t;
+insert t(a,b,d) select 10,4,4 on duplicate key update b=5, d=5;
+check table t; select * from t;
+replace delayed t (a,b,d) values (10,6,6);
+flush tables t;
+check table t; select * from t;
+insert delayed t(a,b,d) values (10,6,6) on duplicate key update b=7, d=7;
+flush tables t;
+check table t; select * from t;
+--write_file $MYSQLTEST_VARDIR/tmp/vblobs.txt
+10 8 foo 8 foo
+EOF
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval load data infile '$MYSQLTEST_VARDIR/tmp/vblobs.txt' replace into table t
+--remove_file $MYSQLTEST_VARDIR/tmp/vblobs.txt
+check table t; select * from t;
+update t set a=11, b=9, d=9 where a>5;
+check table t; select * from t;
+create table t2 select * from t;
+update t, t2 set t.b=10, t.d=10 where t.a=t2.a;
+check table t; select * from t;
+update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
+check table t; select * from t;
+drop table t, t1, t2;
+
+#
+# MDEV-13623 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in virtual longlong Field_long::val_int
+#
+create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
+insert into t (f1,f2) values (1,1),(2,2);
+create view v as
+ select a2.f1, a2.f2, a1.f3
+ from t a1, t a2
+ where a2.f3 <> 0
+ with local check option;
+update v set f3 = 52;
+drop view v;
+drop table t;
diff --git a/mysql-test/suite/vcol/t/update_binlog.test b/mysql-test/suite/vcol/t/update_binlog.test
new file mode 100644
index 00000000..458aac48
--- /dev/null
+++ b/mysql-test/suite/vcol/t/update_binlog.test
@@ -0,0 +1,14 @@
+#
+# Check that vcol update works with binlog enabled
+#
+
+--source include/have_binlog_format_row.inc
+
+set binlog_row_image="FULL";
+set @@default_storage_engine="myisam";
+
+--source update.test
+
+set binlog_row_image="MINIMAL";
+
+--source update.test
diff --git a/mysql-test/suite/vcol/t/upgrade.test b/mysql-test/suite/vcol/t/upgrade.test
new file mode 100644
index 00000000..146495d8
--- /dev/null
+++ b/mysql-test/suite/vcol/t/upgrade.test
@@ -0,0 +1,28 @@
+#
+# MDEV-12936 upgrade to 10.2.6 failed upon tables with virtual columns
+#
+let $datadir=`select @@datadir`;
+copy_file std_data/vcol_autoinc.frm $datadir/test/vcol_autoinc.frm;
+copy_file std_data/vcol_autoinc.MYD $datadir/test/vcol_autoinc.MYD;
+copy_file std_data/vcol_autoinc.MYI $datadir/test/vcol_autoinc.MYI;
+check table vcol_autoinc for upgrade;
+show create table vcol_autoinc;
+select * from vcol_autoinc;
+insert vcol_autoinc (pk) values (1);
+select * from vcol_autoinc;
+drop table vcol_autoinc;
+
+#
+# MDEV-17909 Problem by MariaDB Update 10.1.32 -> 10.2.19 (Incorrect information in file: .frm)
+#
+source include/have_partition.inc;
+copy_file std_data/mdev17909#P#p20181029.MYD $datadir/test/t1#P#p20181029.MYD;
+copy_file std_data/mdev17909#P#p20181029.MYI $datadir/test/t1#P#p20181029.MYI;
+copy_file std_data/mdev17909#P#p20181128.MYD $datadir/test/t1#P#p20181128.MYD;
+copy_file std_data/mdev17909#P#p20181128.MYI $datadir/test/t1#P#p20181128.MYI;
+copy_file std_data/mdev17909.frm $datadir/test/t1.frm;
+copy_file std_data/mdev17909.par $datadir/test/t1.par;
+check table t1 for upgrade;
+flush tables;
+show create table t1;
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/vcol_archive.test b/mysql-test/suite/vcol/t/vcol_archive.test
new file mode 100644
index 00000000..b708b3a4
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_archive.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_blackhole.test b/mysql-test/suite/vcol/t/vcol_blackhole.test
new file mode 100644
index 00000000..6cbc68a9
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_blackhole.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs.test b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs.test
new file mode 100644
index 00000000..d00ab827
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs.test
@@ -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.default_storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+# none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source vcol_blocked_sql_funcs_main.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
diff --git a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc
new file mode 100644
index 00000000..52324176
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc
@@ -0,0 +1,359 @@
+################################################################################
+# 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.
+# As PERSISTANT has higher level checks than VIRTUAL, we use VIRTUAL
+# to check for things that should not work for either VIRTUAL or PERSISTENT
+#
+
+--echo # RAND()
+create or replace table t1 (b double as (rand()));
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (b double as (rand()) PERSISTENT);
+
+--echo # LOAD_FILE()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(64), b varchar(1024) as (load_file(a)));
+
+--echo # CURDATE()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (curdate()) PERSISTENT);
+
+--echo # CURRENT_DATE(), CURRENT_DATE
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (current_date) PERSISTENT);
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (current_date()) PERSISTENT);
+
+--echo # CURRENT_TIME(), CURRENT_TIME
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (current_time) PERSISTENT);
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (current_time()) PERSISTENT);
+
+--echo # CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (current_timestamp()) PERSISTENT);
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (current_timestamp) PERSISTENT);
+
+--echo # CURTIME()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime as (curtime()) PERSISTENT);
+
+--echo # LOCALTIME(), LOCALTIME
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b varchar(10) as (localtime()) PERSISTENT);
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b varchar(10) as (localtime) PERSISTENT);
+
+--echo # LOCALTIMESTAMP, LOCALTIMESTAMP()(v4.0.6)
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b varchar(10) as (localtimestamp()) PERSISTENT);
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b varchar(10) as (localtimestamp) PERSISTENT);
+
+--echo # NOW()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b varchar(10) as (now()) PERSISTENT);
+
+--echo # SYSDATE()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b varchar(10) as (sysdate()) PERSISTENT);
+
+--echo # UNIX_TIMESTAMP()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b datetime as (unix_timestamp()) PERSISTENT);
+
+--echo # UTC_DATE()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b datetime as (utc_date()) PERSISTENT);
+
+--echo # UTC_TIME()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b datetime as (utc_time()) PERSISTENT);
+
+--echo # UTC_TIMESTAMP()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b datetime as (utc_timestamp()) PERSISTENT);
+
+--echo # WEEK() - one argument version
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a datetime, b datetime as (week(a)) PERSISTENT);
+
+--echo # MATCH()
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ create or replace table t1 (a varchar(32), b bool as (match a against ('sample text')) PERSISTENT);
+
+--echo # BENCHMARK()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (benchmark(a,3)));
+
+--echo # CHARSET()
+create or replace table t1 (a varchar(64), b varchar(64) as (charset(a)) PERSISTENT);
+
+--echo # COERCIBILITY()
+create or replace table t1 (a varchar(64), b int as (coercibility(a)) PERSISTENT);
+
+--echo # COLLATION()
+create or replace table t1 (a varchar(64), b varchar(64) as (collation(a)) PERSISTENT);
+
+--echo # CONNECTION_ID()
+create or replace table t1 (a int as (connection_id()));
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int as (connection_id()) PERSISTENT);
+
+--echo # DATABASE()
+create or replace table t1 (a varchar(32) as (database()));
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (database()) PERSISTENT);
+
+--echo # FOUND_ROWS()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (found_rows()));
+
+--echo # GET_LOCK()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (get_lock(a,10)));
+
+--echo # IS_FREE_LOCK()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (is_free_lock(a)));
+
+--echo # IS_USED_LOCK()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (is_used_lock(a)));
+
+--echo # LAST_INSERT_ID()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int as (last_insert_id()));
+
+--echo # MASTER_POS_WAIT()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(32), b int as (master_pos_wait(a,0,2)));
+
+--echo # NAME_CONST()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(32) as (name_const('test',1)));
+
+--echo # RELEASE_LOCK()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(32), b int as (release_lock(a)));
+
+--echo # ROW_COUNT()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int as (row_count()));
+
+--echo # SCHEMA()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(32) as (schema()) PERSISTENT);
+
+--echo # SESSION_USER()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(32) as (session_user()) PERSISTENT);
+
+--echo # SLEEP()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (sleep(a)));
+
+--echo # SYSTEM_USER()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(32) as (system_user()) PERSISTENT);
+
+--echo # USER()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (user()) PERSISTENT);
+
+--echo # UUID_SHORT()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024) as (uuid_short()) PERSISTENT);
+
+--echo # UUID()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024) as (uuid()) PERSISTENT);
+
+--echo # VALUES()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (value(a)));
+
+--echo # VERSION()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(1024), b varchar(1024) as (version()) PERSISTENT);
+
+--echo # ENCRYPT()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (encrypt(a)) PERSISTENT);
+
+--echo # Stored procedures
+
+delimiter //;
+create procedure p1()
+begin
+ select current_user();
+end //
+
+create function f1()
+returns int
+begin
+ return 1;
+end //
+
+delimiter ;//
+
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int as (p1()) PERSISTENT);
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int as (f1()) PERSISTENT);
+
+drop procedure p1;
+drop function f1;
+
+--echo # Unknown functions
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int as (f1()) PERSISTENT);
+
+--echo #
+--echo # GROUP BY FUNCTIONS
+--echo #
+
+--echo # AVG()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (avg(a)));
+
+--echo # BIT_AND()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (bit_and(a)));
+
+--echo # BIT_OR()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (bit_or(a)));
+
+--echo # BIT_XOR()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (bit_xor(a)));
+
+--echo # COUNT(DISTINCT)
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (count(distinct a)));
+
+--echo # COUNT()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (count(a)));
+
+--echo # GROUP_CONCAT()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a varchar(32), b int as (group_concat(a,'')));
+
+--echo # MAX()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (max(a)));
+
+--echo # MIN()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (min(a)));
+
+--echo # STD()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (std(a)));
+
+--echo # STDDEV_POP()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (stddev_pop(a)));
+
+--echo # STDDEV_SAMP()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (stddev_samp(a)));
+
+--echo # STDDEV()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (stddev(a)));
+
+--echo # SUM()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (sum(a)));
+
+--echo # VAR_POP()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (var_pop(a)));
+
+--echo # VAR_SAMP()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (var_samp(a)));
+
+--echo # VARIANCE()
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as (variance(a)));
+
+--echo #
+--echo # XML FUNCTIONS
+--echo #
+
+--echo # ExtractValue()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (ExtractValue(a,'//b[$@j]')) PERSISTENT);
+
+--echo # UpdateXML()
+create or replace table t1 (a varchar(1024), b varchar(1024) as (UpdateXML(a,'/a','<e>fff</e>')) PERSISTENT);
+
+--echo #
+--echo # Sub-selects
+--echo #
+
+create or replace table t1 (a int);
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t2 (a int, b int as (select count(*) from t1));
+drop table t1;
+
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace table t1 (a int, b int as ((select 1)));
+-- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace 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_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create or replace 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 or replace table t1 (a int, b varchar(300) as (concat(a,'$tmp_long_string')));
+drop table t1;
+let $tmp_long_string = `SELECT repeat('a',243)`;
+eval create or replace table t1 (a int, b varchar(16384) as (concat(a,'$tmp_long_string')));
+
+--disable_query_log
+let $tmp_long_string = `SELECT repeat('a',65535)`;
+--error ER_EXPRESSION_IS_TOO_BIG
+eval create or replace table t1 (a int, b varchar(16384) as (concat(a,'$tmp_long_string')));
+--enable_query_log
+
+--echo #
+--echo # Constant expression
+create or replace table t1 (a int as (PI()) PERSISTENT);
+
+drop table if exists t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a timestamp, b varchar(255) as (date_format(a, '%w %a %m %b')) stored);
diff --git a/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test b/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test
new file mode 100644
index 00000000..6fb6a504
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_column_def_options_innodb.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test b/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test
new file mode 100644
index 00000000..63081429
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_column_def_options_myisam.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_csv.test b/mysql-test/suite/vcol/t/vcol_csv.test
new file mode 100644
index 00000000..0c218df6
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_csv.test
@@ -0,0 +1,48 @@
+################################################################################
+# 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.default_storage_engine = 'CSV';
+
+##### Workarounds for known open engine specific bugs
+# none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+
+#------------------------------------------------------------------------------#
+--source suite/vcol/inc/vcol_unsupported_storage_engines.inc
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
diff --git a/mysql-test/suite/vcol/t/vcol_handler_aria.test b/mysql-test/suite/vcol/t/vcol_handler_aria.test
new file mode 100644
index 00000000..0787321e
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_handler_aria.test
@@ -0,0 +1,52 @@
+################################################################################
+# t/vcol_handler_maria.test #
+# #
+# Purpose: #
+# Testing HANDLER.
+# #
+# Maria branch #
+# #
+#------------------------------------------------------------------------------#
+# Original Author: Andrey Zhakov #
+# Original Date: 2008-09-04 #
+# Change Author: #
+# Change Date: #
+# Change: #
+################################################################################
+
+--source include/have_maria.inc
+
+#
+# NOTE: PLEASE DO NOT ADD NOT MARIA 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.default_storage_engine = 'maria';
+
+##### 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
diff --git a/mysql-test/suite/vcol/t/vcol_handler_innodb.test b/mysql-test/suite/vcol/t/vcol_handler_innodb.test
new file mode 100644
index 00000000..c86cbd0d
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_handler_innodb.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_handler_myisam.test b/mysql-test/suite/vcol/t/vcol_handler_myisam.test
new file mode 100644
index 00000000..424752d9
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_handler_myisam.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test b/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test
new file mode 100644
index 00000000..fd1af0ab
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_ins_upd_innodb.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test b/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test
new file mode 100644
index 00000000..d73d0aa6
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_ins_upd_myisam.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_keys_aria.test b/mysql-test/suite/vcol/t/vcol_keys_aria.test
new file mode 100644
index 00000000..b7ac0d26
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_keys_aria.test
@@ -0,0 +1,3 @@
+--source include/have_maria.inc
+--error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
+create table t1 (a int, b int as (a+1), c int, index(b)) engine=aria;
diff --git a/mysql-test/suite/vcol/t/vcol_keys_innodb.opt b/mysql-test/suite/vcol/t/vcol_keys_innodb.opt
new file mode 100644
index 00000000..778b4443
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_keys_innodb.opt
@@ -0,0 +1 @@
+--innodb-sort-buffer-size=64k
diff --git a/mysql-test/suite/vcol/t/vcol_keys_innodb.test b/mysql-test/suite/vcol/t/vcol_keys_innodb.test
new file mode 100644
index 00000000..488a2b93
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_keys_innodb.test
@@ -0,0 +1,137 @@
+###############################################################################
+# 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 INNODB 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.default_storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+# none
+
+#-----------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+let $with_foreign_keys = 1;
+--source suite/vcol/inc/vcol_keys.inc
+
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#-----------------------------------------------------------------------------#
+# Execute storage engine specific tests
+#-----------------------------------------------------------------------------#
+
+--echo #
+--echo # MDEV-11737 Failing assertion: block->magic_n == MEM_BLOCK_MAGIC_N
+--echo #
+
+CREATE TABLE t1 (i INT PRIMARY KEY, vi INT AS (i*2) VIRTUAL UNIQUE)
+ENGINE=InnoDB;
+CREATE TABLE t2 (i INT) ENGINE=InnoDB;
+ALTER TABLE t1 ADD COLUMN col INT;
+SELECT * FROM t1 WHERE vi < 2;
+DROP TABLE t1, t2;
+
+
+#
+# MDEV-11604 Assertion `!check_datetime_range(ltime)' failed in TIME_to_longlong_datetime_packed
+#
+create table t1 (
+ pk int auto_increment,
+ col_varchar varchar(847) not null default '',
+ col_int bigint(15) unsigned zerofill,
+ col_datetime datetime(3) not null default '1900-01-01 00:00:00',
+ col_time time(5) not null default '00:00:00',
+ col_blob text,
+ col_bit bit(34),
+ col_year year,
+ col_char char(10),
+ col_dec decimal(18,9) not null default 0,
+ col_enum enum('','a','b','c','d','e','f','foo','bar') not null default '',
+ col_date date not null default '1900-01-01',
+ col_timestamp timestamp(3) not null default '1971-01-01 00:00:00',
+ vcol_datetime datetime as (truncate(col_datetime,0)) virtual,
+ vcol_dec decimal(18,9) zerofill as (col_dec) virtual,
+ vcol_bit bit(63) as (col_bit) virtual,
+ vcol_char binary(51) as (col_char) virtual,
+ vcol_timestamp timestamp(5) as (col_timestamp) virtual,
+ vcol_enum enum('','a','b','c','d','e','f','foo','bar') as (col_enum) virtual,
+ vcol_int tinyint(48) zerofill as (col_int) virtual,
+ vcol_time time(4) as (col_time) virtual,
+ vcol_varchar varbinary(3873) as (col_varchar) virtual,
+ vcol_year year as (col_year) virtual,
+ vcol_date date as (col_date) virtual,
+ vcol_blob longtext as (col_blob) virtual,
+ primary key(pk)
+ ) engine=innodb;
+
+insert into t1 (col_varchar,col_int,col_datetime,col_time,col_blob,col_bit,col_year,col_char,col_dec,col_enum,col_date,col_timestamp) values
+ ('foo',1,'2010-05-08 13:08:12.034783','18:32:14','foo',b'0111110101001001',1992,'f',0.2,'','1994-12-26','2019-01-11 00:00:00'),
+ ('bar',6,'1900-01-01 00:00:00','00:00:00','bar',b'10011000001101011000101',1985,'b',0.7,'','2028-04-06','1971-01-01 00:00:00');
+
+alter table t1 add index(vcol_datetime);
+drop table t1;
+
+
+#
+# MDEV-11704 InnoDB: Failing assertion: dfield_is_null(dfield2) || dfield2->data
+#
+create table t1 (
+ pk int,
+ col_blob mediumtext not null default '',
+ vcol_blob tinyblob as (col_blob) virtual,
+ col_char char(22) null,
+ primary key(pk),
+ index(col_char,vcol_blob(64))
+ ) engine=innodb;
+insert ignore into t1 (pk) values (1),(2);
+update t1 set col_char = 'foo' where pk = 1;
+drop table t1;
+
+#
+# MDEV-20799 DROP Virtual Column crashes MariaDB
+#
+--source include/have_sequence.inc
+create table t1 (
+ id int not null primary key,
+ a varchar(200),
+ b varchar(200),
+ c int,
+ va char(200) generated always as (ucase(a)) virtual,
+ vb char(200) generated always as (ucase(b)) virtual,
+ key (c,va,vb)
+) engine=innodb;
+insert t1 (id,a,c) select seq,seq,seq from seq_1_to_330;
+select IF(@@innodb_sort_buffer_size < count(*)*200, 'GOOD', 'WRONG SIZE') from t1;
+alter table t1 drop column va;
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/vcol_keys_myisam.test b/mysql-test/suite/vcol/t/vcol_keys_myisam.test
new file mode 100644
index 00000000..ab75703f
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_keys_myisam.test
@@ -0,0 +1,315 @@
+--source include/have_sequence.inc
+--let $datadir= `select @@datadir`
+###############################################################################
+# 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
+SET @@session.default_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
+
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
+
+#-----------------------------------------------------------------------------#
+# Execute storage engine specific test
+#-----------------------------------------------------------------------------#
+
+--echo #
+--echo # Original test
+--echo #
+
+create table t1 (a int, b int as (a+1), c int, index(b));
+insert t1 (a,c) values (0x7890abcd, 0x76543210);
+insert t1 (a,c) select seq, sin(seq)*10000 from seq_1_to_1000;
+explain select * from t1 where b=10;
+select * from t1 where b=10;
+--replace_result $datadir datadir
+--exec $MYISAMCHK -d $datadir/test/t1
+update t1 set a=20 where b=10;
+select * from t1 where b=10;
+select * from t1 where b=21;
+delete from t1 where b=21;
+select * from t1 where b=21;
+alter table t1 add column d char(20) as (concat(a,c));
+select * from t1 where b=11;
+create index i on t1 (d);
+check table t1;
+select * from t1 where b=11;
+check table t1 quick;
+select * from t1 where b=11;
+check table t1 medium;
+select * from t1 where b=11;
+check table t1 extended;
+show keys from t1;
+select * from t1 where b=11;
+delete from t1 where b=12;
+analyze table t1;
+show keys from t1;
+select * from t1 where b=11;
+optimize table t1;
+show keys from t1;
+select * from t1 where b=11;
+repair table t1;
+select * from t1 where b=11;
+repair table t1 quick;
+select * from t1 where b=11;
+repair table t1 extended;
+select * from t1 where b=11;
+repair table t1 use_frm;
+select * from t1 where b=11;
+update t1 set a=30 where b=11;
+select * from t1 where b=11;
+select * from t1 where b=31;
+
+--error 1
+--exec $MYISAMCHK $datadir/test/t1
+--error 1
+--exec $MYISAMCHK -r $datadir/test/t1
+drop table t1;
+
+--echo #
+--echo # MDEV-11606 Server crashes in mi_make_key / sort_key_read
+--echo #
+
+CREATE TABLE t1 (
+ pk BIGINT AUTO_INCREMENT,
+ col_date DATE NULL,
+ col_datetime DATETIME(1) NULL,
+ col_int TINYINT(13) UNSIGNED ZEROFILL NULL,
+ col_varchar VARBINARY(2222) NULL,
+ col_timestamp TIMESTAMP(2) NULL,
+ col_bit BIT(64) NOT NULL DEFAULT 0,
+ col_blob MEDIUMBLOB NULL,
+ col_dec DECIMAL(10,9) ZEROFILL NOT NULL DEFAULT 0,
+ col_time TIME(4) NULL,
+ col_year YEAR NOT NULL DEFAULT '1970',
+ col_char CHAR(129) NULL,
+ col_enum SET('','a','b','c','d','e','f','foo','bar') NULL,
+ vcol_dec DECIMAL(50,18) ZEROFILL AS (col_dec) VIRTUAL,
+ vcol_bit BIT(48) AS (col_bit) VIRTUAL,
+ vcol_char CHAR(224) AS (col_char) VIRTUAL,
+ vcol_datetime DATETIME(4) AS (col_datetime) VIRTUAL,
+ vcol_year YEAR AS (col_year) VIRTUAL,
+ vcol_varchar VARBINARY(356) AS (col_varchar) VIRTUAL,
+ vcol_blob MEDIUMBLOB AS (col_blob) VIRTUAL,
+ vcol_timestamp TIMESTAMP(5) AS (col_timestamp) VIRTUAL,
+ vcol_int BIGINT(46) AS (col_int) VIRTUAL,
+ vcol_time TIME(1) AS (col_time) VIRTUAL,
+ vcol_date DATE AS (col_date) VIRTUAL,
+ vcol_enum SET('','a','b','c','d','e','f','foo','bar') AS (col_enum) VIRTUAL,
+ UNIQUE(pk),
+ PRIMARY KEY(pk)
+ ) ENGINE=MyISAM;
+
+--disable_query_log
+INSERT INTO t1 (col_date,col_datetime,col_int,col_varchar,col_timestamp,col_bit,col_blob,col_dec,col_time,col_year,col_char,col_enum) VALUES
+ (NULL,'2011-04-17 15:46:11.056462',6,'rsprn','1980-01-01 00:00:00',b'0001011111000111001110000110100110010101101','spr',0.0,'00:00:00',1988,'p',''),
+ ('2007-05-18',NULL,5,'rnwg','2009-07-07 23:46:32.052699',b'01010','n',0.6,'04:35:56.018027',1995,'wgrpq',''),
+ ('1994-03-16','2006-03-15 22:48:25.013225',7,'grpquarw','2034-05-17 10:51:23.048265',b'0001011101001011000111101','rp',0.3,'15:13:22.043368',2004,'pq',''),
+ ('1980-01-01','1987-06-01 04:14:04.027480',1,'qu','1989-07-05 09:46:16.038513',b'001111011000100011100111010100101010000100010100101','uar',0.6,'11:56:35.031314',1986,'',''),
+ ('2014-08-16','2021-01-08 20:59:16.041252',0,'arw','2022-12-20 22:48:53.014627',b'110110101100001011001110110100','m',0.6,'17:26:26.039855',2008,'rw',''),
+ ('1981-12-02','1992-02-10 09:29:41.028674',6,'wk','2017-09-25 10:37:25.043516',b'010101001110111010101001101000101010',NULL,0.7,'00:00:00',2035,'kaz',''),
+ ('2022-11-11','2029-03-07 17:24:19.043489',122,'a','1980-01-01 00:00:00',b'0001100111011','z',0.0,'10:23:45.050733',2018,'a',''),
+ ('2004-03-12','1979-02-18 00:00:00',0,'zjeiwvd','1998-07-03 16:09:05.053954',b'0000110101111001001110100100111001111111100001110','',0.4,'07:43:46.015324',2028,'je',''),
+ ('2016-08-08','1986-03-10 00:00:00',3,'eiwv','2025-08-07 12:24:53.040869',b'010001101110100111111','iw',0.3,'02:48:45.058781',2020,'',''),
+ ('1979-02-25',NULL,2,'wvd','1980-01-01 00:00:00',b'010','vdm',0.1,'13:35:24.021296',1995,'dmd',''),
+ ('2012-04-19','2034-10-06 23:29:21.057367',9,'mdiv','2022-05-16 05:28:40.005808',b'110111111101000010011011001','divj',0.3,'11:24:50.017885',1997,'iv',''),
+ ('2009-10-13','1997-01-21 13:04:34.011524',1,'vjqs','1980-01-01 00:00:00',b'11110011100101011100001110110000101001100010000011110110011','j',0.7,'00:00:00',2008,'qsxmh',''),
+ ('2012-01-01','2011-06-23 06:11:33.014723',9,'r','2022-04-27 05:29:32.023395',b'1001011010101100100111','',0.5,'03:34:01.048002',1976,'sx',''),
+ ('2007-08-24','2012-01-24 22:16:53.014811',2,'fpp','2005-10-11 08:58:32.021273',b'011011111011',NULL,0.4,'18:11:17.036115',2026,'m',''),
+ (NULL,'1985-05-28 00:00:00',7,'hjw','2030-06-10 10:15:54.061818',b'0011110101001100011011000101010','',0.5,'02:03:21.020237',1994,'z',''),
+ ('2006-09-09','2002-11-10 06:16:27.008631',0,'jw','2030-07-16 00:00:00',b'11101110111101000010101110000010001110110001001101110100','wa',0.8,'00:00:00',1974,'',''),
+ ('1993-04-22','1980-01-01 00:00:00',3,'a','2020-02-06 08:11:00.051515',b'001110110010','gew',0.4,'11:59:05.013933',1998,NULL,''),
+ ('1985-11-05','2019-12-24 04:13:43.062741',7,'foo','1986-07-02 00:00:00',b'10100110001010100011111111101011011101001110010110101100110000','',0.5,'17:32:55.060182',1978,'w',''),
+ ('2007-02-20','2033-10-16 18:47:42.006517',1,'clc','1971-10-14 00:00:00',b'100001010','',0.1,'20:38:42.062598',2004,'lcfy',''),
+ ('1979-12-10','1972-08-04 00:00:00',8,'','2021-12-24 04:51:09.011443',b'011010010010010010011101000010110011110110110010100010','e',0.1,'23:08:10.014396',2026,'cfykywl',''),
+ ('2002-07-04',NULL,NULL,'fyky','1980-11-02 00:00:00',b'10000010111010000110','f',0.6,'13:07:14.014203',1979,'ykywl',''),
+ ('2019-02-15','2004-08-28 10:16:46.053753',8,'kywl','2004-12-01 00:00:00',b'010111010110001110110011000010110111011','ywlcne',0.2,'09:10:39.028897',2031,'wlcnemiuaab',''),
+ ('1989-05-15','1973-09-04 00:00:00',2,'lcne',NULL,b'100001100101110110000011110','',0.9,'19:22:16.015548',2013,'cnemiuaa',''),
+ ('2023-04-20','2018-12-04 04:19:46.040664',8,NULL,'1985-04-18 05:32:12.013509',b'111011011111100100000001','nem',0.1,'23:18:05.007794',2026,'emiua',''),
+ (NULL,'2024-08-10 03:52:31.047182',2,'miua','2035-09-03 06:07:22.008308',b'000111','',0.1,'03:58:02.003946',1988,'iua',''),
+ ('1977-09-01','1987-02-01 03:44:00.061840',5,'u','1997-11-27 04:02:13.014551',b'111110001001100101101000100010001011101000011',NULL,0.3,'00:00:00',1985,'aab',''),
+ (NULL,'1980-01-01 00:00:00',6,'a','1989-03-02 09:07:11.058643',b'10101001011110110010111010010100001010000110000110010',NULL,0.8,'17:41:15.057101',1975,'br',''),
+ ('1980-01-01','2019-02-10 20:56:51.063985',NULL,'rr','2000-02-28 01:38:27.004468',b'0101001011110001010001','rifnhu',0.5,'20:55:57.029281',1973,'if',''),
+ (NULL,'2019-04-15 02:13:03.019581',7,'fnhu','2000-03-25 18:48:46.063113',b'011000110','nhuu',0.0,'00:00:00',2030,'h',''),
+ ('1997-04-01',NULL,3,NULL,'1976-05-22 04:48:42.013754',b'101110101010000111101',NULL,0.1,'12:09:48.030076',2031,'u',''),
+ (NULL,'1993-10-10 15:11:03.021823',NULL,'ufzasunkrcpvasdqkxbwptigbpnesqigwegcnfeuvrgnecpthm','1986-06-12 04:29:01.017855',b'11110','fza',0.9,NULL,1994,'zasun',''),
+ ('1997-02-13','2001-04-08 02:01:53.018388',0,'as','1975-09-18 00:00:00',b'00111000101001001101001000100100010101110011010111000001011011','su',0.3,'15:15:31.011102',1972,'unk',''),
+ ('1975-07-26','2022-12-24 00:00:00',0,'foo','1986-01-22 21:27:38.024505',b'1111110000000001000010111','krc',0.9,'05:46:08.055789',1996,'rcp',''),
+ ('2000-08-04','1980-01-01 00:00:00',48,'foo','2015-12-21 17:04:06.008790',b'0100001110011001011101011101110110100010000101101100011010','g',0.7,'18:31:50.046211',2025,'pvasdq',''),
+ ('2001-03-26','2032-03-19 13:15:13.063368',NULL,'foo','2026-09-05 02:46:10.026919',b'11','a',0.3,'03:12:20.039599',2019,'sdqkx',''),
+ ('2035-01-14','1987-09-15 05:46:00.041527',4,'p','1980-01-01 00:00:00',b'1111100111','dqkxbwpt',0.0,'09:57:41.059145',1995,'q',''),
+ ('2035-07-13','2011-04-13 04:05:14.025091',212,'kxbw','1985-02-14 11:58:32.002055',b'1010100011110101011111111011010','x',0.2,'19:35:02.024655',1975,'bwptig',''),
+ ('2026-02-08','2015-05-04 09:31:22.017074',4,'wpt','2024-01-26 11:06:03.057899',b'011000010000100000011000011011000100101111001100000111011010','ptig',0.0,'00:00:00',1977,'tig',''),
+ ('1981-05-11',NULL,NULL,'foo','1981-12-09 10:10:34.008107',b'01000100100100110011111','gbp',0.0,'13:05:42.035253',2019,'bpn',''),
+ ('1977-05-16',NULL,9,'pne',NULL,b'001101100111001110110010111001110100','s',0.0,'15:09:37.063819',1998,'ne',''),
+ ('1980-01-01','2018-12-02 00:27:35.056455',2,'','1981-07-07 23:39:32.028644',b'0000101001010111010001101000','es',0.3,'15:43:30.016638',2013,NULL,''),
+ ('2027-09-05','1998-05-14 04:15:42.009728',1,'s','2015-07-16 00:00:00',b'01011101101010000110011010000111001000001000011','',0.6,'08:39:24.041879',2035,'qigweg',''),
+ ('2005-02-04',NULL,2,'i','1974-01-11 11:02:16.024653',b'01001101110001001101101010011001001101010010000','gw',0.6,'03:28:30.012172',1978,'weg',''),
+ (NULL,'1976-06-21 00:00:00',5,NULL,'2023-11-25 15:49:52.021725',b'101011010001100','e',0.1,'00:00:00',1977,'gcn',''),
+ ('1989-07-13',NULL,1,'c','1978-02-22 02:55:14.047104',b'01101010100001100110111011101000111011101101110011','f',0.8,NULL,1987,'nfeu',''),
+ ('2004-04-27','2019-06-28 08:04:35.039213',0,'f','1990-01-09 14:22:27.065127',b'00101001011','eu',0.0,'13:33:09.039791',2007,'uvrgne',''),
+ ('2008-09-08','1990-11-05 00:00:00',1,'w','2026-12-23 00:00:00',b'0001101','vrgnec',0.3,'19:13:14.037732',1983,'d',''),
+ ('2026-08-12','2026-11-23 11:18:35.012315',4,'rgnec','1988-09-06 07:11:55.057710',b'11010111001001101100100010110011100001000100001011000000000010','',0.9,NULL,1982,'gnecpth',''),
+ ('1992-12-03','2033-08-18 04:47:11.033829',65,'n','1989-11-21 17:42:13.012747',b'11011011110000000',NULL,0.9,'10:08:34.006377',1971,'ecpth',''),
+ ('1976-10-11','1975-05-18 00:00:00',3,'c','2017-11-06 03:33:38.002741',b'0111100010000111000111111100111100111000101100111111100','p',0.7,'03:28:07.039921',2014,'thmhf',''),
+ ('2014-04-19','2023-08-07 16:18:59.024013',0,'','2006-05-04 23:01:46.019351',b'0101101011011101101011101110000001001000110100101000011001110','h',0.5,'00:00:00',1995,'m',''),
+ ('1990-07-16','1980-01-01 00:00:00',8,'hffqbythjwpukqubzpomntrddrwhzjtqvb','1985-08-04 05:33:20.030471',b'001101111111100110101111000011100','ff',0.0,'00:00:00',2002,'fqbythj',''),
+ (NULL,'2019-01-12 00:00:00',0,NULL,'2009-01-25 00:00:00',b'100111111010000110010011100100000011101001010101111','qb',0.4,'20:35:33.059895',1981,'byt',''),
+ ('1991-10-07',NULL,2,'yt','2027-04-19 06:38:46.020191',b'001','t',0.4,'10:02:06.014126',2004,'h',''),
+ (NULL,'2009-07-05 00:00:00',241,'j','1981-06-26 12:35:20.061910',b'10101110001101001000011010010111000','wpukqu',0.5,'00:00:00',1973,'pukqu',''),
+ ('2001-05-26','2007-01-06 00:57:02.048605',0,'u',NULL,b'111100','k',0.7,'03:19:10.052988',2026,'q',NULL),
+ ('2008-03-15','1990-09-11 00:00:00',5,'ubz','1980-01-01 00:00:00',b'11010111011110001101111000000011000111101100111','b',0.5,'00:34:27.006616',2013,NULL,''),
+ ('1984-08-01','2000-09-20 09:35:47.025609',3,'zp','2016-11-22 19:38:52.053299',b'00000010','po',0.7,'19:47:19.014687',1996,'o',''),
+ ('1978-02-05','1978-05-08 04:30:57.023271',7,'foo','2000-04-06 08:42:13.019650',b'11000110111100101010001110111101111000001101','n',0.8,NULL,1980,'trdd',''),
+ ('2017-04-11','2002-09-26 12:59:43.051659',8,'rd','1972-03-27 13:09:07.017459',b'00011110001001001000000100110100101010','ddrwh',0.7,'00:00:00',2021,'drwhzj',''),
+ ('1980-01-01','1986-05-04 05:15:19.008418',0,'r','2005-10-04 09:21:09.020131',b'1101100010101001010011010001011101001111110010101111011','wh',0.0,'00:00:00',1975,'hzjtqv',''),
+ ('2035-12-12','1980-01-01 00:00:00',0,'x',NULL,b'0010000101010110111100000110000010001000100001000110111000010110','zjt',0.4,'15:51:12.040679',1984,'jtqvbji',''),
+ ('1993-05-12','2000-11-11 20:54:49.053753',0,'tqvb','2022-02-26 14:26:36.004981',b'110000101110000111011','qv',0.7,'00:00:00',1972,'v',''),
+ ('1971-08-22','2029-02-15 16:39:35.007278',2,NULL,'2033-09-22 08:28:19.057517',b'11111101011101110111100011011111001','bji',0.8,'08:34:37.000701',2000,'o',''),
+ (NULL,NULL,5,'foo','1982-02-24 00:00:00',b'00111111000111111111010111010111011101','iklce',0.8,'01:23:11.014485',2021,'klcek',''),
+ (NULL,NULL,8,'lce','1988-07-28 11:48:23.011427',b'101101000101010000000100000001011','',0.3,'17:15:34.034697',1991,'cekxqy',''),
+ ('2029-12-07','1993-12-24 00:45:29.060155',3,'ekx','1980-01-01 00:00:00',b'01001010110110000100100100111010110000000101001011111110001100','q',0.7,'10:39:47.004022',2006,'foo',''),
+ ('2015-10-20','1980-01-01 00:00:00',189,'xqy','2028-12-19 00:00:00',b'101001011011100101110010101000101110100110','qy',0.5,'15:16:59.059052',1993,'foo',''),
+ ('1998-08-07','2017-08-07 01:53:34.056737',5,'oxsolbx',NULL,b'1000111010110010110','xsolbxth',0.3,'22:56:09.003450',2014,'s',''),
+ ('2016-01-25','2000-09-14 22:35:41.048328',6,'foo','2004-10-11 00:00:00',b'001','olbxt',0.0,'14:15:54.033066',1983,'lbxt',''),
+ ('1979-09-02','2027-01-19 09:34:15.034597',4,'bxth','1989-10-23 09:11:09.055445',b'011011001110000011011011',NULL,0.8,'05:31:31.006489',1978,'xthdc',''),
+ ('1980-01-01',NULL,8,'th','2012-02-07 00:00:00',b'00101011001100111001101011010110','hdc',0.0,'22:09:17.054381',2013,'dcprs',''),
+ (NULL,'2018-08-03 17:37:14.049040',2,'cprswpj','1990-07-28 07:56:50.026324',b'0000010111011110100100010010011011010010001111011010000010011101','',0.1,NULL,1971,'prswpjx',''),
+ ('1984-05-07','2012-05-07 00:00:00',1,'rswp','2030-05-09 07:42:25.003848',b'1001','swp',0.4,'13:27:32.040813',1997,'wpj',''),
+ (NULL,'2030-03-22 14:03:46.000742',7,'pjxixm','2022-05-11 00:00:00',b'00111110011001010010001111010001111110010010000111','j',0.8,'00:00:00',1996,'x',NULL),
+ ('2000-12-03','2020-08-13 16:03:09.041436',8,'ix','1985-05-19 11:28:09.002728',b'11011010000101000110111111010111','xmvfwm',0.9,'19:06:00.002417',1976,'m',''),
+ ('1990-03-13','2035-09-08 21:29:04.011731',5,'vfwmsys','2029-11-03 04:28:54.058532',b'0110001011001010100','fw',0.6,'20:30:32.032224',1994,'wmsys',''),
+ ('2035-06-04','2027-06-07 11:27:21.038934',8,'ms','1987-09-02 00:00:00',b'001101101101111110010110110011','syse',0.1,'01:10:53.060943',2027,'yse',''),
+ (NULL,'1993-06-06 07:29:56.029103',NULL,'','1971-06-08 23:51:55.054403',b'11001110001111111001001010101110111011000100111010','se',0.2,'10:24:53.013058',1995,'eb',''),
+ ('2018-06-12','2020-08-06 23:47:35.060301',5,NULL,NULL,b'110011110111010111','blwc',0.6,NULL,1971,'lwc',''),
+ ('2005-02-03','2016-10-11 00:00:00',0,'w','2005-03-25 00:00:00',b'0101001001001','',0.2,'21:56:26.025743',1971,'c',''),
+ ('2025-10-10',NULL,1,'vumvyv','2034-05-06 18:17:26.004829',b'10110101101100100001000011001111100100111101100','um',0.3,'19:42:29.005509',1992,'m',''),
+ ('2014-01-27','1980-01-01 00:00:00',2,'vyvb','1975-04-08 10:13:06.052060',b'111011110111111010011111011011101111','yv',0.4,'15:13:32.059509',2011,NULL,''),
+ ('2016-08-04','2008-12-03 01:55:41.030042',6,'vb','1993-09-08 00:01:40.016566',b'000101110101100111001101010110','b',0.5,'08:39:05.055786',1993,'it',''),
+ ('1980-01-01','1980-01-01 00:00:00',9,'tx','1991-07-19 05:37:43.056696',b'110110111010111101010001100010111100110011111010100100100','k',0.9,'00:00:00',1999,'h',''),
+ (NULL,'2007-06-14 15:47:29.017306',9,'foo',NULL,b'0100111000001011111000111010000011011000011000101010','qjxdzd',0.3,'13:52:31.035851',2001,'jxdzd',''),
+ (NULL,'2022-04-28 18:27:19.060240',4,'foo','2018-02-28 02:49:16.013066',b'10000100000000110011011110101110100001100011101110011011100','d',0.0,'15:01:48.022368',1987,'zdytun',''),
+ ('1987-10-10','1975-06-02 02:47:57.012240',9,'dy','1980-06-10 00:00:00',b'110000111','',0.7,'08:13:44.003967',1981,'',''),
+ ('2015-09-28',NULL,4,'d','2005-08-09 08:35:04.039832',b'00','b',0.1,'00:47:43.048164',1973,'yt',''),
+ ('2030-01-18','2011-12-09 00:00:00',6,NULL,'1982-05-13 00:00:00',b'111110100001000010001110110010111100001011010','v',0.2,'00:39:24.001557',2027,'tun',''),
+ ('1980-06-28','2016-04-07 00:00:00',8,'y','1980-01-01 00:00:00',b'01011100100001010110101110111110110','unq',0.7,'00:00:00',2016,'foo',''),
+ ('2018-09-16','1975-01-03 00:00:00',NULL,'qv','2028-05-10 00:00:00',b'0001100101001011100110','vv',0.0,'23:54:42.064230',2000,'vr',''),
+ ('2033-12-11','2021-07-23 12:20:17.025201',3,'rm','1996-07-16 00:00:00',b'1011001110','mpyx',0.7,'04:04:01.055956',2009,'pyx',''),
+ ('1982-12-18','1996-09-16 00:00:00',9,'yx','2003-10-14 03:54:44.012072',b'11001011011000001111011000101111101110100101','x',0.9,NULL,1981,'rencqh',''),
+ ('1980-01-01','2009-01-17 12:11:34.030449',7,'encqh','1980-01-01 00:00:00',b'1101001101001000101010001100100100','ncq',0.4,'23:44:22.012217',2030,'b',''),
+ ('2015-05-03','1987-03-19 17:37:53.053429',6,'','2012-08-03 00:00:00',b'0','cq',0.0,'17:16:43.030750',2035,'qh',NULL),
+ (NULL,'1980-01-01 00:00:00',1,'huyr','2012-02-11 14:15:13.004778',b'110011001100010100001101011001011110010000011001110101','',0.7,'09:33:00.034425',2024,'uyr',''),
+ ('2019-06-05','2020-08-05 23:53:07.028129',1,'yr',NULL,b'1001011110101010001111101000011001011111100','rflu',0.3,NULL,2016,'fluezqe',''),
+ ('1980-01-10','2025-05-12 08:22:39.039097',1,'lu','1975-07-24 00:00:00',b'10100111001111101001110000110011','',0.1,'23:58:28.031575',2005,NULL,''),
+ ('2008-03-17','1982-05-27 11:44:53.038339',NULL,'uezqe','2024-10-12 02:16:04.063095',b'1001010110101101000101011011000011','e',0.9,'19:37:29.063243',1987,'zqekmq','')
+;
+--enable_query_log
+--disable_warnings
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+ALTER TABLE t1 ADD INDEX(col_enum,vcol_int);
+SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
+ALTER TABLE t1 ADD INDEX(col_year);
+--enable_warnings
+DROP TABLE t1;
+
+#
+# MDEV-11750 Assertion `vfield' failed in TABLE::update_virtual_fields after crash recovery on corrupted MyISAM table
+#
+create table t1 (
+ pk int primary key auto_increment,
+ b bit default null,
+ key(b)
+) engine=myisam;
+
+insert into t1 values (null, 0);
+repair table t1 extended;
+drop table t1;
+
+#
+# MDEV-18486 Database crash on a table with indexed virtual column
+#
+create table t1 ( id int primary key,
+ hexid varchar(10) generated always as (hex(id)) stored,
+ key (hexid)) engine=myisam;
+insert into t1 (id) select 100;
+select * from t1;
+drop table t1;
+
+
+--echo #
+--echo # MDEV-15881 Assertion `is_valid_value_slow()' failed in Datetime::Datetime or corrupt data after ALTER with indexed persistent column
+--echo #
+
+CREATE TABLE t1 (i INT, d1 DATE, d2 DATE NOT NULL, t TIMESTAMP, KEY(t)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'2023-03-16','2023-03-15','2012-12-12 12:12:12');
+ALTER TABLE t1 MODIFY t FLOAT AS (i) PERSISTENT;
+--disable_ps2_protocol
+SELECT i, d1, d2 INTO OUTFILE 'load_t1' FROM t1;
+--enable_ps2_protocol
+DELETE FROM t1;
+LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
+SELECT * FROM t1 WHERE d2 < d1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ i INT DEFAULT NULL,
+ d1 DATE DEFAULT NULL,
+ d2 DATE NOT NULL,
+ t FLOAT GENERATED ALWAYS AS (i) STORED,
+ KEY (t)
+) ENGINE=MyISAM;
+LOAD DATA INFILE 'load_t1' INTO TABLE t1 (i,d1,d2);
+SELECT * FROM t1 WHERE d2 < d1;
+DROP TABLE t1;
+# Cleanup
+--let $datadir= `SELECT @@datadir`
+--remove_file $datadir/test/load_t1
+
+
+--echo #
+--echo # MDEV-20015 Assertion `!in_use->is_error()' failed in TABLE::update_virtual_field
+--echo #
+create or replace table t1 (a int);
+insert into t1 (a) values (1), (1);
+create or replace table t2 (pk int, b int, c int as (b) virtual, primary key (pk), key(c));
+--error ER_DUP_ENTRY
+insert into t2 (pk) select a from t1;
+drop tables t1, t2;
diff --git a/mysql-test/suite/vcol/t/vcol_memory.test b/mysql-test/suite/vcol/t/vcol_memory.test
new file mode 100644
index 00000000..b78850ed
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_memory.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_merge.test b/mysql-test/suite/vcol/t/vcol_merge.test
new file mode 100644
index 00000000..ee1511ee
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_merge.test
@@ -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_ENGINE_FOR_GENERATED_COLUMNS
+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
diff --git a/mysql-test/suite/vcol/t/vcol_misc.opt b/mysql-test/suite/vcol/t/vcol_misc.opt
new file mode 100644
index 00000000..fd1faea4
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_misc.opt
@@ -0,0 +1 @@
+--character-sets-dir=$MYSQL_TEST_DIR/std_data/ldml/
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
new file mode 100644
index 00000000..83a06e83
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -0,0 +1,543 @@
+--source include/have_ucs2.inc
+--source include/have_debug.inc
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+#
+# Bug#601164: DELETE/UPDATE with ORDER BY index and LIMIT
+#
+
+create table t1 (a int, b int, v int as (a+1), index idx(b));
+insert into t1(a, b) values
+ (4, 40), (3, 30), (5, 50), (7, 70), (8, 80), (2, 20), (1, 10);
+
+select * from t1 order by b;
+
+delete from t1 where v > 6 order by b limit 1;
+select * from t1 order by b;
+
+update t1 set a=v order by b limit 1;
+select * from t1 order by b;
+
+drop table t1;
+
+#
+# Bug#604549: Expression for virtual column returns row
+#
+
+-- error ER_OPERAND_COLUMNS
+CREATE TABLE t1 (
+ a int NOT NULL DEFAULT '0',
+ v double AS ((1, a)) VIRTUAL
+);
+
+#
+# Bug#603654: Virtual column in ORDER BY, no other references of table columns
+#
+
+CREATE TABLE t1 (
+ a CHAR(255) BINARY NOT NULL DEFAULT 0,
+ b CHAR(255) BINARY NOT NULL DEFAULT 0,
+ v CHAR(255) BINARY AS (CONCAT(a,b)) VIRTUAL );
+INSERT INTO t1(a,b) VALUES ('4','7'), ('4','6');
+SELECT 1 AS C FROM t1 ORDER BY v;
+
+DROP TABLE t1;
+
+#
+# Bug#603186: Insert into a table with stored vurtual columns
+#
+
+CREATE TABLE t1(a int, b int DEFAULT 0, v INT AS (b+10) PERSISTENT);
+INSERT INTO t1(a) VALUES (1);
+SELECT b, v FROM t1;
+
+DROP TABLE t1;
+
+CREATE TABLE t1(a int DEFAULT 100, v int AS (a+1) PERSISTENT);
+INSERT INTO t1 () VALUES ();
+CREATE TABLE t2(a int DEFAULT 100 , v int AS (a+1));
+INSERT INTO t2 () VALUES ();
+
+SELECT a, v FROM t1;
+SELECT a, v FROM t2;
+
+DROP TABLE t1,t2;
+
+#
+# Bug#604503: Virtual column expression with datetime comparison
+#
+
+CREATE TABLE t1 (
+ a datetime NOT NULL DEFAULT '2000-01-01',
+ v boolean AS (a < '2001-01-01')
+);
+INSERT INTO t1(a) VALUES ('2002-02-15');
+INSERT INTO t1(a) VALUES ('2000-10-15');
+
+SELECT a, v FROM t1;
+SELECT a, v FROM t1;
+
+CREATE TABLE t2 (
+ a datetime NOT NULL DEFAULT '2000-01-01',
+ v boolean AS (a < '2001-01-01') PERSISTENT
+);
+INSERT INTO t2(a) VALUES ('2002-02-15');
+INSERT INTO t2(a) VALUES ('2000-10-15');
+
+SELECT * FROM t2;
+
+DROP TABLE t1, t2;
+
+#
+# Bug#607566: Virtual column in the select list of SELECT with ORDER BY
+#
+
+CREATE TABLE t1 (
+ a char(255), b char(255), c char(255), d char(255),
+ v char(255) AS (CONCAT(c,d) ) VIRTUAL
+);
+
+INSERT INTO t1(a,b,c,d) VALUES ('w','x','y','z'), ('W','X','Y','Z');
+
+SELECT v FROM t1 ORDER BY CONCAT(a,b);
+
+DROP TABLE t1;
+
+#
+# Bug#607168: CREATE TABLE AS SELECT that returns virtual columns
+#
+
+CREATE TABLE t1 (f1 INTEGER, v1 INTEGER AS (f1) VIRTUAL);
+CREATE TABLE t2 AS SELECT v1 FROM t1;
+SHOW CREATE TABLE t2;
+
+DROP TABLE t1,t2;
+
+#
+# Bug#607177: ROUND function in the expression for a virtual function
+#
+
+CREATE TABLE t1 (p int, a double NOT NULL, v double AS (ROUND(a,p)) VIRTUAL);
+INSERT IGNORE INTO t1 VALUES (0,1,0);
+INSERT IGNORE INTO t1 VALUES (NULL,0,0);
+SELECT a, p, v, ROUND(a,p), ROUND(a,p+NULL) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (p int, a double NOT NULL);
+INSERT INTO t1(p,a) VALUES (0,1);
+INSERT INTO t1(p,a) VALUES (NULL,0);
+SELECT a, p, ROUND(a,p), ROUND(a,p+NULL) FROM t1;
+DROP TABLE t1;
+
+#
+# Bug#610890: SHOW CREATE TABLE with a virtual column
+#
+
+CREATE TABLE t1 (a char(32), v char(32) CHARACTER SET ucs2 AS (a) VIRTUAL);
+
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+#
+# Bug#930814: no info in information schema for tables with virtual columns
+#
+
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (a int, b int as (a+1) VIRTUAL);
+
+SELECT table_schema, table_name, column_name, column_type, extra
+ FROM information_schema.columns WHERE table_name = 't1';
+SELECT table_schema, table_name, column_name, column_type, extra
+ FROM information_schema.columns WHERE table_name = 't2';
+
+DROP TABLE t1,t2;
+
+#
+# Bug mdev-354: virtual columns of ENUM and SET types
+#
+
+create table t1 (
+ a int not null, b char(2) not null,
+ c enum('Y','N') as (case when b = 'aa' then 'Y' else 'N' end) persistent
+);
+show create table t1;
+insert into t1(a,b) values (1,'bb'), (2,'aa'), (3,'cc');
+select * from t1;
+
+create table t2 (
+ a int, b int,
+ c set("y","n")
+ as (if(a=0,if(b=0,('n,n'),('n,y')),if(b=0,('y,n'),('y,y')))) persistent
+);
+show create table t2;
+insert into t2(a,b) values (7,0), (2,3), (0,1);
+select * from t2;
+
+drop table t1,t2;
+
+#
+# Bug mdev-3938: INSERT DELAYED for a table with virtual columns
+#
+
+SET @old_debug= @@global.debug;
+SET @old_debug= @@global.debug;
+SET GLOBAL debug_dbug= "+d,write_delay_wakeup";
+CREATE TABLE t1 (a int,
+ ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ tsv TIMESTAMP AS (ADDDATE(ts, INTERVAL 1 DAY)) VIRTUAL
+) ENGINE=MyISAM;
+
+--echo # First test FLUSH TABLES
+INSERT INTO t1 (a,tsv) VALUES (1,DEFAULT);
+INSERT DELAYED INTO t1 (a,tsv) VALUES (2,DEFAULT);
+FLUSH TABLES;
+# Count may be 1 or 2, depending on FLUSH happened before or after delayed
+SELECT COUNT(*) > 0 FROM t1;
+
+--echo # Then test FLUSH TABLES t1;
+INSERT INTO t1 (a,tsv) VALUES (3,DEFAULT);
+INSERT DELAYED INTO t1 (a,tsv) VALUES (4,DEFAULT);
+FLUSH TABLES t1;
+SELECT COUNT(*) FROM t1;
+
+--echo # Then test FLUSH TABLES WITH READ LOCK;
+
+INSERT INTO t1 (a,tsv) VALUES (5,DEFAULT);
+INSERT DELAYED INTO t1 (a,tsv) VALUES (6,DEFAULT);
+FLUSH TABLES WITH READ LOCK;
+SELECT COUNT(*) FROM t1;
+set GLOBAL debug_dbug= @old_debug;
+unlock tables;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-4823 Server crashes in Item_func_not::fix_fields on
+--echo # creating a table with a virtual column using NOT
+--echo #
+CREATE TABLE t1 ( f1 INT, v4 INT AS ( NOT f1 ) VIRTUAL );
+drop table t1;
+
+--echo # end of 5.2 tests
+
+#
+# SELECT that uses a virtual column and executed with BKA
+#
+
+create table t1 (a int, b int);
+insert into t1 values (3, 30), (4, 20), (1, 20);
+create table t2 (c int, d int, v int as (d+1), index idx(c));
+insert into t2(c,d) values
+ (20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
+ (70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
+insert into t2(c,d) values
+ (120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
+ (170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
+
+set join_cache_level=6;
+explain
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+set join_cache_level=default;
+
+drop table t1, t2;
+
+#
+# Test crashes when using convert_const_item()
+#
+create table t1 (a bigint, b bigint as (a > '2'));
+show create table t1;
+insert into t1 (a) values (1),(3);
+select * from t1;
+select * from t1;
+drop table t1;
+create table t1 (a bigint, b bigint as (a between 0 and 2));
+show create table t1;
+insert into t1 (a) values (1),(3);
+select * from t1;
+select * from t1;
+drop table t1;
+create table t1 (a char(10), b char(10) as (a between 0 and 2));
+show create table t1;
+insert into t1 (a) values (1),(3);
+select * from t1;
+select * from t1;
+drop table t1;
+
+#
+# Test output of show columns
+#
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` varchar(32) DEFAULT NULL,
+ `c` int(11) AS (a MOD 10) VIRTUAL,
+ `d` varchar(5) AS (LEFT(b,5)) PERSISTENT
+) ENGINE=MyISAM;
+show create table t1;
+show columns from t1;
+--replace_column 8 #
+show full columns from t1;
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,NULL);
+UPDATE IGNORE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+INSERT IGNORE INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+set sql_mode='strict_all_tables';
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+UPDATE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+drop table t1;
+
+--echo #
+--echo # MDEV-5611: self-referencing virtual column
+--echo #
+
+--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
+create table t1 (a int, b int as (b is null) virtual);
+
+create table t1 (a int as (1+1), b int as (a is null) virtual);
+drop table t1;
+
+--echo # end of 5.3 tests
+
+#
+# MDEV-7655 SHOW CREATE TABLE returns invalid DDL when using virtual columns along with a table collation
+#
+create table t1 (v1 varchar(255) as (c1) persistent, c1 varchar(50)) collate=latin1_general_ci;
+show create table t1;
+drop table t1;
+
+#
+# MDEV-11527 Virtual columns do not get along well with NO_ZERO_DATE
+#
+set sql_mode='no_zero_date';
+create table t1 (
+ ts timestamp not null default current_timestamp,
+ tsv timestamp as (adddate(ts, interval 1 day)) virtual
+);
+drop table t1;
+set sql_mode=default;
+
+--echo #
+--echo # MDEV-11819 NO_ZERO_IN_DATE: Incorrect generated column value
+--echo #
+
+SET sql_mode='NO_ZERO_IN_DATE';
+CREATE TABLE t1
+(
+ a datetime DEFAULT NULL,
+ b datetime DEFAULT NULL,
+ c time GENERATED ALWAYS AS (timediff(`a`,`b`)) VIRTUAL
+);
+INSERT INTO t1 VALUES ('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',DEFAULT);
+SELECT * FROM t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # MDEV-15834 The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
+--echo #
+
+--copy_file std_data/frm/t1.frm $MYSQLD_DATADIR/test/t1.frm
+SHOW TABLES;
+--replace_result $MYSQLD_DATADIR ./
+--error ER_NOT_FORM_FILE
+SHOW CREATE TABLE t1;
+--replace_result $MYSQLD_DATADIR ./
+--error ER_NOT_FORM_FILE
+ALTER TABLE t1;
+--remove_file $MYSQLD_DATADIR/test/t1.frm
+
+
+--echo #
+--echo # End of 5.5 tests
+--echo #
+
+--echo #
+--echo # End of 10.0 tests
+--echo #
+
+--echo #
+--echo # MDEV-8441 Bad SHOW CREATE TABLE output for a table with a virtual column
+--echo #
+CREATE TABLE t1 (a DATETIME, b TIMESTAMP AS (TIMESTAMP(a)));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+# Make sure that if the first TIMESTAMP column appears to be virtual,
+# then no further promotion is done, so the next TIMESTAMP column "c" does not
+# get the "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" attributes.
+CREATE TABLE t1 (a DATETIME, b TIMESTAMP AS (TIMESTAMP(a)),c TIMESTAMP);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-8839 COLUMN_GET() produces warnings with no data
+--echo #
+SET @aaa= COLUMN_CREATE('price', _binary 0xF0F1F2F3F4F5F6F7);
+SELECT COLUMN_GET(@aaa, 'price' AS DECIMAL) aaa;
+SELECT COLUMN_GET(@aaa, 'price' AS INT) aaa;
+SELECT COLUMN_GET(@aaa, 'price' AS DOUBLE) aaa;
+
+
+--echo #
+--echo # MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
+--echo #
+
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (
+ a INT NOT NULL DEFAULT 10,
+ b INT AS (a+1) VIRTUAL
+) ENGINE=MyISAM;
+
+# Testing with a column list
+
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+INSERT INTO t1 (b) VALUES (10);
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+INSERT INTO t1 (b) VALUES (DEFAULT(a));
+INSERT INTO t1 (b) VALUES (DEFAULT);
+
+# Testing without a column list
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+INSERT INTO t1 VALUES (10,10);
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
+INSERT INTO t1 VALUES (10,DEFAULT(a));
+INSERT INTO t1 VALUES (10, DEFAULT);
+
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # End of 10.1 tests
+--echo #
+
+--echo #
+--echo # MDEV-16518 MYSQL57_GENERATED_FIELD: The code in TABLE_SHARE::init_from_binary_frm_image() is not safe
+--echo #
+
+--copy_file std_data/frm/mdev16518.frm $MYSQLD_DATADIR/test/t1.frm
+SHOW TABLES;
+--replace_result $MYSQLD_DATADIR ./
+--error ER_NOT_FORM_FILE
+SHOW CREATE TABLE t1;
+--replace_result $MYSQLD_DATADIR ./
+--error ER_NOT_FORM_FILE
+ALTER TABLE t1;
+--remove_file $MYSQLD_DATADIR/test/t1.frm
+
+--echo #
+--echo # MDEV-19771 REPLACE on table with virtual_field can cause crash in set_ok_status()
+--echo
+
+create or replace table t1 (pk int primary key, col_bit bit(15) default null,
+ vcol_bit bit(10) GENERATED ALWAYS AS (`col_bit`) VIRTUAL);
+replace INTO `t1` (`pk`,col_bit) VALUES (99,1000);
+select pk, col_bit+0, vcol_bit+0 from t1;
+replace INTO `t1` (`pk`,col_bit) VALUES (99,10000);
+select pk, col_bit+0, vcol_bit+0 from t1;
+--error ER_DATA_TOO_LONG
+REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
+drop table t1;
+
+--echo #
+--echo # MDEV-17837 REPLACE on table with virtual_field can cause crash in set_ok_status()
+--echo #
+
+SET @old_sql_mode=@@sql_mode;
+SET sql_mode= STRICT_ALL_TABLES;
+
+CREATE TABLE t1 (
+ pk INT,
+ i TINYINT,
+ vi TINYINT AS (i+1) PERSISTENT,
+ PRIMARY KEY(pk)
+);
+
+INSERT INTO t1 (pk,i) VALUES (1,1);
+TRUNCATE TABLE t1;
+INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
+--error ER_WARN_DATA_OUT_OF_RANGE
+REPLACE INTO t1 (pk,i) VALUES (1,2);
+DROP TABLE t1;
+SET @sql_mode=@old_sql_mode;
+
+--echo #
+--echo # MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
+--echo # 10.2+ specific part
+--echo #
+
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (
+ a INT NOT NULL DEFAULT 10,
+ b INT AS (a+1) VIRTUAL
+) ENGINE=MyISAM;
+
+# Testing with column list
+
+EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING DEFAULT;
+EXECUTE IMMEDIATE 'INSERT INTO t1 (b) VALUES(?)' USING IGNORE;
+INSERT INTO t1 (b) VALUES (DEFAULT);
+INSERT INTO t1 (b) VALUES (IGNORE);
+SELECT * FROM t1;
+DELETE FROM t1;
+
+# Testing without column list
+
+EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(10,?)' USING DEFAULT;
+EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES(11,?)' USING IGNORE;
+INSERT INTO t1 VALUES (12,DEFAULT);
+INSERT INTO t1 VALUES (13,IGNORE);
+SELECT * FROM t1;
+
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+--echo #
+--echo # CONTEXT_ANALYSIS_ONLY_VCOL_EXPR
+--echo #
+
+--source include/have_ucs2.inc
+call mtr.add_suppression("Charset id.*trying to replace");
+create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci,
+ v1 char(1) character set ucs2 collate ucs2_test_ci as (c1),
+ v2 int as (c1 = 'b'),
+ v3 int as (v1 = 'b'));
+insert into t1 (c1) values ('a');
+select * from t1 where v1 = 'b';
+show create table t1;
+drop table t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
+--echo #
+--echo # RAND is session func
+--echo #
+create table t1 (a int, b float default rand(1));
+insert into t1 (a) values (1);
+insert into t1 (a) values (2);
+insert into t1 (a) values (3);
+select * from t1;
+drop table t1;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
+
+--echo #
+--echo # MDEV-31112 vcol circular references lead to stack overflow
+--echo #
+create table t (a int, c int as (a));
+alter table t alter column c drop default;
+--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
+alter table t modify column a int as (c) stored;
+drop table t;
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test b/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test
new file mode 100644
index 00000000..8f7a4671
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_non_stored_columns_innodb.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test b/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test
new file mode 100644
index 00000000..74c11ba8
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_non_stored_columns_myisam.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_partition_innodb.test b/mysql-test/suite/vcol/t/vcol_partition_innodb.test
new file mode 100644
index 00000000..7b8e8de2
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_partition_innodb.test
@@ -0,0 +1,51 @@
+################################################################################
+# 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: #
+################################################################################
+
+#
+# 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 inc/vcol_init_vars.pre
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source 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.default_storage_engine = 'InnoDB';
+
+##### Workarounds for known open engine specific bugs
+# none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source inc/vcol_partition.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source inc/vcol_cleanup.inc
diff --git a/mysql-test/suite/vcol/t/vcol_partition_myisam.test b/mysql-test/suite/vcol/t/vcol_partition_myisam.test
new file mode 100644
index 00000000..b41a2482
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_partition_myisam.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_select_innodb.test b/mysql-test/suite/vcol/t/vcol_select_innodb.test
new file mode 100644
index 00000000..5b04096a
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_select_innodb.test
@@ -0,0 +1,56 @@
+################################################################################
+# 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 include/default_optimizer_switch.inc
+--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.default_storage_engine = 'InnoDB';
+SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent=0;
+
+##### 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
+
+SET GLOBAL innodb_stats_persistent=@save_stats_persistent;
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
diff --git a/mysql-test/suite/vcol/t/vcol_select_myisam.test b/mysql-test/suite/vcol/t/vcol_select_myisam.test
new file mode 100644
index 00000000..1e1adf29
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_select_myisam.test
@@ -0,0 +1,132 @@
+###############################################################################
+# 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 include/default_optimizer_switch.inc
+--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.default_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
+
+--echo #
+--echo # Bug #806057: join with USING over a virtual column
+--echo #
+
+CREATE TABLE t1 (b int);
+INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154);
+
+CREATE TABLE t2 (a int, b int AS (a) VIRTUAL);
+INSERT IGNORE INTO t2 VALUES (187,187), (9,9), (187,187);
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 JOIN t2 USING (b);
+SELECT * FROM t1 JOIN t2 USING (b);
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 NATURAL JOIN t2;
+SELECT * FROM t1 NATURAL JOIN t2;
+
+DROP TABLE t1,t2;
+
+#
+# MDEV-11525 Assertion `cp + len <= buff + buff_size' failed in JOIN_CACHE::write_record_data
+#
+
+create table t1 (
+ pk integer auto_increment,
+ bi integer not null,
+ vi integer generated always as (bi) persistent,
+ bc varchar(1) not null,
+ vc varchar(2) generated always as (concat(bc, bc)) persistent,
+ primary key (pk),
+ key (vi, vc));
+insert t1 (bi, bc) values (0, 'x'), (0, 'n'), (1, 'w'), (7, 's'), (0, 'a'), (4, 'd'), (1, 'w'), (1, 'j'), (1, 'm'), (4, 'k'), (7, 't'), (4, 'k'), (2, 'e'), (0, 'i'), (1, 't'), (6, 'z'), (3, 'c'), (6, 'i'), (8, 'v');
+create table t2 (
+ pk integer auto_increment,
+ bi integer not null,
+ vi integer generated always as (bi) persistent,
+ bc varchar(257) not null,
+ vc varchar(2) generated always as (concat(bc, bc)) persistent,
+ primary key (pk),
+ key (vi, vc));
+insert t2 (bi, bc) values (1, 'c'), (8, 'm'), (9, 'd'), (6, 'y'), (1, 't'), (6, 'd'), (2, 's'), (4, 'r'), (8, 'm'), (4, 'b'), (4, 'x'), (7, 'g'), (4, 'p'), (1, 'q'), (9, 'w'), (4, 'd'), (8, 'e'), (4, 'b'), (8, 'y');
+explain # should be using join buffer
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+--sorted_result
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+drop table t2,t1;
+
+#
+# End of 5.5 tests
+#
+
+#
+# MDEV-11640 gcol.gcol_select_myisam fails in buildbot on Power
+# (same as MDEV-11525 above, but for virtual columns)
+#
+
+create table t1 (
+ pk integer auto_increment,
+ bi integer not null,
+ vi integer generated always as (bi) virtual,
+ bc varchar(1) not null,
+ vc varchar(2) generated always as (concat(bc, bc)),
+ primary key (pk),
+ key (vi, vc));
+insert t1 (bi, bc) values (0, 'x'), (0, 'n'), (1, 'w'), (7, 's'), (0, 'a'), (4, 'd'), (1, 'w'), (1, 'j'), (1, 'm'), (4, 'k'), (7, 't'), (4, 'k'), (2, 'e'), (0, 'i'), (1, 't'), (6, 'z'), (3, 'c'), (6, 'i'), (8, 'v');
+create table t2 (
+ pk integer auto_increment,
+ bi integer not null,
+ vi integer generated always as (bi) virtual,
+ bc varchar(257) not null,
+ vc varchar(2) generated always as (concat(bc, bc)),
+ primary key (pk),
+ key (vi, vc));
+insert t2 (bi, bc) values (1, 'c'), (8, 'm'), (9, 'd'), (6, 'y'), (1, 't'), (6, 'd'), (2, 's'), (4, 'r'), (8, 'm'), (4, 'b'), (4, 'x'), (7, 'g'), (4, 'p'), (1, 'q'), (9, 'w'), (4, 'd'), (8, 'e'), (4, 'b'), (8, 'y');
+explain # should be using join buffer
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+--sorted_result
+select t2.vi from (t2 as t3 right join (t2 left join t1 on (t1.bi = t2.vi)) on (t1.vc = t2.vc));
+drop table t2,t1;
diff --git a/mysql-test/suite/vcol/t/vcol_sql_mode.test b/mysql-test/suite/vcol/t/vcol_sql_mode.test
new file mode 100644
index 00000000..f52345c7
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_sql_mode.test
@@ -0,0 +1,322 @@
+--echo #
+--echo # Start of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-18156 Assertion `0' failed or `btr_validate_index(index, 0, false)' in row_upd_sec_index_entry or error code 126: Index is corrupted upon DELETE with PAD_CHAR_TO_FULL_LENGTH
+--echo #
+
+--echo #
+--echo # PAD_CHAR_TO_FULL_LENGTH + various virtual column data types
+--echo #
+
+CREATE TABLE t1 (a CHAR(5), v CHAR(5) AS (a) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v INT AS (a) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v TIME AS (a) VIRTUAL, KEY(v));
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (c CHAR(8), v BINARY(8) AS (c), KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v BIT(64) AS (a) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (a) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (a) VIRTUAL, KEY(v(100)));
+SHOW WARNINGS;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + TRIM resolving dependency
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RTRIM(a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (RTRIM(a)) VIRTUAL, KEY(v(100)));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING ' ' FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (TRIM(TRAILING ' ' FROM a)) VIRTUAL, KEY(v(100)));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH ' ' FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (TRIM(BOTH ' ' FROM a)) VIRTUAL, KEY(v(100)));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING NULL FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH NULL FROM a)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + TRIM not resolving dependency
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(LEADING ' ' FROM a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v TEXT AS (TRIM(LEADING ' ' FROM a)) VIRTUAL, KEY(v(100)));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING '' FROM a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH '' FROM a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(TRAILING 'x' FROM a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (TRIM(BOTH 'x' FROM a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+# more than one space
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a CHAR(5),
+ v VARCHAR(5) AS (TRIM(TRAILING ' ' FROM a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+# more than one space
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a CHAR(5),
+ v VARCHAR(5) AS (TRIM(BOTH ' ' FROM a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + TRIM(... non_constant FROM a)
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a CHAR(5),
+ b CHAR(5),
+ v TEXT AS (TRIM(TRAILING b FROM a)) VIRTUAL, KEY(v(100)));
+SHOW WARNINGS;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + RPAD resolving dependency
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,5,' ')) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,6,' ')) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,6,NULL)) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,NULL,' ')) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + RPAD not resolving dependency
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RPAD(a,4,' ')) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a CHAR(5),
+ b CHAR(5),
+ v VARCHAR(5) AS (RPAD(a,NULL,b)) VIRTUAL,
+ KEY(v)
+);
+SHOW WARNINGS;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + comparison
+
+CREATE TABLE t1 (a CHAR(5), v INT AS (a='a') VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a CHAR(5) CHARACTER SET latin1 COLLATE latin1_nopad_bin,
+ v INT AS (a='a') VIRTUAL, KEY(v)
+);
+SHOW WARNINGS;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + LIKE
+
+CREATE TABLE t1 (a CHAR(5), v INT AS (a LIKE 'a%') VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), v INT AS (a LIKE NULL) VIRTUAL, KEY(v));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v INT AS (a LIKE 'a') VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+
+--echo # PAD_CHAR_TO_FULL_LENGTH + LENGTH(char_column) = hard dependency
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v INT AS (LENGTH(a)) VIRTUAL, KEY(v));
+SHOW WARNINGS;
+
+
+--echo #
+--echo # Testing NO_UNSIGNED_SUBTRACTION
+--echo #
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c INT GENERATED ALWAYS AS (a-b) VIRTUAL,
+ KEY (c)
+);
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c INT GENERATED ALWAYS AS (CAST(a AS SIGNED)-b) VIRTUAL,
+ KEY (c)
+);
+SHOW WARNINGS;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c INT GENERATED ALWAYS AS (a-CAST(b AS SIGNED)) VIRTUAL,
+ KEY (c)
+);
+SHOW WARNINGS;
+
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c INT GENERATED ALWAYS AS (CAST(a AS SIGNED)-CAST(b AS SIGNED)) VIRTUAL,
+ KEY (c)
+);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+# 'CAST(signed AS DECIMAL)' does not copy 'unsigned_flag' from the argument.
+# So the below is safe.
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c INT GENERATED ALWAYS AS (CAST(a AS DECIMAL(20,0))-CAST(b AS DECIMAL(20,0))) VIRTUAL,
+ KEY (c)
+);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Comnination: PAD_CHAR_TO_FULL_LENGTH + NO_UNSIGNED_SUBTRACTION
+--echo #
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c CHAR(5),
+ v VARCHAR(5) GENERATED ALWAYS AS (RPAD(c,a-b,' ')) VIRTUAL,
+ KEY (v)
+);
+SHOW WARNINGS;
+
+
+# The below solves the dependency on NO_UNSIGNED_SUBTRACTION
+# but does not solve the dependency on PAD_CHAR_TO_FULL_LENGTH,
+# because the 'length' argument to RPAD() is not a constant.
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c CHAR(5),
+ v VARCHAR(5) GENERATED ALWAYS AS (RPAD(c,CAST(a AS DECIMAL(20,1))-b,' ')) VIRTUAL,
+ KEY (v)
+);
+SHOW WARNINGS;
+
+
+
+--echo # ALTER TABLE ADD KEY(vcol_depending_on_sql_mode) --> error
+
+# This makes sure that QT_ITEM_IDENT_SKIP_DB_NAMES and
+# QT_ITEM_IDENT_SKIP_TABLE_NAMES are passed to print()
+# to avoid temporary table names like `test`.`#sql-50a6_4`.`c`
+# in the error message.
+#
+
+CREATE TABLE t1 (
+ a INT UNSIGNED,
+ b INT UNSIGNED,
+ c CHAR(5),
+ v VARCHAR(5) GENERATED ALWAYS AS (c) VIRTUAL
+);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD KEY(v);
+SHOW WARNINGS;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE INDEX v ON t1 (v);
+SHOW WARNINGS;
+DROP TABLE t1;
+
+
+--echo # A virtual column on the second position in an index - cannot depend on sql_mode
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (id int, a CHAR(5), v TEXT AS (a) VIRTUAL, KEY(id, v(100)));
+SHOW WARNINGS;
+
+
+--echo # A persisten virtual column cannot depend on sql_mode
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (a) PERSISTENT);
+SHOW WARNINGS;
+
+CREATE TABLE t1 (a CHAR(5), v VARCHAR(5) AS (RTRIM(a)) PERSISTENT);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/mysql-test/suite/vcol/t/vcol_sql_mode_datetime.test b/mysql-test/suite/vcol/t/vcol_sql_mode_datetime.test
new file mode 100644
index 00000000..19ebd964
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_sql_mode_datetime.test
@@ -0,0 +1,134 @@
+--echo #
+--echo # Start of 10.4 tests
+--echo #
+
+--echo #
+--echo # MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
+--echo #
+
+SET sql_mode=DEFAULT;
+
+--echo # OK: same FSP + virtual index
+
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(4) AS (t) VIRTUAL,
+ KEY(v,d)
+);
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+ KEY(v,d)
+);
+DROP TABLE t1;
+
+
+--echo # OK: lower FSP + no virtual index
+
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(3) AS (t) VIRTUAL
+);
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
+);
+DROP TABLE t1;
+
+
+--echo # NOT OK: lower FSP + virtual index
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(3) AS (t) VIRTUAL,
+ KEY(v,d)
+);
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(3) AS (COALESCE(t)) VIRTUAL,
+ KEY(v,d)
+);
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+ KEY(v,d)
+);
+
+
+--echo # OK: lower FSP + ROUND + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(3) AS (ROUND(t,3)) VIRTUAL,
+ KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo # OK: lower FSP + TRUNCATE + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+ t DATETIME(4),
+ d DATETIME,
+ v DATETIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
+ KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+--echo #
+--echo # MDEV-20423 Assertion `0' failed or `btr_validate_index(index, 0, false)' in row_upd_sec_index_entry or error code 126: Index is corrupted upon DELETE with TIME_ROUND_FRACTIONAL
+--echo #
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a DATETIME(6),
+ v VARCHAR(30) GENERATED ALWAYS AS (CAST(a AS DATETIME(3))) VIRTUAL,
+ KEY (v)
+);
+
+CREATE TABLE t1 (
+ a DATETIME(6),
+ v VARCHAR(30) GENERATED ALWAYS AS (TRUNCATE(a,3)) VIRTUAL,
+ KEY (v)
+);
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ a DATETIME(6),
+ v VARCHAR(30) GENERATED ALWAYS AS (ROUND(a,3)) VIRTUAL,
+ KEY (v)
+);
+DROP TABLE t1;
+
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/mysql-test/suite/vcol/t/vcol_sql_mode_time.test b/mysql-test/suite/vcol/t/vcol_sql_mode_time.test
new file mode 100644
index 00000000..2ce2a9eb
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_sql_mode_time.test
@@ -0,0 +1,135 @@
+--echo #
+--echo # Start of 10.4 tests
+--echo #
+
+--echo #
+--echo # MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
+--echo #
+
+SET sql_mode=DEFAULT;
+
+--echo # OK: same FSP + virtual index
+
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(4) AS (t) VIRTUAL,
+ KEY(v,d)
+);
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(4) AS ('10:20:30.1234') VIRTUAL,
+ KEY(v,d)
+);
+DROP TABLE t1;
+
+
+--echo # OK: lower FSP + no virtual index
+
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(3) AS (t) VIRTUAL
+);
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
+);
+DROP TABLE t1;
+
+
+--echo # NOT OK: lower FSP + virtual index
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(3) AS (t) VIRTUAL,
+ KEY(v,d)
+);
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(3) AS (COALESCE(t)) VIRTUAL,
+ KEY(v,d)
+);
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+ KEY(v,d)
+);
+
+
+--echo # OK: lower FSP + ROUND + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(3) AS (ROUND(t,3)) VIRTUAL,
+ KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
+SELECT * FROM t1;
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = CURRENT_TIME;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo # OK: lower FSP + TRUNCATE + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+ t TIME(4),
+ d TIME,
+ v TIME(3) AS (TRUNCATE(t,3)) VIRTUAL,
+ KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('12:44:34.0496','21:27:53');
+SELECT * FROM t1;
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = CURRENT_TIME;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # MDEV-20423 Assertion `0' failed or `btr_validate_index(index, 0, false)' in row_upd_sec_index_entry or error code 126: Index is corrupted upon DELETE with TIME_ROUND_FRACTIONAL
+--echo #
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ a TIME(6),
+ v VARCHAR(30) GENERATED ALWAYS AS (CAST(a AS TIME(3))) VIRTUAL,
+ KEY (v)
+);
+
+CREATE TABLE t1 (
+ a TIME(6),
+ v VARCHAR(30) GENERATED ALWAYS AS (TRUNCATE(a,3)) VIRTUAL,
+ KEY (v)
+);
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ a TIME(6),
+ v VARCHAR(30) GENERATED ALWAYS AS (ROUND(a,3)) VIRTUAL,
+ KEY (v)
+);
+DROP TABLE t1;
+
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/mysql-test/suite/vcol/t/vcol_sql_mode_timestamp.test b/mysql-test/suite/vcol/t/vcol_sql_mode_timestamp.test
new file mode 100644
index 00000000..e3dee582
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_sql_mode_timestamp.test
@@ -0,0 +1,122 @@
+--echo #
+--echo # Start of 10.4 tests
+--echo #
+
+--echo #
+--echo # MDEV-18153 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIME_ROUND_FRACTIONAL
+--echo #
+
+SET sql_mode=DEFAULT;
+
+--echo # OK: same FSP + virtual index
+
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(4) AS (t) VIRTUAL,
+ KEY(v,d)
+);
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(4) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+ KEY(v,d)
+);
+DROP TABLE t1;
+
+
+--echo # OK: lower FSP + no virtual index
+
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(3) AS (t) VIRTUAL
+);
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL
+);
+DROP TABLE t1;
+
+
+--echo # NOT OK: lower FSP + virtual index
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(3) AS (t) VIRTUAL,
+ KEY(v,d)
+);
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(3) AS (COALESCE(t)) VIRTUAL,
+ KEY(v,d)
+);
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(3) AS ('2001-01-01 10:20:30.1234') VIRTUAL,
+ KEY(v,d)
+);
+
+
+--echo # OK: lower FSP + ROUND + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(3) AS (ROUND(t,3)) VIRTUAL,
+ KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo # OK: lower FSP + TRUNCATE + virtual index
+SET sql_mode=DEFAULT;
+CREATE TABLE t1 (
+ t TIMESTAMP(4),
+ d DATETIME,
+ v TIMESTAMP(3) AS (TRUNCATE(t,3)) VIRTUAL,
+ KEY(v,d)
+);
+INSERT IGNORE INTO t1 (t,d) VALUES ('2006-03-01 12:44:34.0496','2029-10-10 21:27:53');
+SELECT * FROM t1;
+SET SQL_MODE= 'TIME_ROUND_FRACTIONAL';
+UPDATE IGNORE t1 SET d = NOW();
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+--echo #
+--echo # MDEV-20639 ASAN SEGV in get_prefix upon modifying base column type with existing indexed virtual column
+--echo #
+
+CREATE TABLE t1 (
+ a TIMESTAMP,
+ b TIMESTAMP AS (a) VIRTUAL,
+ KEY (b)
+);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 MODIFY a BLOB FIRST;
+SHOW WARNINGS;
+DROP TABLE t1;
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test b/mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test
new file mode 100644
index 00000000..71e34231
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test
@@ -0,0 +1,193 @@
+-- source include/mysql_upgrade_preparation.inc
+call mtr.add_suppression("Table rebuild required");
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--enable_prepare_warnings
+
+--echo #
+--echo # Opening a Maria-10.2.26 table with a stored VARCHAR column
+--echo #
+
+--echo # Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t1;
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+
+FLUSH TABLES;
+SELECT * FROM t1;
+SELECT * FROM t1;
+FLUSH TABLES;
+SELECT * FROM t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+
+SHOW CREATE TABLE t1;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD b INT DEFAULT a;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD c INT DEFAULT a;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Fixing a Maria-10.2.26 table with a stored VARCHAR column
+--echo #
+
+--echo # Fixing by dropping the generated stored column
+--echo # Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+ALTER TABLE t1 DROP v;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo # Fixing by altering the generation expression of the stored column
+--echo # Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS (RTRIM(a)) PERSISTENT;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+
+--echo #
+--echo # Opening a Maria-10.2.26 table with a virtual VARCHAR column
+--echo #
+
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t1;
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+
+FLUSH TABLES;
+SELECT * FROM t1;
+SELECT * FROM t1;
+FLUSH TABLES;
+SELECT * FROM t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+
+
+SHOW CREATE TABLE t1;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD b INT DEFAULT a;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD c INT DEFAULT a;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Fixing a Maria-10.2.26 table with a virtual VARCHAR column
+--echo #
+
+--echo # Fixing by dropping the virtual column
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 DROP v;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo # Fixing by dropping a key on a virtual column, using ALTER TABLE
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 DROP KEY v;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo # Fixing by dropping a key on a virtual column, using DROP INDEX
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+DROP INDEX v ON t1;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo # Fixing by altering the generation expression of a virtual column
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS(RTRIM(a)) VIRTUAL;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Upgrading a Maria-10.2.26 table with a stored column
+--echo #
+
+--echo # Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+CHECK TABLE t1 FOR UPGRADE;
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Upgrading a Maria-10.2.26 table with a virtual column
+--echo #
+
+--echo # Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+CHECK TABLE t1 FOR UPGRADE;
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs.test b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs.test
new file mode 100644
index 00000000..36c1ba09
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs.test
@@ -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.default_storage_engine = 'MyISAM';
+
+##### Workarounds for known open engine specific bugs
+# none
+
+#------------------------------------------------------------------------------#
+# Execute the tests to be applied to all storage engines
+--source vcol_supported_sql_funcs_main.inc
+
+#------------------------------------------------------------------------------#
+# Execute storage engine specific tests
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
diff --git a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc
new file mode 100644
index 00000000..fa2162e5
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc
@@ -0,0 +1,1223 @@
+################################################################################
+# 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 = 1,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' escape '!');
+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_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 # 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;
+set time_zone='UTC';
+--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 # 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_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,0));
+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 # 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_communication.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
+
+--echo # MONTHNAME()
+let $cols = a date, b varchar(100) as (monthname(a));
+let $values1 = '2010-10-10',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DAYNAME()
+let $cols = a date, b varchar(100) as (dayname(a));
+let $values1 = '2011-11-11',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DATE_FORMAT()
+let $cols = a date, b varchar(100) as (date_format(a, '%W %a %M %b'));
+let $values1 = '2012-12-12',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # DATE_FORMAT() STORED
+let $cols = a date, b varchar(100) as (date_format(a, '%W %a %M %b', 'de_DE')) STORED;
+let $values1 = '2012-12-12',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # CURRENT_USER()
+let $cols = a char, b varchar(32) as (current_user());
+let $values1 = 'a', default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIME_FORMAT()
+let $cols = a datetime, b varchar(10) as (time_format(a,"%H.%i.%S"));
+let $values1 = '2001-01-01 02:03:04',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
+--echo # TIME_FORMAT() STORED
+let $cols = a datetime, b varchar(10) as (time_format(a,"%H.%i.%S")) STORED;
+let $values1 = '2001-01-01 02:03:04',default;
+let $rows = 1;
+--source suite/vcol/inc/vcol_supported_sql_funcs.inc
+
diff --git a/mysql-test/suite/vcol/t/vcol_syntax.test b/mysql-test/suite/vcol/t/vcol_syntax.test
new file mode 100644
index 00000000..c26c4897
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_syntax.test
@@ -0,0 +1,189 @@
+#
+# test syntax
+#
+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;
+
+--echo #
+--echo # MDEV-25091 CREATE TABLE: field references qualified by a wrong table name succeed
+--echo #
+create table t2 (x int);
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, y int generated always as (t2.x));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, y int check (y > t2.x));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, y int default t2.x);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, check (t2.x > 0));
+
+create table t1 (x int);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add column y int generated always as (t2.x);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add column y int check (z > t2.x);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add column y int default t2.x;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add constraint check (t2.x > 0);
+
+create or replace table t1 (x int, y int generated always as (t1.x));
+create or replace table t1 (x int, y int check (y > t1.x));
+create or replace table t1 (x int, y int default t1.x);
+create or replace table t1 (x int, check (t1.x > 0));
+
+create or replace table t1 (x int, y int generated always as (test.t1.x));
+create or replace table t1 (x int, y int check (y > test.t1.x));
+create or replace table t1 (x int, y int default test.t1.x);
+create or replace table t1 (x int, check (test.t1.x > 0));
+
+drop tables t1, t2;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, y int generated always as (test2.t1.x));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, y int check (y > test2.t1.x));
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, y int default test2.t1.x);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t1 (x int, check (test2.t1.x > 0));
+
+--echo #
+--echo # MDEV-25672 table alias from previous statement interferes later commands
+--echo #
+create table t1 (a int, v_a int generated always as (a));
+update t1 as x set a = 1;
+alter table t1 force;
+drop table t1;
+
+create table t1 (
+ id int not null auto_increment primary key,
+ order_date_time datetime not null,
+ order_date date generated always as (convert(order_date_time, date)),
+ language_id binary(16) null
+);
+
+update t1 as tx set order_date= null;
+alter table t1 modify column language_id binary(16) not null;
+# Cleanup
+drop table t1;
+
+--echo #
+--echo # MDEV-24176 Server crashes after insert in the table with virtual column generated using date_format() and if()
+--echo #
+create table t1 (d1 date not null, d2 date not null,
+ gd text as (concat(d1,if(d1 <> d2, date_format(d2, 'to %y-%m-%d '), ''))) );
+
+insert into t1(d1,d2) values
+ ('2020-09-01','2020-09-01'),('2020-05-01','2020-09-01');
+select * from t1;
+
+drop table t1;
+
+--echo # MDEV-25772 (duplicate) and LOCK TABLES case
+create table t1 (d1 datetime , v_d1 tinyint(1) as (d1 < curdate()));
+insert into t1 (d1) values ('2021-09-11 08:38:23'), ('2021-09-01 08:38:23');
+
+lock tables t1 write;
+select * from t1 where v_d1=1;
+select * from t1;
+unlock tables;
+
+drop table t1;
+
+--echo # MDEV-26432 (duplicate)
+create table t1 (v2 int, v1 int as ((user() like 'x'))) ;
+select 1 from t1 where v1=1 ;
+select * from t1;
+
+drop table t1;
+
+create table t1 (v2 int as ( user () like 'x'));
+select 1 from t1 order by v2 ;
+alter table t1 add i int;
+drop table t1;
+
+--echo # MDEV-26437 (duplicate)
+create table v0 (v2 int not null,
+ v1 bigint as (case 'x' when current_user() then v2 end));
+
+select v2 as v3 from v0 where v1 like 'x' escape 'x';
+insert into v0 (v2) values (-128);
+
+drop table v0;
+
+create table t1 (vi int as (case 'x' when current_user() then 1 end));
+select 1 from t1 where vi=1;
+show create table t1;
+
+drop table t1;
+
+create table t1 (vi int as (case 'x' when current_user() then 1 end));
+select 1 from t1 where vi=1;
+select 1 from t1 where vi=1;
+
+drop table t1;
+
+--echo # MDEV-28092 (duplicate)
+create table t1 (b timestamp, a int as (1 in (dayofmonth (b between 'x' and current_user) = b)));
+insert into t1(b) values ('2022-03-17 14:55:37');
+
+select 1 from t1 x natural join t1;
+drop table t1;
+
+--echo # MDEV-28089 (duplicate)
+create table t1 (a int , b date as (1 in ('x' ,(database () = 'x' is null) ))) ;
+select b from t1;
+select a from t1 order by 'x' = b;
+drop table t1;
+
+create table t1 (a int , b date as (1 in ('x' ,(database ()) ))) ;
+select b from t1;
+select a from t1 order by 'x' = b;
+drop table t1;
+
+--echo #
+--echo # MDEV-31319 Assertion const_item_cache == true failed in Item_func::fix_fields
+--echo #
+create table t (f1 int, f2 int, fv int generated always as (case user() when 'foo' or 'bar' then f1 else f2 end) virtual);
+select * from t;
+insert into t (f1,f2) values(1,1);
+select * from t;
+create table tmp as select * from information_schema.tables where table_name = 't';
+select * from t;
+
+# cleanup
+drop table t, tmp;
+
+--echo #
+--echo # MDEV-29357 Assertion (fixed) in Item_func_dayname on INSERT
+--echo #
+set sql_mode='';
+create table t (c1 blob ,c2 int,c3 char(10) as (dayname (c2)));
+create trigger tr before insert on t for each row set new.c2=0;
+insert into t values (0, 0, 0);
+insert into t values (1, 1, 1);
+
+drop trigger tr;
+drop table t;
diff --git a/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test b/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test
new file mode 100644
index 00000000..c35a1279
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_trigger_sp_innodb.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test b/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test
new file mode 100644
index 00000000..d5f36d80
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_trigger_sp_myisam.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/vcol_view_innodb.test b/mysql-test/suite/vcol/t/vcol_view_innodb.test
new file mode 100644
index 00000000..3b869425
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_view_innodb.test
@@ -0,0 +1,55 @@
+################################################################################
+# 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.default_storage_engine = 'InnoDB';
+SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent=0;
+
+##### 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
+
+SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent;
+
+#------------------------------------------------------------------------------#
+# Cleanup
+--source suite/vcol/inc/vcol_cleanup.inc
diff --git a/mysql-test/suite/vcol/t/vcol_view_myisam.test b/mysql-test/suite/vcol/t/vcol_view_myisam.test
new file mode 100644
index 00000000..1b4a387a
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_view_myisam.test
@@ -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.default_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
diff --git a/mysql-test/suite/vcol/t/wrong_arena.test b/mysql-test/suite/vcol/t/wrong_arena.test
new file mode 100644
index 00000000..4b6f9415
--- /dev/null
+++ b/mysql-test/suite/vcol/t/wrong_arena.test
@@ -0,0 +1,66 @@
+#
+# This tests various issues when vcol items allocate memory (e.g. more items)
+# not in the TABLE::expr_arena.
+#
+
+--echo #
+--echo # MDEV-9690 concurrent queries with virtual columns crash in temporal code
+--echo #
+create table t1 (a datetime,
+ # get_datetime_value
+ b int as (a > 1), # Arg_comparator
+ c int as (a in (1,2,3)), # in_datetime
+ d int as ((a,a) in ((1,1),(2,1),(NULL,1))), # cmp_item_datetime
+ # other issues
+ e int as ((a,1) in ((1,1),(2,1),(NULL,1))) # cmp_item_row::alloc_comparators()
+);
+enable_prepare_warnings;
+show create table t1;
+disable_prepare_warnings;
+connect con1, localhost, root;
+disable_warnings;
+insert t1 (a) values ('2010-10-10 10:10:10');
+enable_warnings;
+#Enable after fix MDEV-31359
+--disable_ps2_protocol
+select * from t1;
+--enable_ps2_protocol
+disconnect con1;
+connection default;
+disable_warnings;
+select * from t1;
+enable_warnings;
+drop table t1;
+
+connect con1, localhost, root;
+create table t1 (a datetime,
+ b datetime as (least(a,1)) # Item_func_min_max::get_date
+);
+insert t1 (a) values ('2010-10-10 10:10:10');
+select * from t1;
+disconnect con1;
+connection default;
+select * from t1;
+drop table t1;
+
+--echo #
+--echo # MDEV-13435 Crash when selecting virtual columns generated using JSON functions
+--echo #
+create table t1 (
+ id int not null ,
+ js varchar(1000) not null,
+ t time AS (cast(json_value(json_extract(js,concat('$.singleDay."', dayname(curdate()),'"')),'$.start') as time)) virtual);
+insert into t1(id,js) values (0, '{"default" : {"start": "00:00:00", "end":"23:59:50"}}');
+select * from t1;
+drop table t1;
+
+--echo #
+--echo # MDEV-26281 ASAN use-after-poison when complex conversion is involved in blob
+--echo #
+create table t1 (v2 blob as ('a' is null), a1 int, a char(1) as (cast(a1 in (0,current_user() is null) as char(16777216) )));
+insert ignore into t1 values ('x','x',v2) ;
+drop table t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #