MDEV-40388: sequence.simple fails on replay#5427
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the logic in Optimizer_context_recorder::dump_sql_script to identify sequence tables by checking if the storage engine name is "SEQUENCE" instead of checking the sequence flag on the table share. The reviewer suggested a performance and code-simplification improvement: accessing the storage engine's handlerton directly from the table share (tbl->table->s->db_type) instead of calling the virtual method partition_ht() on the handler.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (!tbl->is_view() && tbl->table) | ||
| { | ||
| handlerton *hton= tbl->table->file->partition_ht(); | ||
| const LEX_CSTRING *engine_name= hton_name(hton); | ||
| if (strcmp(engine_name->str, "SEQUENCE") == 0) | ||
| continue; | ||
| } |
There was a problem hiding this comment.
Instead of calling the virtual method partition_ht() on the handler (tbl->table->file), you can directly access the storage engine's handlerton from the table share (tbl->table->s->db_type). This is more direct, avoids a virtual function call, and simplifies the code.
if (!tbl->is_view() && tbl->table)
{
const LEX_CSTRING *engine_name= hton_name(tbl->table->s->db_type);
if (strcmp(engine_name->str, "SEQUENCE") == 0)
continue;
}There was a problem hiding this comment.
actually here gemini absolutely right, why not tbl->table->file ?
There was a problem hiding this comment.
Why it is SQL_SEQUENCE or SEQUENCE if you need probably one, or could you say what is the difference?
There was a problem hiding this comment.
maybe use lex_string_eq ?
There was a problem hiding this comment.
Why it is SQL_SEQUENCE or SEQUENCE if you need probably one, or could you say what is the difference?
SEQUENCE is for the following eg: -
explain select * from seq_15_to_1_step_12345;
and SQL_SEQUENCE is for the following eg: -
create sequence s1;
EXPLAIN select * from s1;
There was a problem hiding this comment.
actually here gemini absolutely right, why not tbl->table->file ?
For this example
create sequence s1;
EXPLAIN select * from s1;
const LEX_CSTRING *engine_name= hton_name(tbl->table->s->db_type());
is seen as InnoDB or MyISAM, and not SQL_SEQUENCE or SEQUENCE
d78faae to
b2f5d98
Compare
There was a problem hiding this comment.
Pull request overview
Fixes MDEV-40388 by ensuring optimizer context recording/replay does not attempt to capture DDL/stats for sequence tables, which can break replay (e.g., sequence.simple).
Changes:
- Update
Optimizer_context_recorder::dump_sql_script()to skip sequence tables based on storage engine name instead ofTABLE_SHARE::sequence. - Add a regression test case to verify sequence tables are not recorded in optimizer context output.
- Update the expected result file accordingly.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
sql/opt_context_store_replay.cc |
Changes sequence-table detection logic to skip recording sequence tables during context dump. |
mysql-test/main/opt_context_store_stats.test |
Adds a regression test query against a sequence under optimizer_record_context=ON. |
mysql-test/main/opt_context_store_stats.result |
Records expected output for the new regression test section. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!tbl->is_view() && tbl->table) | ||
| { | ||
| handlerton *hton= tbl->table->file->partition_ht(); | ||
| const LEX_CSTRING *engine_name= hton_name(hton); | ||
| if (strcmp(engine_name->str, "SEQUENCE") == 0 || | ||
| strcmp(engine_name->str, "SQL_SEQUENCE") == 0) | ||
| { | ||
| continue; | ||
| } | ||
| } |
| set optimizer_record_context=ON; | ||
| explain select * from seq_15_to_1_step_12345; | ||
| id select_type table type possible_keys key key_len ref rows Extra | ||
| 1 SIMPLE seq_15_to_1_step_12345 ALL NULL NULL NULL NULL 1 | ||
| # == 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 |
There was a problem hiding this comment.
not required
| set optimizer_record_context=ON; | ||
| explain select * from seq_15_to_1_step_12345; | ||
|
|
||
| --source include/opt_context_list_tables_and_ranges.inc |
There was a problem hiding this comment.
not required
sanja-byelkin
left a comment
There was a problem hiding this comment.
The direction is correct, but please fix small things and answer questions
| if (!tbl->is_view() && tbl->table) | ||
| { | ||
| handlerton *hton= tbl->table->file->partition_ht(); | ||
| const LEX_CSTRING *engine_name= hton_name(hton); | ||
| if (strcmp(engine_name->str, "SEQUENCE") == 0) | ||
| continue; | ||
| } |
There was a problem hiding this comment.
actually here gemini absolutely right, why not tbl->table->file ?
| if (!tbl->is_view() && tbl->table) | ||
| { | ||
| handlerton *hton= tbl->table->file->partition_ht(); | ||
| const LEX_CSTRING *engine_name= hton_name(hton); | ||
| if (strcmp(engine_name->str, "SEQUENCE") == 0) | ||
| continue; | ||
| } |
There was a problem hiding this comment.
Why it is SQL_SEQUENCE or SEQUENCE if you need probably one, or could you say what is the difference?
| set optimizer_record_context=ON; | ||
| explain select * from seq_15_to_1_step_12345; | ||
|
|
||
| --source include/opt_context_list_tables_and_ranges.inc |
|
|
||
| --echo # | ||
| --echo # MDEV-40388: sequence.simple fails on replay | ||
| --echo # Table context should *not* be recorded for seq |
| if (!tbl->is_view() && tbl->table) | ||
| { | ||
| handlerton *hton= tbl->table->file->partition_ht(); | ||
| const LEX_CSTRING *engine_name= hton_name(hton); | ||
| if (strcmp(engine_name->str, "SEQUENCE") == 0) | ||
| continue; | ||
| } |
There was a problem hiding this comment.
maybe use lex_string_eq ?
b2f5d98 to
5abaa6b
Compare
|
Why the test fails on replay? Your commit comment doesn't explain anything besides repeating what the code does. |
When the recording is enabled for the query Now, when that context is replayed, the DDL statement is executed. But, we cannot create such the table and instead it errors out |
5abaa6b to
fe2e034
Compare
When the recording is enabled for the query,
explain select * from seq_15_to_1_step_12345;
it recorded the table context having a DDL definition as: -
CREATE TABLE `seq_15_to_1_step_12345` (
-> `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 the table and instead it errors out saying
ERROR 1050 (42S01): Table 'seq_15_to_1_step_12345' already exists.
The problem is that,
sequence table was determined using tbl->table->s->sequence. The
intention was to not record sequence table information. However, the
check was only partially correct.
Instead, we need an enhanced condition like: -
if (!tbl->is_view() && tbl->table)
{
if (tbl->table->s->sequence ||
lex_string_eq(hton_name(tbl->table->s->db_type()),
STRING_WITH_LEN("SEQUENCE")))
{
continue;
}
}
This makes both the following kinds of queries on sequences, to not
record any table contexts on them: -
1. explain select * from seq_15_to_1_step_12345;
2. create sequence s1;
EXPLAIN select * from s1;
fe2e034 to
a9983bf
Compare
When the recording is enabled for the query,
explain select * from seq_15_to_1_step_12345;
it recorded the table context having a DDL definition as: -
CREATE TABLE
seq_15_to_1_step_12345(->
seqbigint(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 the table and instead it errors out saying
ERROR 1050 (42S01): Table 'seq_15_to_1_step_12345' already exists.
The problem is that,
sequence table was determined using tbl->table->s->sequence. The
intention was to not record sequence table information. However, the
check was only partially correct.
Instead, we need an enhanced condition like: -
if (!tbl->is_view() && tbl->table)
{
if (tbl->table->s->sequence ||
lex_string_eq(hton_name(tbl->table->s->db_type()),
STRING_WITH_LEN("SEQUENCE")))
{
continue;
}
}
This makes both the following kinds of queries on sequences, to not
record any table contexts on them: -
EXPLAIN select * from s1;