Skip to content

MDEV-37020: Derived table merge optimization does not work for delete…#5055

Open
DaveGosselin-MariaDB wants to merge 1 commit into10.11from
10.11-MDEV-37020-dt-merge
Open

MDEV-37020: Derived table merge optimization does not work for delete…#5055
DaveGosselin-MariaDB wants to merge 1 commit into10.11from
10.11-MDEV-37020-dt-merge

Conversation

@DaveGosselin-MariaDB
Copy link
Copy Markdown
Member

… 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.

… 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.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

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.

@DaveGosselin-MariaDB DaveGosselin-MariaDB requested review from spetrunia and removed request for spetrunia May 8, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

1 participant