Skip to content

fix: Handle wrapped aggregates in aggregate pushdown#3804

Merged
mithuncy merged 4 commits intomainfrom
fix/3757-wrapped-aggregates
Jan 6, 2026
Merged

fix: Handle wrapped aggregates in aggregate pushdown#3804
mithuncy merged 4 commits intomainfrom
fix/3757-wrapped-aggregates

Conversation

@mithuncy
Copy link
Copy Markdown
Contributor

Summary

Fixes #3757 - Aggregates wrapped in functions like jsonb_pretty(pdb.agg(...)) were not recognized for pushdown.

  • Add find_single_aggref_in_expr() using expression_tree_walker to find nested Aggref nodes
  • Update replace_aggrefs_in_target_list() to use expression_tree_mutator for wrapped Aggrefs
  • Follows same pattern as window function handling in window_agg.rs

Test plan

  • Added non-window wrapped aggregate tests to fn_wrapped_agg.sql (Tests 5-10)
  • Verified issue test cases: jsonb_pretty(pdb.agg(...)), pdb.agg(...)->'values'
  • Passes cargo fmt, cargo clippy, cargo check

@mithuncy mithuncy self-assigned this Dec 18, 2025
@mithuncy mithuncy added the Do Not Cherry Pick PR should not be cherry-picked to other branches label Dec 18, 2025
@mithuncy mithuncy force-pushed the fix/3757-wrapped-aggregates branch from 2feb2c8 to e07610d Compare December 18, 2025 23:22
Aggregates wrapped in functions like COALESCE(COUNT(*), 0) were not
being recognized for pushdown to Tantivy. The code only checked if
the top-level expression was an Aggref.

Changes:
- Add find_single_aggref_in_expr() to walk expression trees and find
  nested Aggref nodes using PostgreSQL's expression_tree_walker
- Update replace_aggrefs_in_target_list() to use expression_tree_mutator
  so wrapped Aggrefs are properly replaced with placeholder FuncExprs
- Only returns an Aggref if exactly one is found (multiple aggregates
  in a single expression are not supported)
@mithuncy mithuncy force-pushed the fix/3757-wrapped-aggregates branch from e07610d to b7f6044 Compare December 19, 2025 08:34
Comment thread pg_search/tests/pg_regress/expected/fn_wrapped_agg.out
- Use Const nodes with per-row projection (pdbscan pattern) to evaluate wrapped expressions
- Reuse tuple slot in state to fix per-row memory leak
- Switch to per-tuple memory context for ExecBuildProjectionInfo to prevent allocation leak
- Add debug_asserts for contiguous non-resjunk targetlist assumption
@mithuncy mithuncy requested a review from stuhood December 31, 2025 15:28
Copy link
Copy Markdown
Collaborator

@stuhood stuhood left a comment

Choose a reason for hiding this comment

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

Thanks a lot!

Comment thread pg_search/src/postgres/customscan/aggregatescan/mod.rs Outdated
Comment thread pg_search/src/postgres/customscan/aggregatescan/scan_state.rs Outdated
Comment thread pg_search/src/postgres/customscan/aggregatescan/mod.rs Outdated
Comment thread pg_search/src/postgres/customscan/aggregatescan/mod.rs Outdated
Comment thread pg_search/src/postgres/customscan/aggregatescan/mod.rs Outdated
Comment thread pg_search/src/postgres/customscan/aggregatescan/mod.rs Outdated
Move generic projection code to shared customscan/projections.rs.
Apply review feedback: Vec over HashMap, early-continue, .any(), iter_ptr().
Copy link
Copy Markdown
Collaborator

@stuhood stuhood left a comment

Choose a reason for hiding this comment

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

Thanks!

@mithuncy mithuncy merged commit 6dcf669 into main Jan 6, 2026
19 checks passed
@mithuncy mithuncy deleted the fix/3757-wrapped-aggregates branch January 6, 2026 19:10
vrn21 pushed a commit to vrn21/paradedb that referenced this pull request Jan 7, 2026
## Summary
Fixes paradedb#3757 - Aggregates wrapped in functions like
`jsonb_pretty(pdb.agg(...))` were not recognized for pushdown.

- Add `find_single_aggref_in_expr()` using `expression_tree_walker` to
find nested Aggref nodes
- Update `replace_aggrefs_in_target_list()` to use
`expression_tree_mutator` for wrapped Aggrefs
- Follows same pattern as window function handling in `window_agg.rs`

## Test plan
- Added non-window wrapped aggregate tests to `fn_wrapped_agg.sql`
(Tests 5-10)
- Verified issue test cases: `jsonb_pretty(pdb.agg(...))`,
`pdb.agg(...)->'values'`
- Passes `cargo fmt`, `cargo clippy`, `cargo check`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Cherry Pick PR should not be cherry-picked to other branches

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pdb.agg() in agg position can't be wrapped in a function call

2 participants