Skip to content

MDEV-40821 Wrong result after PORTION OF with subquery (11.4) - #5930

Open
midenok wants to merge 2 commits into
11.4from
11.4-midenok-MDEV-40821
Open

midenok wants to merge 2 commits into
11.4from
11.4-midenok-MDEV-40821

Conversation

@midenok

@midenok midenok commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

This is 11.4 part of the fix, on top of 10.11 which is pushed by #5881.
The merge of 10.11 branch after #5881 pushed can be resolved by 10.11 commit from this PR.

Single-table DELETE converted to multi-table (when a subquery
references the target table) skipped FOR PORTION OF row splitting and
the constant expression check, so it deleted whole rows instead of the
portion.

The fix prohibits processing DELETE ... FOR PORTION OF as multi-table,
like DELETE ... RETURNING.

Copilot AI balanced review requested due to automatic review settings October 20, 2026 11:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

The parser assigned versioning conditions of DELETE HISTORY ... BEFORE
SYSTEM_TIME and period conditions of DELETE ... FOR PORTION OF to the
table pointed by last_table(). When the BEFORE SYSTEM_TIME or FOR
PORTION OF expression references another table (e.g. via a subquery or
a sequence function), last_table() is already switched to that table,
and the DELETE target gets no conditions.

DELETE HISTORY then deletes current rows permanently instead of
history, keeps the history it had to purge, and is checked for DELETE
privilege instead of DELETE HISTORY. DELETE HISTORY from a
non-versioned table is not rejected with ER_VERS_NOT_VERSIONED.
DELETE ... FOR PORTION OF deletes all rows of the table, ignoring the
period.

The fix assigns the conditions to the TABLE_LIST returned by
delete_single_table, i.e. the DELETE target itself, regardless of
tables added later in the statement.

DBUG_ASSERT in TABLE::vers_switch_partition() is removed. It checked
delete_history on last_table() and assumed no other table is opened
for write by DELETE HISTORY, which is false for the underlying table
of a view or a table locked by SELECT ... FOR UPDATE in the history
point. The DELETE HISTORY target is already skipped there by its own
delete_history check.
Single-table DELETE converted to multi-table (when a subquery
references the target table) skipped FOR PORTION OF row splitting and
the constant expression check, so it deleted whole rows instead of the
portion.

The fix prohibits processing DELETE ... FOR PORTION OF as multi-table,
like DELETE ... RETURNING.
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.

3 participants