From ec1af7ee09df16210dd2875c4abb576a462fb4fe Mon Sep 17 00:00:00 2001 From: zzylol <50204836+zzylol@users.noreply.github.com> Date: Thu, 5 Nov 2026 05:08:46 +0000 Subject: [PATCH 1/2] refactor(stage1): top-k reuse and finer-aggregate reads as one operator over groups Rules 4 (top-k reuse) and 5 (finer aggregate) add their reader copies through `add_candidate_over_groups`, so the `Limit` of a top-k read and the compensating `Filter` of a finer-aggregate read are groups. Top-k's sort and ranking producers are found or added with Stage 0's equality (`find_or_add_producer`); its exact-only input groups through `Memo::find_or_add_group`, their exact guarantee keeping them apart from the group they copy. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ --- .../src/pass2/memo/rules/finer_aggregate.rs | 4 +-- .../src/pass2/memo/rules/topk.rs | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs index 64da2407d..dbc710605 100644 --- a/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs @@ -1,7 +1,7 @@ //! Read a SQL aggregate from a finer aggregate's result //! ([`match_finer`](crate::pass2::finer_aggregate::match_finer)): filter the finer //! rows, then merge them into the query's groups with each measure's rollup. -use super::reuse::append_reader; +use super::reuse::add_candidate_over_groups; use crate::pass2::finer_aggregate::match_finer; use crate::pass2::memo::state_groups::Pass2RuleError; use asap_types::ir::operator::{AggIntent, Reduction}; @@ -167,7 +167,7 @@ fn add_read(memo: &mut Memo, owner: usize, finer: usize) -> Result Date: Thu, 5 Nov 2026 16:00:47 +0000 Subject: [PATCH 2/2] refactor(stage1): review fixes for #1220: merge an exact input group's candidates when found `exact_input_group` replaced the candidates of the group `find_or_add_group` returned, also when it found an existing group. Now the exact candidates replace the own candidate only of a group it added; a found group keeps its candidates and gets the new ones through `push_candidate_if_new`. Top-k and finer-aggregate reads follow #1218's interface changes (`MemoGroupId` owner, `find_or_add_producer` without budget parts). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ --- .../src/pass2/memo/rules/finer_aggregate.rs | 4 ++-- .../src/pass2/memo/rules/topk.rs | 20 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs index dbc710605..2712061ee 100644 --- a/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs @@ -6,7 +6,7 @@ use crate::pass2::finer_aggregate::match_finer; use crate::pass2::memo::state_groups::Pass2RuleError; use asap_types::ir::operator::{AggIntent, Reduction}; use asap_types::ir::{NonASAPOp, Operator, OperatorNode, OperatorResultKind}; -use asap_types::stages::{Memo, OriginOfCandidateForMemoGroup}; +use asap_types::stages::{Memo, MemoGroupId, OriginOfCandidateForMemoGroup}; use std::collections::HashMap; use std::rc::Rc; @@ -169,7 +169,7 @@ fn add_read(memo: &mut Memo, owner: usize, finer: usize) -> Result= groups_before { + // Added: the exact candidates replace the group's own candidate. + memo.candidates[id.0 as usize] = candidates; + } else { + // Found (another group's exact input equals it): keep its + // candidates and add the new ones. + for candidate in candidates { + memo.add_candidate(id, candidate); + } + } known.insert(group, Some(id)); Ok(Some(id)) }