Repository navigation
POC: stage DuckLake aggregate matches by row ID - #147
Merged
Merged
Conversation
ila
changed the base branch from
upgrade/duckdb-2.0-parser-ctes-20261028
to
main
November 11, 2026 20:50
ila
marked this pull request as ready for review
November 11, 2026 20:51
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.
Why
DuckDB 2.0's DuckLake aggregate
MERGEscans a large backing table even when the grouped delta is small. In the SF100 Figure 1 workload,silver.watchesspent 2,547/2,479 ms in theMERGEstatement for B2/B3 on the preceding candidate.What changes
For insert-only DuckLake grouped aggregates, stage the grouped delta with each matching target row ID, then UPDATE matched rows and INSERT new groups. The existing
MERGEremains for deletes, inline cascade maintenance, and any output column namedrowidthat hides DuckLake's virtual row ID. A standalone grouped DuckLake refresh executes the data program in one transaction so these writes commit together.The review found a watermark regression from that transaction: it checked DuckLake sources before commit and could leave the watermark behind the MV's own new snapshot. OpenIVM now verifies the sources again after commit, before advancing the watermark. A concurrent source commit at that boundary leaves the refresh marked for recovery and triggers a retry; the existing no-op and concurrency regressions pass.
Performance evidence
SF100 Figure 1 run 41999990131 passed at POC pin
7dc2067a(one run, B1/B2/B3 inserts 100/1/0.01, OpenIVM only). Against the preceding SF100 run 41901172305, B2+B3 dbt time fell from 144.98 to 133.69 seconds (7.8%). Completesilver.watchesrefresh fell from 2,965/2,882 to 690/690 ms; its staged match, UPDATE and INSERT together took 291/290 ms versus 2,547/2,479 ms for the priorMERGE. All three batches and their 50 dbt nodes completed. SF100 post-batch validation was disabled, as in the preceding run. The runs are single observations, and other model timings also changed, so the dbt difference is not solely attributable to this path.Current head
f37e1ad2adds the review fix, edge tests, and a guard requiring an explicit insert-only fact before staging row IDs in compile-only output. It also skips an unnecessary dependency lookup for split-protocol refreshes, which already require an atomic data transaction.silver.watcheshas a downstream view, so it does not enter the new standalone post-commit check. A local standalone refresh measured that additional source check at 9–19 ms; this is one small-case measurement, not an SF100 estimate.Correctness checks
test/sql/ducklake_aggregate.test: 229 assertions passed locally, including nullable two-column keys, a physicalrowidcolumn, both sides of a joined aggregate changing before one refresh, and a one-snapshot assertion for staged UPDATE/INSERT. The committed test passed using its normal install command.ducklake_deltas.test(244 assertions),ducklake_concurrent_source_commit.test(75),ducklake_chained.test(698),ducklake_left_join.test(168), andducklake_chained_recovery.test(40) passed on the review fix.EXCEPT ALLin both directions. The larger review rerun also passed full bag checks for all four views.GEN=ninja makeandgit diff --checkpassed.make format-fixpassed. The latest one-line lookup change rebuilt successfully; the watermark and concurrent-source tests passed again (244 and 75 assertions).Stacked on DuckDB 2.0 PR #146. This remains a draft until its CI checks pass.