Skip to content

ORCA: keep HAVING above a scalar GbAgg in CNormalizer::FPushable#1693

Open
yjhjstz wants to merge 1 commit intoapache:mainfrom
yjhjstz:orca-having-false-scalar-gbagg
Open

ORCA: keep HAVING above a scalar GbAgg in CNormalizer::FPushable#1693
yjhjstz wants to merge 1 commit intoapache:mainfrom
yjhjstz:orca-having-false-scalar-gbagg

Conversation

@yjhjstz
Copy link
Copy Markdown
Member

@yjhjstz yjhjstz commented Apr 22, 2026

A scalar (plain) aggregate with no grouping columns always emits exactly one row regardless of input cardinality. Predicates above it (from a HAVING clause) filter that output row, so they cannot be moved onto the aggregate's input without changing semantics:

SELECT count() FROM t HAVING false -- 0 rows
SELECT count(
) FROM t WHERE false -- 1 row (count=0)

CNormalizer::FPushable previously only blocked pushing volatile predicates below a GbAgg. Any other predicate -- including a constant false -- was considered pushable because its used-column set was trivially contained in the aggregate's output columns. The normalizer then routed the Select's predicate through the GbAgg and down into its logical child, dropping HAVING semantics for scalar aggregates.

Fixes #ISSUE_Number

What does this PR do?

Type of Change

  • Bug fix (non-breaking change)
  • New feature (non-breaking change)
  • Breaking change (fix or feature with breaking changes)
  • Documentation update

Breaking Changes

Test Plan

  • Unit tests added/updated
  • Integration tests added/updated
  • Passed make installcheck
  • Passed make -C src/test installcheck-cbdb-parallel

Impact

Performance:

User-facing changes:

Dependencies:

Checklist

Additional Context

CI Skip Instructions


A scalar (plain) aggregate with no grouping columns always emits
exactly one row regardless of input cardinality. Predicates above it
(from a HAVING clause) filter that output row, so they cannot be
moved onto the aggregate's input without changing semantics:

  SELECT count(*) FROM t HAVING false      -- 0 rows
  SELECT count(*) FROM t WHERE  false      -- 1 row (count=0)

CNormalizer::FPushable previously only blocked pushing volatile
predicates below a GbAgg. Any other predicate -- including a constant
false -- was considered pushable because its used-column set was
trivially contained in the aggregate's output columns. The normalizer
then routed the Select's predicate through the GbAgg and down into
its logical child, dropping HAVING semantics for scalar aggregates.
Copy link
Copy Markdown
Contributor

@my-ship-it my-ship-it left a comment

Choose a reason for hiding this comment

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

LGTM, thanks

@yjhjstz yjhjstz requested review from reshke April 24, 2026 22:57
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.

2 participants