From d7572ed6f3fdc10485cd92c4369044125f3730cc Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Tue, 21 Jul 2026 18:16:35 +0530 Subject: [PATCH] MDEV-40388: sequence.simple fails on replay The problem is that, when recording is enabled for the query such as, explain select * from seq_1_to_10; it recorded the table context having a DDL definition as: - CREATE TABLE `seq_1_to_10` ( -> `seq` bigint(20) unsigned NOT NULL, -> PRIMARY KEY (`seq`) -> ) ENGINE=SEQUENCE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; Now, when that context is replayed, the DDL statement is executed. But, we cannot create such a table, and instead it errors out saying ERROR 1050 (42S01): Table 'seq_1_to_10' already exists. Solution is to use: - CREATE TABLE IF NOT EXISTS seq_1_to_10 ...; ===== Also, there is a different way to use sequences as: - Create sequence s1; Explain select * from s1; Here, we should be recording the DDL statement, but no need to store the stats for it. However, we didn't record the DDL statement earlier. Moreover, sequence's next value should be the same in the replay environment. Solution here is to record the DDL for such a sequence as CREATE TABLE IF NOT EXISTS s1 ...; and also set its start value as the recorded environment's previous value using SELECT SETVAL(s1, prev_value); --- .../main/opt_context_replay_basic.result | 28 +++- mysql-test/main/opt_context_replay_basic.test | 29 +++- .../opt_context_replay_innodb_comp.result | 56 -------- .../opt_context_replay_innodb_pref.result | 56 -------- mysql-test/main/opt_context_store_ddls.result | 131 ++++++++++-------- mysql-test/main/opt_context_store_ddls.test | 15 ++ .../main/opt_context_store_stats.result | 47 +++++++ mysql-test/main/opt_context_store_stats.test | 36 +++++ sql/opt_context_store_replay.cc | 82 +++++++---- 9 files changed, 282 insertions(+), 198 deletions(-) diff --git a/mysql-test/main/opt_context_replay_basic.result b/mysql-test/main/opt_context_replay_basic.result index e8a091036c596..f2cca086e4dbc 100644 --- a/mysql-test/main/opt_context_replay_basic.result +++ b/mysql-test/main/opt_context_replay_basic.result @@ -118,10 +118,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' count(*) 20 set optimizer_replay_context='opt_context'; @@ -549,4 +545,28 @@ select context like '%bar%' from information_schema.optimizer_context; context like '%bar%' 1 drop table t1; +# +# MDEV-40388: sequence.simple fails on replay +# +set optimizer_record_context=0; +create sequence s1; +select setval(s1, 10); +setval(s1, 10) +10 +set optimizer_record_context=1; +select nextval(s1) as nv; +nv +11 +select context into dumpfile "../../tmp/dump1.sql" +from information_schema.optimizer_context; +set optimizer_record_context=0; +drop table s1; +set optimizer_replay_context='opt_context'; +# Get the last recorded value from the sequence; must have same output as above +select lastval(s1) as nv; +nv +11 +set optimizer_replay_context=''; +drop table s1; +# End of 13.1 tests drop database db1; diff --git a/mysql-test/main/opt_context_replay_basic.test b/mysql-test/main/opt_context_replay_basic.test index b8a17c0bf5758..961609f376e4e 100644 --- a/mysql-test/main/opt_context_replay_basic.test +++ b/mysql-test/main/opt_context_replay_basic.test @@ -1,6 +1,6 @@ --source include/not_embedded.inc --source include/have_sequence.inc ---source include/no_view_protocol.inc +--source include/no_protocol.inc --echo #enable optimizer_record_context set optimizer_trace=0; set optimizer_record_context=ON; @@ -351,4 +351,31 @@ explain select * from t1 where a >'foo' or a < 'bar'; select context like '%bar%' from information_schema.optimizer_context; drop table t1; + +--echo # +--echo # MDEV-40388: sequence.simple fails on replay +--echo # +set optimizer_record_context=0; +create sequence s1; +select setval(s1, 10); +set optimizer_record_context=1; +select nextval(s1) as nv; +select context into dumpfile "../../tmp/dump1.sql" +from information_schema.optimizer_context; +set optimizer_record_context=0; +drop table s1; +--disable_query_log +--disable_result_log +--source "$MYSQLTEST_VARDIR/tmp/dump1.sql" +--enable_query_log +--enable_result_log +set optimizer_replay_context='opt_context'; +--echo # Get the last recorded value from the sequence; must have same output as above +select lastval(s1) as nv; + +set optimizer_replay_context=''; +--remove_file "$MYSQLTEST_VARDIR/tmp/dump1.sql" +drop table s1; +--echo # End of 13.1 tests + drop database db1; diff --git a/mysql-test/main/opt_context_replay_innodb_comp.result b/mysql-test/main/opt_context_replay_innodb_comp.result index bda7dc1233baa..77ed14919ee9e 100644 --- a/mysql-test/main/opt_context_replay_innodb_comp.result +++ b/mysql-test/main/opt_context_replay_innodb_comp.result @@ -197,10 +197,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -323,10 +319,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -444,10 +436,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -569,10 +557,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -698,10 +682,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -823,10 +803,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -933,10 +909,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1033,10 +1005,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1115,10 +1083,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1206,10 +1170,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1295,10 +1255,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1383,10 +1339,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1496,10 +1448,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1634,10 +1582,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { diff --git a/mysql-test/main/opt_context_replay_innodb_pref.result b/mysql-test/main/opt_context_replay_innodb_pref.result index 1401eba480885..5d422e9d87c80 100644 --- a/mysql-test/main/opt_context_replay_innodb_pref.result +++ b/mysql-test/main/opt_context_replay_innodb_pref.result @@ -197,10 +197,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -323,10 +319,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -444,10 +436,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -569,10 +557,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -698,10 +682,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -823,10 +803,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -933,10 +909,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1033,10 +1005,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1115,10 +1083,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1206,10 +1170,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1295,10 +1255,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1383,10 +1339,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1496,10 +1448,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { @@ -1634,10 +1582,6 @@ Warnings: Warning 4200 The setting 'optimizer_adjust_secondary_key_costs' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: Note 1007 Can't create database 'db1'; database exists -Warnings: -Note 4092 Unknown VIEW: 'db1.t1' -Warnings: -Note 1051 Unknown table 'db1.t1' EXPLAIN { "query_block": { diff --git a/mysql-test/main/opt_context_store_ddls.result b/mysql-test/main/opt_context_store_ddls.result index 4d1119dc76a68..4781ba6d80596 100644 --- a/mysql-test/main/opt_context_store_ddls.result +++ b/mysql-test/main/opt_context_store_ddls.result @@ -37,7 +37,7 @@ name db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -67,7 +67,7 @@ name db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -86,20 +86,16 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.view1; -DROP TABLE IF EXISTS db1.view1; -CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW db1.view1 AS (select `db1`.`t1`.`a` AS `a`,`db1`.`t1`.`b` AS `b`,`db1`.`t2`.`a` AS `c` from (`db1`.`t1` join `db1`.`t2`) where `db1`.`t1`.`a` = `db1`.`t2`.`a`); +CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW IF NOT EXISTS db1.view1 AS (select `db1`.`t1`.`a` AS `a`,`db1`.`t1`.`b` AS `b`,`db1`.`t2`.`a` AS `c` from (`db1`.`t1` join `db1`.`t2`) where `db1`.`t1`.`a` = `db1`.`t2`.`a`); # @@ -114,13 +110,11 @@ db1.t2 db1.temp1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.temp1; -DROP TABLE IF EXISTS db1.temp1; -CREATE TEMPORARY TABLE `temp1` ( +CREATE TEMPORARY TABLE IF NOT EXISTS `temp1` ( `col1` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -138,7 +132,7 @@ name db1.t2 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -155,20 +149,16 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.view1; -DROP TABLE IF EXISTS db1.view1; -CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW db1.view1 AS (select `db1`.`t1`.`a` AS `a`,`db1`.`t1`.`b` AS `b`,`db1`.`t2`.`a` AS `c` from (`db1`.`t1` join `db1`.`t2`) where `db1`.`t1`.`a` = `db1`.`t2`.`a`); +CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW IF NOT EXISTS db1.view1 AS (select `db1`.`t1`.`a` AS `a`,`db1`.`t1`.`b` AS `b`,`db1`.`t2`.`a` AS `c` from (`db1`.`t1` join `db1`.`t2`) where `db1`.`t1`.`a` = `db1`.`t2`.`a`); # @@ -181,13 +171,11 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -203,7 +191,7 @@ name db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -219,7 +207,7 @@ name db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -236,13 +224,11 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -268,13 +254,11 @@ db2.t1 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `db2`.`t1` ( +CREATE TABLE IF NOT EXISTS `db2`.`t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -296,15 +280,13 @@ db2.t1 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; CREATE DATABASE IF NOT EXISTS db1; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `db1`.`t1` ( +CREATE TABLE IF NOT EXISTS `db1`.`t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -325,7 +307,7 @@ name db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `db1`.`t1` ( +CREATE TABLE IF NOT EXISTS `db1`.`t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -353,7 +335,7 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `a` int(11) NOT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) @@ -362,9 +344,7 @@ CREATE TABLE `t2` ( SET STATEMENT sql_mode=REPLACE(REPLACE(@@sql_mode,'STRICT_ALL_TABLES',''),'STRICT_TRANS_TABLES','') FOR REPLACE INTO db1.t2(a, b) VALUES (1, 1); -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -415,7 +395,7 @@ name db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `pk` int(11) NOT NULL, `a` int(11) DEFAULT NULL, PRIMARY KEY (`pk`), @@ -475,15 +455,13 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `id` int(11) DEFAULT NULL, `address` varchar(10) DEFAULT NULL, KEY `fk_id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) @@ -507,13 +485,11 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `id2` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `id1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id1`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; @@ -529,17 +505,58 @@ db1.t2 db1.t1 # === Optimizer Context DDLs @ddls -CREATE TABLE `t2` ( +CREATE TABLE IF NOT EXISTS `t2` ( `id2` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; -DROP VIEW IF EXISTS db1.t1; -DROP TABLE IF EXISTS db1.t1; -CREATE TABLE `t1` ( +CREATE TABLE IF NOT EXISTS `t1` ( `id1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id1`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; drop table t1, t2; +# +# MDEV-40388: sequence.simple fails on replay +# +create sequence s1; +# context result should have the ddl +explain select * from s1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE s1 system NULL NULL NULL NULL 1 +# == Optimizer Context Tables +name +# === Optimizer Context DDLs +@ddls +CREATE TABLE IF NOT EXISTS `s1` ( + `next_not_cached_value` bigint(21) NOT NULL, + `minimum_value` bigint(21) NOT NULL, + `maximum_value` bigint(21) NOT NULL, + `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used', + `increment` bigint(21) NOT NULL COMMENT 'increment value', + `cache_size` bigint(21) unsigned NOT NULL, + `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed', + `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done' +) ENGINE=MyISAM SEQUENCE=1; + +SELECT SETVAL(db1.s1, 1); + + +drop table s1; +# no ddl should be captured here +explain select * from seq_1_to_10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_10 index NULL PRIMARY 8 NULL 10 Using index +# == Optimizer Context Tables +name +db1.seq_1_to_10 +# === Optimizer Context DDLs +@ddls +CREATE TABLE IF NOT EXISTS `seq_1_to_10` ( + `seq` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`seq`) +) ENGINE=SEQUENCE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; + + +# End of 13.1 tests drop database db1; diff --git a/mysql-test/main/opt_context_store_ddls.test b/mysql-test/main/opt_context_store_ddls.test index 8fc42f1260a18..a0b025e0d2377 100644 --- a/mysql-test/main/opt_context_store_ddls.test +++ b/mysql-test/main/opt_context_store_ddls.test @@ -312,4 +312,19 @@ delete t1.*, t2.* from t1, t2 where t1.id1 = t2.id2; drop table t1, t2; +--echo # +--echo # MDEV-40388: sequence.simple fails on replay +--echo # +create sequence s1; +--echo # context result should have the ddl +explain select * from s1; +--source include/opt_context_list_tables_ddls.inc +drop table s1; + +--echo # no ddl should be captured here +explain select * from seq_1_to_10; +--source include/opt_context_list_tables_ddls.inc + +--echo # End of 13.1 tests + drop database db1; diff --git a/mysql-test/main/opt_context_store_stats.result b/mysql-test/main/opt_context_store_stats.result index 9c10e27ad40bf..7ae3049a8419d 100644 --- a/mysql-test/main/opt_context_store_stats.result +++ b/mysql-test/main/opt_context_store_stats.result @@ -591,3 +591,50 @@ table_name file_stat_records index_name rec_per_key index_name ranges num_rows max_index_blocks max_row_blocks # == End of optimizer context drop table s1; +# +# MDEV-40388: sequence.simple fails on replay +# Table context should *not* be recorded for seq +# +set optimizer_record_context=ON; +explain select * from seq_1_to_10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_10 index NULL PRIMARY 8 NULL 10 Using index +# == Optimizer Context +# === Tables +# Tables in the context +table_name file_stat_records index_name rec_per_key +test.seq_1_to_10 10 PRIMARY ["0"] +# === Range accesses +index_name ranges num_rows max_index_blocks max_row_blocks +# == End of optimizer context +# +# partitioned table test +# context result should have stats for this table +# +create table t1 ( +pk int primary key, +a int, +key (a) +) +engine=myisam +partition by range(pk) ( +partition p0 values less than (10), +partition p1 values less than MAXVALUE +); +insert into t1 select seq, MOD(seq, 100) from seq_1_to_5000; +flush tables; +explain +select * from t1 partition (p1) where a=10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 49 +# == Optimizer Context +# === Tables +# Tables in the context +table_name file_stat_records index_name rec_per_key +test.t1 4991 NULL NULL +# === Range accesses +index_name ranges num_rows max_index_blocks max_row_blocks +a ["(10) <= (a) <= (10)"] 49 1 11 +# == End of optimizer context +drop table t1; +# End of 13.1 tests diff --git a/mysql-test/main/opt_context_store_stats.test b/mysql-test/main/opt_context_store_stats.test index 3554477a6f07f..667b4f96f380e 100644 --- a/mysql-test/main/opt_context_store_stats.test +++ b/mysql-test/main/opt_context_store_stats.test @@ -1,5 +1,6 @@ --source include/not_embedded.inc --source include/have_sequence.inc +--source include/have_partition.inc --echo #enable optimizer_record_context --disable_replay testfile Don't replay a replay test @@ -432,3 +433,38 @@ EXPLAIN select * from s1; --source include/opt_context_list_tables_and_ranges.inc drop table s1; + +--echo # +--echo # MDEV-40388: sequence.simple fails on replay +--echo # Table context should *not* be recorded for seq +--echo # +set optimizer_record_context=ON; +explain select * from seq_1_to_10; + +--source include/opt_context_list_tables_and_ranges.inc + +--echo # +--echo # partitioned table test +--echo # context result should have stats for this table +--echo # +create table t1 ( + pk int primary key, + a int, + key (a) +) +engine=myisam +partition by range(pk) ( + partition p0 values less than (10), + partition p1 values less than MAXVALUE +); +insert into t1 select seq, MOD(seq, 100) from seq_1_to_5000; +flush tables; + +explain +select * from t1 partition (p1) where a=10; + +--source include/opt_context_list_tables_and_ranges.inc + +drop table t1; + +--echo # End of 13.1 tests diff --git a/sql/opt_context_store_replay.cc b/sql/opt_context_store_replay.cc index cc66a537f55f0..e69f3dca3c468 100644 --- a/sql/opt_context_store_replay.cc +++ b/sql/opt_context_store_replay.cc @@ -382,6 +382,7 @@ static void get_create_view_stmt(THD *thd, TABLE_LIST *table, String *name, buf->append(STRING_WITH_LEN("CREATE ")); view_store_options(thd, table, buf); buf->append(STRING_WITH_LEN("VIEW ")); + buf->append(STRING_WITH_LEN("IF NOT EXISTS ")); buf->append(*name); buf->append(STRING_WITH_LEN(" AS ")); buf->append(table->select_stmt.str, table->select_stmt.length); @@ -395,6 +396,17 @@ static bool get_create_table_stmt(THD *thd, TABLE_LIST *tbl, String *ddl) bool res= false; bool restore_mode= false; sql_mode_t saved_mode= thd->variables.sql_mode; + Table_specification_st create_info; + create_info.init(DDL_options_st::OPT_IF_NOT_EXISTS); + /* + A non-NULL create_info makes show_create_table() print only the clauses + whose used_fields bit is set. Set the bits for the clauses we want in the + dumped DDL (ENGINE=, DEFAULT CHARSET=, and engine-specific table options), + otherwise they are silently omitted. + */ + create_info.used_fields|= + HA_CREATE_USED_ENGINE | HA_CREATE_USED_DEFAULT_CHARSET | + HA_CREATE_USED_CHARSET | HA_CREATE_PRINT_ALL_OPTIONS; /* Some @@sql_mode settings prevent printing of essential table options like @@ -417,7 +429,7 @@ static bool get_create_table_stmt(THD *thd, TABLE_LIST *tbl, String *ddl) ddl->append(STRING_WITH_LEN("';\n")); } - if (show_create_table(thd, tbl, ddl, NULL, WITH_DB_NAME)) + if (show_create_table(thd, tbl, ddl, &create_info, WITH_DB_NAME)) res= true; if (restore_mode) @@ -670,18 +682,6 @@ bool store_optimizer_context(THD *thd) return res; } -static void store_drop_table_and_view_stmts(String &name, String &buf) -{ - StringBuffer<128> drop; - drop.append(STRING_WITH_LEN("DROP VIEW IF EXISTS ")); - drop.append(name); - drop.append(STRING_WITH_LEN(";\n")); - drop.append(STRING_WITH_LEN("DROP TABLE IF EXISTS ")); - drop.append(name); - drop.append(STRING_WITH_LEN(";\n")); - buf.append(drop); -} - /* @brief Dump definitions, basic stats of all tables and views used by the @@ -753,12 +753,6 @@ bool Optimizer_context_recorder::dump_sql_script(THD* thd, String &sql_script) LEX_CSTRING *tbl_name_key; append_table_or_view_name(tbl, &full_tbl_name); - /* - Sequence table doesn't need CREATE TABLE or contain any stats - */ - if (tbl->table && tbl->table->s && tbl->table->s->sequence) - continue; - /* A query can use the same table multiple times. Do not dump the DDL multiple times. @@ -790,8 +784,7 @@ bool Optimizer_context_recorder::dump_sql_script(THD* thd, String &sql_script) break; } - /* Add DROP and CREATE TABLE|VIEW statement */ - store_drop_table_and_view_stmts(full_tbl_name, qry_ctx_script); + /* Add CREATE TABLE|VIEW statement */ if (tbl->is_view()) { get_create_view_stmt(thd, tbl, &full_tbl_name, &ddl); @@ -807,20 +800,61 @@ bool Optimizer_context_recorder::dump_sql_script(THD* thd, String &sql_script) qry_ctx_script.append(ddl); qry_ctx_script.append(STRING_WITH_LEN(";\n\n")); - /* If this is a VIEW, we've stored its DDL and we're done. */ + /* If this is a VIEW we've stored its DDL and we're done. */ if (tbl->is_view()) continue; + /* + if this is a SEQUENCE table defined as + CREATE SEQUENCE s1; + then, record the current value of s1 as well, and then we're done. + DDL for it has already been recorded. + No need to record other stats. + */ + if (tbl->table->s->sequence) + { + const char *key; + uint length= get_table_def_key(tbl, &key); // table def key = hash key + SEQUENCE_LAST_VALUE *entry= (SEQUENCE_LAST_VALUE *) my_hash_search( + &thd->sequences, (uchar *) key, length); + SEQUENCE *seq= tbl->table->s->sequence; + longlong value; + if (entry && !entry->check_version(tbl->table)) + { + /* + Set the sequence so that the next NEXTVAL returns the value that + was last handed out (entry->value): SETVAL(x) makes the next + NEXTVAL return x + increment, so use entry->value - increment. + Keep the argument within the sequence bounds - for an ascending + sequence it may fall below min_value, for a descending one it may + rise above max_value, and SETVAL rejects out-of-range values. + */ + longlong candidate= entry->value - seq->increment; + value= seq->increment > 0 ? MY_MAX(candidate, seq->min_value) + : MY_MIN(candidate, seq->max_value); + } + else + value= seq->reserved_until; + + qry_ctx_script.append(STRING_WITH_LEN("SELECT SETVAL(")); + qry_ctx_script.append(full_tbl_name); + qry_ctx_script.append(STRING_WITH_LEN(", ")); + qry_ctx_script.append_longlong(value); + qry_ctx_script.append(STRING_WITH_LEN(");\n\n")); + + continue; + } + /* No, it's a base table */ Json_writer_object ctx_wrapper(&ctx_writer); /* Write basic table statistics */ - dump_table_stats(tbl, (uchar*)tbl_name_key->str, tbl_name_key->length, + dump_table_stats(tbl, (uchar *) tbl_name_key->str, tbl_name_key->length, ctx_wrapper, &ctx_writer); /* Find the table in the captured context */ table_context_for_store *table_context= - search((uchar *) tbl_name_key->str, tbl_name_key->length); + search((uchar *) tbl_name_key->str, tbl_name_key->length); if (table_context) {