From 29f52f76c66d4c3c991b4274029a68c301e1c8c3 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 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 not record a DDL statement or any stats for sequence tables such as seq_1_to_10. 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. --- mysql-test/main/opt_context_store_ddls.result | 35 +++++++++++++++++++ mysql-test/main/opt_context_store_ddls.test | 15 ++++++++ .../main/opt_context_store_stats.result | 16 +++++++++ mysql-test/main/opt_context_store_stats.test | 11 ++++++ sql/opt_context_store_replay.cc | 15 +++++--- 5 files changed, 88 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/opt_context_store_ddls.result b/mysql-test/main/opt_context_store_ddls.result index 4d1119dc76a68..0135d24727204 100644 --- a/mysql-test/main/opt_context_store_ddls.result +++ b/mysql-test/main/opt_context_store_ddls.result @@ -542,4 +542,39 @@ CREATE TABLE `t1` ( 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 `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; + + +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 +# === Optimizer Context DDLs +@ddls + +# 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..cf8fdc0fa6a4c 100644 --- a/mysql-test/main/opt_context_store_stats.result +++ b/mysql-test/main/opt_context_store_stats.result @@ -591,3 +591,19 @@ 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 +# === Range accesses +index_name ranges num_rows max_index_blocks max_row_blocks +# == End of optimizer context +# 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..752f672a6bf65 100644 --- a/mysql-test/main/opt_context_store_stats.test +++ b/mysql-test/main/opt_context_store_stats.test @@ -432,3 +432,14 @@ 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 # End of 13.1 tests diff --git a/sql/opt_context_store_replay.cc b/sql/opt_context_store_replay.cc index fcc4f7018d926..5a6920ffb9f26 100644 --- a/sql/opt_context_store_replay.cc +++ b/sql/opt_context_store_replay.cc @@ -756,10 +756,14 @@ bool Optimizer_context_recorder::dump_sql_script(THD* thd, String &sql_script) append_table_or_view_name(tbl, &full_tbl_name); /* - Sequence table doesn't need CREATE TABLE or contain any stats + Sequence table such as seq_1_to_10 is a virtual table and so + doesn't need CREATE TABLE STATEMENT, and stats. */ - if (tbl->table && tbl->table->s && tbl->table->s->sequence) + if (!tbl->is_view() && tbl->table && + tbl->table->s->db_type()->discover_table) + { continue; + } /* A query can use the same table multiple times. Do not dump the @@ -809,8 +813,11 @@ 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 (tbl->is_view()) + /* If this is a VIEW or a SEQUENCE table as + CREATE SEQUENCE s1; + explain SELECT * FROM s1; + we've stored its DDL and we're done. */ + if (tbl->is_view() || (tbl->table && tbl->table->s->sequence)) continue; /* No, it's a base table */