Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions mysql-test/main/alter_table_combinations.result
Original file line number Diff line number Diff line change
Expand Up @@ -321,4 +321,13 @@ drop table t1;
#
# End of 10.5 tests
#
#
# MDEV-31808 Server crash upon altering table with NEXTVAL for default under exclusive lock
#
CREATE SEQUENCE s ENGINE=Aria;
CREATE TABLE t (a INT DEFAULT(NEXTVAL(s)), b INT);
ALTER TABLE t FORCE, ALGORITHM=COPY, LOCK=EXCLUSIVE;
DROP TABLE t;
DROP SEQUENCE s;
# End of 10.6 tests
set @@default_storage_engine= @save_default_engine;
14 changes: 14 additions & 0 deletions mysql-test/main/alter_table_combinations.test
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,18 @@ drop table t1;
--echo # End of 10.5 tests
--echo #

--echo #
--echo # MDEV-31808 Server crash upon altering table with NEXTVAL for default under exclusive lock
--echo #

CREATE SEQUENCE s ENGINE=Aria;
CREATE TABLE t (a INT DEFAULT(NEXTVAL(s)), b INT);
ALTER TABLE t FORCE, ALGORITHM=COPY, LOCK=EXCLUSIVE;

# Cleanup
DROP TABLE t;
DROP SEQUENCE s;

--echo # End of 10.6 tests

set @@default_storage_engine= @save_default_engine;
6 changes: 5 additions & 1 deletion sql/sql_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2085,7 +2085,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
goto retry_share;
}

if (thd->open_tables && thd->open_tables->s->tdc->flushed)
if (!table_list->sequence && thd->open_tables && thd->open_tables->s->tdc->flushed)
{
/*
If the version changes while we're opening the tables,
Expand Down Expand Up @@ -5006,6 +5006,10 @@ bool open_and_lock_internal_tables(TABLE *table, bool lock_table)
MYSQL_LOCK_USE_MALLOC))
goto err;

/* no existing lock to merge with */
if (save_lock == nullptr)
DBUG_RETURN(0);

if (!(new_lock= mysql_lock_merge(save_lock, thd->lock)))
Comment on lines +5009 to 5013
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of returning early with DBUG_RETURN(0) when save_lock is nullptr, we can conditionally merge the locks using a ternary operator. Returning early from open_and_lock_internal_tables is risky because it bypasses any potential cleanup, monitoring, or other logic that might exist or be added to the end of the function.

By using a ternary operator, we can safely handle the case where there is no existing lock to merge, while allowing the function to proceed to its natural exit point.

    /* Merge with the existing lock if there is one, otherwise keep the new lock. */
    new_lock= save_lock ? mysql_lock_merge(save_lock, thd->lock) : thd->lock;
    if (!new_lock)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no cleanup required, and an assignment of thd->lock back to itself a bit of an odd logic flow.

{
thd->lock= save_lock;
Expand Down