From 47ea526efa755750c17b68e799617fb69169a2e7 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 28 Nov 2017 21:40:27 +0300 Subject: [PATCH] IB: get template with virtual columns [#365 bug 1] Affected tests (forced mode): binlog_encryption.encrypted_slave --- mysql-test/suite/versioning/r/insert.result | 10 ++++++++++ mysql-test/suite/versioning/t/insert.test | 9 +++++++++ storage/innobase/include/row0mysql.h | 14 ++++++++++++++ storage/innobase/row/row0mysql.cc | 8 ++++---- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result index b7a133e2ccd..f01ba09584e 100644 --- a/mysql-test/suite/versioning/r/insert.result +++ b/mysql-test/suite/versioning/r/insert.result @@ -360,6 +360,16 @@ insert into t2(x) values (1); insert into t1(x) values (1); ERROR HY000: Some versioned DML requires `transaction_registry` to be set to ON. set global transaction_registry= on; +create or replace table t1 ( +x int, +y int as (x) virtual +) engine=innodb with system versioning; +insert into t1 values (1, null); +update t1 set x= x + 1; +select *, sys_trx_end = 18446744073709551615 as current from t1 for system_time all; +x y current +2 2 1 +1 1 0 drop table t1; drop table t2; drop procedure test_01; diff --git a/mysql-test/suite/versioning/t/insert.test b/mysql-test/suite/versioning/t/insert.test index 666ae370a21..cf5d1659223 100644 --- a/mysql-test/suite/versioning/t/insert.test +++ b/mysql-test/suite/versioning/t/insert.test @@ -191,6 +191,15 @@ insert into t2(x) values (1); insert into t1(x) values (1); set global transaction_registry= on; +# virtual columns +create or replace table t1 ( + x int, + y int as (x) virtual +) engine=innodb with system versioning; +insert into t1 values (1, null); +update t1 set x= x + 1; +select *, sys_trx_end = 18446744073709551615 as current from t1 for system_time all; + drop table t1; drop table t2; diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 3ff25024b1d..2f0b2289a08 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -859,6 +859,20 @@ struct row_prebuilt_t { /** The MySQL table object */ TABLE* m_mysql_table; + + /** Get template by column number */ + const mysql_row_templ_t* get_template_by_col(ulint col) const + { + ut_a(col < n_template); + ut_a(mysql_template); + for (int i = col; i < n_template; ++i) + { + const mysql_row_templ_t* templ = mysql_template + i; + if (!templ->is_virtual && templ->col_no == col) + return templ; + } + return NULL; + } }; /** Callback for row_mysql_sys_index_iterate() */ diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 7076b640f17..74dba51fae1 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1517,8 +1517,8 @@ row_insert_for_mysql( ut_ad(table->vers_start != table->vers_end); /* Return back modified fields into mysql_rec, so that upper logic may benefit from it (f.ex. 'on duplicate key'). */ - const mysql_row_templ_t* t = &prebuilt->mysql_template[table->vers_end]; - ut_ad(t->mysql_col_len == 8); + const mysql_row_templ_t* t = prebuilt->get_template_by_col(table->vers_end); + ut_ad(t && t->mysql_col_len == 8); if (ins_mode == ROW_INS_HISTORICAL) { set_tuple_col_8(node->row, table->vers_end, trx->id, node->vers_end_buf); @@ -1526,8 +1526,8 @@ row_insert_for_mysql( else /* ROW_INS_VERSIONED */ { set_tuple_col_8(node->row, table->vers_end, TRX_ID_MAX, node->vers_end_buf); int8store(&mysql_rec[t->mysql_col_offset], TRX_ID_MAX); - t = &prebuilt->mysql_template[table->vers_start]; - ut_ad(t->mysql_col_len == 8); + t = prebuilt->get_template_by_col(table->vers_start); + ut_ad(t && t->mysql_col_len == 8); set_tuple_col_8(node->row, table->vers_start, trx->id, node->vers_start_buf); int8store(&mysql_rec[t->mysql_col_offset], trx->id); }