From f51ecfee933f4dc004c35c73c6662f0ab9a8346c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 12 Feb 2018 00:06:40 +0100 Subject: [PATCH] MDEV-15146 SQLError[4122]: View is not system versioned don't expand AS OF in views, and, in particular, don't auto-add AS OF NOW(). --- mysql-test/suite/versioning/r/view.result | 27 +++++++++--- mysql-test/suite/versioning/t/view.test | 18 +++++++- sql/share/errmsg-utf8.txt | 2 +- sql/sql_select.cc | 54 ++++++++++++++++++++--- sql/table.h | 2 + 5 files changed, 88 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result index 209a7aa77a1..f94cf4567db 100644 --- a/mysql-test/suite/versioning/r/view.result +++ b/mysql-test/suite/versioning/r/view.result @@ -17,7 +17,7 @@ x create or replace view vt1 as select * from t1; show create view vt1; View Create View character_set_client collation_connection -vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` FOR SYSTEM_TIME ALL where `t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null latin1 latin1_swedish_ci +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` latin1 latin1_swedish_ci drop view vt1; drop view vt2; create or replace view vt1 as select * from t1 for system_time all; @@ -69,7 +69,7 @@ create or replace table t1 (x int) with system versioning; create or replace view vt1(c) as select x from t1; show create view vt1; View Create View character_set_client collation_connection -vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `c` from `t1` FOR SYSTEM_TIME ALL where `t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null latin1 latin1_swedish_ci +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `c` from `t1` latin1 latin1_swedish_ci # VIEW over JOIN of versioned tables [#153] create or replace table t1 (a int) with system versioning; create or replace table t2 (b int) with system versioning; @@ -87,15 +87,15 @@ create or replace table t3 (x int); create or replace view vt1 as select * from t1, t2, t3; show create view vt1; View Create View character_set_client collation_connection -vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x` from ((`t1` FOR SYSTEM_TIME ALL join `t2` FOR SYSTEM_TIME ALL) join `t3`) where (`t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null) and (`t2`.`row_end` = MAX_RESULT or `t2`.`row_end` is null) latin1 latin1_swedish_ci +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x` from ((`t1` join `t2`) join `t3`) latin1 latin1_swedish_ci create or replace view vt1 as select * from t3, t2, t1; show create view vt1; View Create View character_set_client collation_connection -vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a` from ((`t3` join `t2` FOR SYSTEM_TIME ALL) join `t1` FOR SYSTEM_TIME ALL) where (`t2`.`row_end` = MAX_RESULT or `t2`.`row_end` is null) and (`t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null) latin1 latin1_swedish_ci +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a` from ((`t3` join `t2`) join `t1`) latin1 latin1_swedish_ci create or replace view vt1 as select a, t2.row_end as endo from t3, t1, t2; show create view vt1; View Create View character_set_client collation_connection -vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`row_end` AS `endo` from ((`t3` join `t1` FOR SYSTEM_TIME ALL) join `t2` FOR SYSTEM_TIME ALL) where (`t1`.`row_end` = MAX_RESULT or `t1`.`row_end` is null) and (`t2`.`row_end` = MAX_RESULT or `t2`.`row_end` is null) latin1 latin1_swedish_ci +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`row_end` AS `endo` from ((`t3` join `t1`) join `t2`) latin1 latin1_swedish_ci # VIEW over UNION [#269] create or replace view vt1 as select * from t1 union select * from t1; select * from vt1; @@ -118,3 +118,20 @@ execute stmt; a drop database test; create database test; +use test; +create table t1 (a int) with system versioning; +insert t1 values (1),(2); +set @a=now(6); +create view v1 as select * from t1; +delete from t1; +select * from v1; +a +select * from v1 for system_time as of @a; +a +1 +2 +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci +drop view v1; +drop table t1; diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test index 56e322477e7..a83820a0419 100644 --- a/mysql-test/suite/versioning/t/view.test +++ b/mysql-test/suite/versioning/t/view.test @@ -96,7 +96,21 @@ create or replace table t2 (b int) with system versioning; prepare stmt from 'select a from v1 inner join t2 group by a order by a'; execute stmt; execute stmt; - - drop database test; create database test; +use test; + +# +# MDEV-15146 SQLError[4122]: View is not system versioned +# + +create table t1 (a int) with system versioning; +insert t1 values (1),(2); +set @a=now(6); +create view v1 as select * from t1; +delete from t1; +select * from v1; +select * from v1 for system_time as of @a; +show create view v1; +drop view v1; +drop table t1; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 353d5212e6b..c860b580a26 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7825,7 +7825,7 @@ ER_VERS_FIELD_WRONG_TYPE ER_VERS_ENGINE_UNSUPPORTED eng "Transaction system versioning for %`s is not supported" -ER_UNUSED_22 +ER_UNUSED_23 eng "You should never see it" ER_PARTITION_WRONG_TYPE diff --git a/sql/sql_select.cc b/sql/sql_select.cc index da43c2217a9..66d96dd62dc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -690,6 +690,47 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd) return false; } +void vers_select_conds_t::print(String *str, enum_query_type query_type) +{ + const static LEX_CSTRING unit_type[]= + { + { STRING_WITH_LEN("") }, + { STRING_WITH_LEN("TIMESTAMP ") }, + { STRING_WITH_LEN("TRANACTION ") } + }; + switch (type) { + case SYSTEM_TIME_UNSPECIFIED: + break; + case SYSTEM_TIME_AS_OF: + str->append(STRING_WITH_LEN(" FOR SYSTEM_TIME AS OF ")); + str->append(unit_type + unit_start); + start->print(str, query_type); + break; + case SYSTEM_TIME_FROM_TO: + str->append(STRING_WITH_LEN(" FOR SYSTEM_TIME FROM ")); + str->append(unit_type + unit_start); + start->print(str, query_type); + str->append(STRING_WITH_LEN(" TO ")); + str->append(unit_type + unit_end); + end->print(str, query_type); + break; + case SYSTEM_TIME_BETWEEN: + str->append(STRING_WITH_LEN(" FOR SYSTEM_TIME BETWEEN ")); + str->append(unit_type + unit_start); + start->print(str, query_type); + str->append(STRING_WITH_LEN(" AND ")); + str->append(unit_type + unit_end); + end->print(str, query_type); + break; + case SYSTEM_TIME_BEFORE: + DBUG_ASSERT(0); + break; + case SYSTEM_TIME_ALL: + str->append(" FOR SYSTEM_TIME ALL"); + break; + } +} + int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr) { DBUG_ENTER("SELECT_LEX::vers_setup_cond"); @@ -704,6 +745,9 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr DBUG_RETURN(0); } + if (thd->lex->is_view_context_analysis()) + DBUG_RETURN(0); + if (!versioned_tables) { for (table= tables; table; table= table->next_local) @@ -977,6 +1021,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr DBUG_ASSERT(0); } } + vers_conditions.type= SYSTEM_TIME_ALL; if (cond1) { @@ -1005,9 +1050,6 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr this->where->top_level_item(); } - if (outer_table) - outer_table->vers_conditions.type= SYSTEM_TIME_ALL; - // Invalidate current SP [#52, #422] if (thd->spcont) { @@ -25998,10 +26040,8 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, #endif /* WITH_PARTITION_STORAGE_ENGINE */ } if (table && table->versioned()) - { - // versioning conditions are already unwrapped to WHERE clause - str->append(" FOR SYSTEM_TIME ALL"); - } + vers_conditions.print(str, query_type); + if (my_strcasecmp(table_alias_charset, cmp_name, alias.str)) { char t_alias_buff[MAX_ALIAS_NAME]; diff --git a/sql/table.h b/sql/table.h index b6adbfc6188..917439c243d 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1900,6 +1900,8 @@ struct vers_select_conds_t Item * s= NULL, vers_sys_type_t u_end= VERS_UNDEFINED, Item * e= NULL); + void print(String *str, enum_query_type query_type); + bool init_from_sysvar(THD *thd); bool operator== (vers_system_time_t b)