diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2019-12-02 12:46:15 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2019-12-02 12:46:15 +0300 |
commit | 1d46923a0f6508d52d7ce679a7dd8e7e0e957ae4 (patch) | |
tree | e49b51394ca259fb5e54be41df8fb382f49fa420 | |
parent | a3b63b8da36b5896dc0093fdbceb2851e0a04214 (diff) | |
download | mariadb-git-1d46923a0f6508d52d7ce679a7dd8e7e0e957ae4.tar.gz |
MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED (10.4)
Don't do skip_setup_conds() unless all errors are checked.
Fixes following errors:
ER_PERIOD_NOT_FOUND
ER_VERS_QUERY_IN_PARTITION
ER_VERS_ENGINE_UNSUPPORTED
ER_VERS_NOT_VERSIONED
-rw-r--r-- | mysql-test/suite/period/r/delete.result | 12 | ||||
-rw-r--r-- | mysql-test/suite/period/t/delete.test | 14 | ||||
-rw-r--r-- | mysql-test/suite/versioning/r/partition.result | 8 | ||||
-rw-r--r-- | mysql-test/suite/versioning/r/select.result | 15 | ||||
-rw-r--r-- | mysql-test/suite/versioning/r/view.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/versioning/t/partition.test | 8 | ||||
-rw-r--r-- | mysql-test/suite/versioning/t/select.test | 15 | ||||
-rw-r--r-- | sql/sql_select.cc | 59 | ||||
-rw-r--r-- | sql/table.h | 13 |
9 files changed, 118 insertions, 28 deletions
diff --git a/mysql-test/suite/period/r/delete.result b/mysql-test/suite/period/r/delete.result index 428200a4564..451017e5340 100644 --- a/mysql-test/suite/period/r/delete.result +++ b/mysql-test/suite/period/r/delete.result @@ -353,6 +353,18 @@ id s e datediff(e, s) 1 1999-01-01 1999-01-03 2 1 2018-12-10 2018-12-12 2 2 1999-01-01 1999-01-03 2 +# +# MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +# +create or replace table t1 (id int, s date, e date, period for apptime(s,e)); +create or replace procedure sp() +delete from t1 for portion of othertime from '2000-01-01' to '2018-01-01'; +call sp; +ERROR HY000: Period `othertime` is not found in table +call sp; +ERROR HY000: Period `othertime` is not found in table +drop table t1; +drop procedure sp; drop table t,t2,t3,log_tbl; drop view v; drop procedure log; diff --git a/mysql-test/suite/period/t/delete.test b/mysql-test/suite/period/t/delete.test index 00bc314160f..738d77d2c19 100644 --- a/mysql-test/suite/period/t/delete.test +++ b/mysql-test/suite/period/t/delete.test @@ -181,6 +181,20 @@ delete from t for portion of apptime from '1999-01-03' to '2018-12-10'; --sorted_result select *, datediff(e, s) from t; +--echo # +--echo # MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +--echo # +create or replace table t1 (id int, s date, e date, period for apptime(s,e)); +create or replace procedure sp() +delete from t1 for portion of othertime from '2000-01-01' to '2018-01-01'; +--error ER_PERIOD_NOT_FOUND +call sp; +--error ER_PERIOD_NOT_FOUND +call sp; +drop table t1; +drop procedure sp; + + drop table t,t2,t3,log_tbl; drop view v; drop procedure log; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 76268af9c3c..474f529bb8c 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -512,6 +512,14 @@ delete from t1 where a is not null; create or replace table t1 (i int) with system versioning partition by system_time limit 10 (partition p0 history, partition pn current); select * from t1 partition (p0) for system_time all; ERROR HY000: SYSTEM_TIME partitions in table `t1` does not support historical query +# MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +create or replace procedure sp() +select * from t1 partition (p0) for system_time all; +call sp; +ERROR HY000: SYSTEM_TIME partitions in table `t1` does not support historical query +call sp; +ERROR HY000: SYSTEM_TIME partitions in table `t1` does not support historical query +drop procedure sp; # MDEV-15380 Index for versioned table gets corrupt after partitioning and DELETE create or replace table t1 (pk int primary key) engine=myisam diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 3569268ce1d..b63e6222581 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -356,6 +356,21 @@ ERROR HY000: Table `t` is not system-versioned create or replace table t1 (x int) with system versioning engine myisam; select * from t1 for system_time as of transaction 1; ERROR HY000: Transaction-precise system versioning for `t1` is not supported +# MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +create or replace procedure sp() +select * from t1 for system_time as of transaction 1; +call sp; +ERROR HY000: Transaction-precise system versioning for `t1` is not supported +call sp; +ERROR HY000: Transaction-precise system versioning for `t1` is not supported +create or replace table t1 (a int); +create or replace procedure sp() +select * from t1 for system_time all; +call sp; +ERROR HY000: Table `t1` is not system-versioned +call sp; +ERROR HY000: Table `t1` is not system-versioned +drop procedure sp; create or replace table t1 ( x int, sys_trx_start bigint unsigned as row start invisible, diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result index 8b23e87d6a4..b33602f7336 100644 --- a/mysql-test/suite/versioning/r/view.result +++ b/mysql-test/suite/versioning/r/view.result @@ -146,7 +146,7 @@ i create or replace view v1 as select * from t1 for system_time as of date_sub(now(), interval 6 second); 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`.`i` AS `i` from `t1` FOR SYSTEM_TIME AS OF current_timestamp() - interval 6 second latin1 latin1_swedish_ci +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp() - interval 6 second latin1 latin1_swedish_ci drop view v1, vt1, vt12; drop tables t1, t3; # diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index bf6dd18118e..88f6a45b301 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -446,6 +446,14 @@ delete from t1 where a is not null; create or replace table t1 (i int) with system versioning partition by system_time limit 10 (partition p0 history, partition pn current); --error ER_VERS_QUERY_IN_PARTITION select * from t1 partition (p0) for system_time all; +--echo # MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +create or replace procedure sp() +select * from t1 partition (p0) for system_time all; +--error ER_VERS_QUERY_IN_PARTITION +call sp; +--error ER_VERS_QUERY_IN_PARTITION +call sp; +drop procedure sp; --echo # MDEV-15380 Index for versioned table gets corrupt after partitioning and DELETE create or replace table t1 (pk int primary key) diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index c4c1d703ce5..5771b9652f5 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -228,6 +228,21 @@ for system_time all as t; create or replace table t1 (x int) with system versioning engine myisam; --error ER_VERS_ENGINE_UNSUPPORTED select * from t1 for system_time as of transaction 1; +--echo # MDEV-18929 2nd execution of SP does not detect ER_VERS_NOT_VERSIONED +create or replace procedure sp() +select * from t1 for system_time as of transaction 1; +--error ER_VERS_ENGINE_UNSUPPORTED +call sp; +--error ER_VERS_ENGINE_UNSUPPORTED +call sp; +create or replace table t1 (a int); +create or replace procedure sp() +select * from t1 for system_time all; +--error ER_VERS_NOT_VERSIONED +call sp; +--error ER_VERS_NOT_VERSIONED +call sp; +drop procedure sp; create or replace table t1 ( x int, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a50736047cd..337b1d5e02a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -888,9 +888,7 @@ bool skip_setup_conds(THD *thd) int SELECT_LEX::period_setup_conds(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("SELECT_LEX::period_setup_conds"); - - if (skip_setup_conds(thd)) - DBUG_RETURN(0); + const bool update_conds= !skip_setup_conds(thd); Query_arena backup; Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup); @@ -911,11 +909,15 @@ int SELECT_LEX::period_setup_conds(THD *thd, TABLE_LIST *tables) DBUG_RETURN(-1); } - conds.period= &table->table->s->period; - result= and_items(thd, result, - period_get_condition(thd, table, this, &conds, true)); + if (update_conds) + { + conds.period= &table->table->s->period; + result= and_items(thd, result, + period_get_condition(thd, table, this, &conds, true)); + } } - where= and_items(thd, where, result); + if (update_conds) + where= and_items(thd, where, result); if (arena) thd->restore_active_arena(arena, &backup); @@ -926,9 +928,7 @@ int SELECT_LEX::period_setup_conds(THD *thd, TABLE_LIST *tables) int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("SELECT_LEX::vers_setup_conds"); - - if (skip_setup_conds(thd)) - DBUG_RETURN(0); + const bool update_conds= !skip_setup_conds(thd); if (!versioned_tables) { @@ -999,13 +999,15 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) */ if (table->partition_names && table->table->part_info->vers_info) { - if (vers_conditions.is_set()) + /* If the history is stored in partitions, then partitions + themselves are not versioned. */ + if (vers_conditions.was_set()) { my_error(ER_VERS_QUERY_IN_PARTITION, MYF(0), table->alias.str); DBUG_RETURN(-1); } - else - vers_conditions.init(SYSTEM_TIME_ALL); + else if (!vers_conditions.is_set()) + vers_conditions.set_all(); } #endif @@ -1050,24 +1052,27 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } } - vers_conditions.period = &table->table->s->vers; - Item *cond= period_get_condition(thd, table, this, &vers_conditions, - timestamps_only); - if (is_select) - table->on_expr= and_items(thd, table->on_expr, cond); - else + if (update_conds) { - if (join) + vers_conditions.period = &table->table->s->vers; + Item *cond= period_get_condition(thd, table, this, &vers_conditions, + timestamps_only); + if (is_select) + table->on_expr= and_items(thd, table->on_expr, cond); + else { - where= and_items(thd, join->conds, cond); - join->conds= where; + if (join) + { + where= and_items(thd, join->conds, cond); + join->conds= where; + } + else + where= and_items(thd, where, cond); + table->where= and_items(thd, table->where, cond); } - else - where= and_items(thd, where, cond); - table->where= and_items(thd, table->where, cond); - } - table->vers_conditions.type= SYSTEM_TIME_ALL; + table->vers_conditions.set_all(); + } } // for (table= tables; ...) DBUG_RETURN(0); diff --git a/sql/table.h b/sql/table.h index ae46b192854..6b125fe43ad 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1929,6 +1929,7 @@ public: struct vers_select_conds_t { vers_system_time_t type; + vers_system_time_t orig_type; bool used:1; bool delete_history:1; Vers_history_point start; @@ -1943,6 +1944,7 @@ struct vers_select_conds_t void empty() { type= SYSTEM_TIME_UNSPECIFIED; + orig_type= SYSTEM_TIME_UNSPECIFIED; used= false; delete_history= false; start.empty(); @@ -1955,6 +1957,7 @@ struct vers_select_conds_t Lex_ident _name= "SYSTEM_TIME") { type= _type; + orig_type= _type; used= false; delete_history= (type == SYSTEM_TIME_HISTORY || type == SYSTEM_TIME_BEFORE); @@ -1963,6 +1966,12 @@ struct vers_select_conds_t name= _name; } + void set_all() + { + type= SYSTEM_TIME_ALL; + name= "SYSTEM_TIME"; + } + void print(String *str, enum_query_type query_type) const; bool init_from_sysvar(THD *thd); @@ -1971,6 +1980,10 @@ struct vers_select_conds_t { return type != SYSTEM_TIME_UNSPECIFIED; } + bool was_set() const + { + return orig_type != SYSTEM_TIME_UNSPECIFIED; + } bool resolve_units(THD *thd); bool eq(const vers_select_conds_t &conds) const; }; |