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; | ||
| } | ||
| } |
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?
| 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 |
fe2e034 to
a9983bf
Compare
53e01d6 to
9636bdf
Compare
|
Verified: It fixes below tests |
77103a4 to
ee1b2a8
Compare
|
I suspect the best approach here is to use If you absolutely must have a check, check for This was about |
"CREATE IF NOT EXISTS", might not be appropriate for all the situations. For "SEQUENCE" it should be fine. But, for user tables, if the replay environment already has a table with that name, then its definition could be entirely different from the table used in replay query. Yes, hton->discover_table != NULL is working for "SEQUENCE" situation. But, for "SQL_SEQUENCE", it is NULL, hence I am planning to using existing condition tbl->table->s->sequence. |
It can be for any discovering engine, you never know what definition the table will have.
You didn't answer what was the problem with sequences, why do you need to have special handling for them? |
One point to consider for this feature is that, we only try to capture as much context as possible for all the base tables that were used in the "QUERY" we are interested in. We want the replay environment to be clean and only use the context that was recorded earlier. So, if the replay environment already had tables with same names, then it would definitely interfere with the replay of that query. So, we DROP those tables if they exist. For "SEQUENCE", we don't need to capture context for those tables, as they are available in the replay environment. But, it was getting captured now, which is what I want to avoid. I think "SEQUENCE" is a virtual table as in "SELECT * from seq_1_to_2", and we can't use a "CREATE STATEMENT" to create one. So, no need to capture this in the query context. The ENGINE used for "select * from seq_1_to_2" is "SEQUENCE", and the "discover_table" is defined for this one (and 3 others such as ha_archive, ha_s3, and ha_perfschema). However, The ENGINE used for "CREATE SEQUENCE s1" is either "InnoDB", or "MyISAM" depending on the default engine type specified, and such engines doesn't have "discover_table" defined. So, we can use "tbl->table->s->sequence" field that was set for these. |
ee1b2a8 to
b7f3119
Compare
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.
b7f3119 to
29f52f7
Compare
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(->
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 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.