MDEV-37020: Derived table merge optimization does not work for delete…#5055
Open
DaveGosselin-MariaDB wants to merge 1 commit into10.11from
Open
MDEV-37020: Derived table merge optimization does not work for delete…#5055DaveGosselin-MariaDB wants to merge 1 commit into10.11from
DaveGosselin-MariaDB wants to merge 1 commit into10.11from
Conversation
… and update A derived table in a multitable DELETE or UPDATE was materialized while a derived table in an equivalent query using a VIEW was merged. The cause was a blanket guard in TABLE_LIST::init_derived added by commit fe89df4. That commit fixed a ROWNUM crash on VIEWs with ORDER BY, but its derived table guard was wider than it needed to be. Narrow that guard to the case when the derived table lives inside a VIEW's body (the case when belong_to_view is set). A derived table at the top level of a multitable query will be merged, while a derived nested table within a VIEW will be materialized. Narrowing that guard exposes a separate latent bug. The access check in multi_update_check_table_access has a branch for VIEWs and another for 'not VIEWs' which dereferences table->table->map. A merged derived table that is not a VIEW fits neither condition. As is the case in main.lock_multi_bug38499, when concurrent ALTER on the target forces the prepared statement to be prepared again, table->table on the merged derived table might be NULL and this leads to a crash. Privileges for the underlying base tables are already checked by multi_update_precheck, so multi_update_check_table_access now returns early in its else branch when the input is a merged derived table.
There was a problem hiding this comment.
Code Review
This pull request enables the merging of derived tables in multi-table DELETE and UPDATE statements (MDEV-37020), aligning their optimization behavior with SELECT statements. Key changes include modifications to TABLE_LIST::init_derived to permit merging in these contexts and a new guard in multi_update_check_table_access to prevent crashes during privilege checks on merged tables that lack a direct TABLE pointer. The changes are supported by updated test results showing simplified execution plans. I have no feedback to provide as no review comments were included.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
… and update
A derived table in a multitable DELETE or UPDATE was materialized while a derived table in an equivalent query using a VIEW was merged.
The cause was a blanket guard in TABLE_LIST::init_derived added by commit fe89df4. That commit fixed a ROWNUM crash on VIEWs with ORDER BY, but its derived table guard was wider than it needed to be.
Narrow that guard to the case when the derived table lives inside a VIEW's body (the case when belong_to_view is set). A derived table at the top level of a multitable query will be merged, while a derived nested table within a VIEW will be materialized.
Narrowing that guard exposes a separate latent bug. The access check in multi_update_check_table_access has a branch for VIEWs and another for 'not VIEWs' which dereferences table->table->map. A merged derived table that is not a VIEW fits neither condition. As is the case in main.lock_multi_bug38499, when concurrent ALTER on the target forces the prepared statement to be prepared again, table->table on the merged derived table might be NULL and this leads to a crash. Privileges for the underlying base tables are already checked by multi_update_precheck, so multi_update_check_table_access now returns early in its else branch when the input is a merged derived table.