Skip to content

[ORCA] Narrow CTE Producer columns in CXformGbAggWithMDQA2Join - #1914

Open
yjhjstz wants to merge 1 commit into
apache:mainfrom
yjhjstz:orca-mdqa-narrow-cte-producer-columns
Open

[ORCA] Narrow CTE Producer columns in CXformGbAggWithMDQA2Join#1914
yjhjstz wants to merge 1 commit into
apache:mainfrom
yjhjstz:orca-mdqa-narrow-cte-producer-columns

Conversation

@yjhjstz

@yjhjstz yjhjstz commented Aug 20, 2026

Copy link
Copy Markdown
Member
SET optimizer = on;
SET optimizer_enable_multiple_distinct_aggs = on;

EXPLAIN SELECT a, count(DISTINCT b) AS cnt_b, count(DISTINCT c) AS cnt_c
FROM mdqa_part WHERE b BETWEEN 0 AND 2 GROUP BY a;

Note: optimizer_enable_multiple_distinct_aggs is off by default; without it ORCA falls back before reaching the buggy code path.

Error and stack trace (cassert build)

CPhysicalCTEProducer.cpp:117: Failed assertion: col_ref->GetUsage() != CColRef::EUnknown
Stack trace:
1    gpos::CException::Raise + 278
2    gpopt::CPhysicalCTEProducer::PcrsRequired + 380
3    gpopt::CReqdPropPlan::ComputeReqdCols + 223
4    gpopt::CReqdPropPlan::Compute + 153
5    gpopt::CExpressionHandle::ComputeChildReqdProps + 515
6    gpopt::CJobGroupExpressionOptimization::ComputeCurrentChildRequirements + 423
7    gpopt::CJobGroupExpressionOptimization::ScheduleChildGroupsJobs + 236
8    gpopt::CJobGroupExpressionOptimization::EevtOptimizeChildren + 115
9    gpopt::CJobStateMachine + 376
10   gpopt::CJobGroupExpressionOptimization::FExecute + 123
11   gpopt::CScheduler::FExecute + 77
12   gpopt::CScheduler::ExecuteJobs + 121
13   gpopt::CScheduler::Run + 46
14   gpopt::CEngine::Optimize + 919
15   gpopt::COptimizer::PexprOptimize + 115
16   gpopt::COptimizer::PdxlnOptimize + 1416
17   COptTasks::OptimizeTask + 1651
18   gpos::CTask::Execute + 202
19   gpos::CWorker::Execute + 197
20   gpos::CAutoTaskProxy::Execute + 227
21   gpos_exec + 933

LOG:  GPORCA failed to produce plan (unexpected)

On release builds the assertion is compiled out and the same over-declared column list crashes later with SIGSEGV in MakeDXLTableDescr during DXL translation.

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


@yjhjstz
yjhjstz requested a review from jiaqizho August 20, 2026 16:41
When rewriting a GbAgg with multiple distinct-qualified aggregates
(MDQAs) into a join of single-DQA aggregates, the transform declared
every column the child expression could produce on the CTE Producer.
On the partitioned-table path the over-declared columns included
unreferenced and system columns whose usage state is EUnknown/EUnused,
which fails the assertion "col_ref->GetUsage() != CColRef::EUnknown"
in CPhysicalCTEProducer::PcrsRequired on assert builds and crashes
with SIGSEGV in MakeDXLTableDescr on release builds:

    CREATE TABLE mdqa_part(a int, b int, c int, d int)
    DISTRIBUTED BY (a)
    PARTITION BY RANGE(a) (START (0) END (100) EVERY (50),
                           DEFAULT PARTITION other);
    SET optimizer_enable_multiple_distinct_aggs = on;
    SELECT a, count(DISTINCT b), count(DISTINCT c)
      FROM mdqa_part WHERE b BETWEEN 0 AND 2 GROUP BY a;

Fix by restricting the CTE Producer/Consumer columns to the columns
the GbAgg actually needs: group-by keys plus aggregate-argument
references, clipped to what the child can produce. Besides fixing the
crash, this also simplifies MDQA plans on non-partitioned tables: the
narrowed producer no longer carries unused and system columns, and
ORCA can now place a single Redistribute Motion below the producer
instead of one per consumer.

Ported from warehouse-pg/warehouse-pg#149, minidump changes omitted.
@yjhjstz
yjhjstz force-pushed the orca-mdqa-narrow-cte-producer-columns branch from 1c8141c to 6893bf9 Compare August 20, 2026 17:41
yjhjstz added a commit to quantumiodb/pgorca that referenced this pull request Aug 20, 2026
Port of apache/cloudberry#1914 (code only; the upstream regression-test
output is MPP-specific).

PexprMDQAs2Join built the CTE producer over the child's *entire* derived
output column set. For a Get the child output is every column of the
table descriptor -- including the system columns -- so a query grouping
on one column and taking two DISTINCT aggregates over two others
declared a 9-column producer where 3 columns suffice.

Restrict the producer to the columns the GbAgg actually reads: the
group-by keys plus everything referenced from the aggregate list,
intersected with what the child can produce.

Upstream this is a crash fix: Cloudberry's CPhysicalCTEProducer::
PcrsRequired asserts every declared column has a known CColRef usage,
and the over-declared system columns are EUnknown; release builds
instead segfault later in MakeDXLTableDescr. Neither path exists here --
our CPhysicalCTEProducer has no usage assertion and the DXL table
descriptor is built differently -- so for pg_orca this only stops the
producer from materializing columns nobody consumes. Taking it anyway
keeps the xform aligned with upstream.

Verified: the PR's repro shape (GROUP BY a with count(DISTINCT b) and
count(DISTINCT c)) now hands PexprAddCTEProducer 3 columns instead of 9.
test.sh --orca-tests 19/19 pass, olap_mdqa included. The 6 failures
under --pg-tests --ignore-plans (subselect, aggregates, join_hash,
select_parallel, window, stats) produce a byte-identical
regression.diffs on the pre-change tree. cost_align.sh is unchanged
(total=311, same-plan <=2%=192, off=4, diff plan=115); its 4 off rows
are correlated-subquery/NOT EXISTS/NOT IN items and cost_align.sql has
no multiple-DQA query, so Exfp never fires there.
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