Skip to content

adapter: Skip the intersection of DELETE ... ROWS when containment is proven - #40053

Draft
antiguru wants to merge 6 commits into
delete-rowsfrom
delete-rows-containment
Draft

antiguru wants to merge 6 commits into
delete-rowsfrom
delete-rows-containment

Conversation

@antiguru

@antiguru antiguru commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Based on #40052.

DELETE FROM t ROWS (q) writes Negate(q) instead of Negate(t INTERSECT ALL q) when it can prove that q is a sub-multiset of t. The selection then reads only q, for example a small materialized view of rows due for cleanup, instead of scanning and arranging all of t.

A new SubMultiset MIR analysis in mz-transform does the proof. The adapter feeds it facts from the catalog: views by their definition, and materialized views only without a refresh schedule or replacement history. Unknown shapes fall back to the intersection. The OCC write at T lands only if the table is unchanged since T-1, so the proof holds at write time. The counter mz_delete_rows_selection_total records which path ran.

🤖 Generated with Claude Code

@antiguru
antiguru added this pull request to stack #40054 October 21, 2026 08:23
@antiguru antiguru changed the title delete rows containment adapter: Skip the intersection of DELETE ... ROWS when containment is proven Oct 21, 2026
antiguru and others added 6 commits October 21, 2026 11:26
… proven

`DELETE FROM t ROWS (q)` retracts `t INTERSECT ALL q`, which reads and
arranges all of `t`. When `q` is provably a sub-multiset of `t` at every
timestamp, the intersection equals `q`, so the write can retract `q`
directly and read only the collections `q` reads, for example a small
materialized view of garbage rows.

A new `SubMultiset` analysis in `mz-transform` proves containment
conservatively over filters, identity projections, `EXCEPT ALL` and
`INTERSECT ALL` shapes, and `Let` bindings. The adapter seeds it from the
catalog: views and materialized views without a refresh schedule or
replacement history count when their definitions are proven contained in
the target table version. Anything else keeps the intersection.
`mz_delete_rows_selection_total` counts which selection ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Local optimization pushes `Negate` below `Map` and `Project`, so the
subtracted input of a planned `EXCEPT ALL` need not be a `Negate`. The
intersection rule also proves `A INTERSECT ALL B` from `A` alone for any
subtracted input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antiguru
antiguru force-pushed the delete-rows-containment branch from d6325a2 to 373bb46 Compare October 21, 2026 09:34

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant