[subquery] Preserve COUNT semantics in scalar subquery pull-up#376
[subquery] Preserve COUNT semantics in scalar subquery pull-up#376Excaliiiibur wants to merge 1 commit into
Conversation
|
As I see, the case like this (SELECT COUNT(*)+1 FROM ...) is still incorrect. You should add the check that the type of expression here can be OpExpr in the is_plain_count_agg_expr function. Is this case is reproducible for orca? we should mention it in the commit message if it isn't and only for fallback postgres optimizer (just in case). |
…back rewrite Fix scalar-subquery pull-up in cdbsubselect for target expressions that contain COUNT aggregates. In the fallback PostgreSQL optimizer rewrite path, preserve no-match semantics with LEFT JOIN + COALESCE(agg_expr, default_expr). The default expression is derived from the original aggregate expression tree using empty-input defaults: COUNT -> 0, non-COUNT aggregates -> NULL of aggregate result type. Add regression coverage for COUNT-only and mixed COUNT+other aggregate expressions (including CASE/FuncExpr/COALESCE wrappers), and keep explicit fallback-path validation (non-ORCA-specific).
e7efea8 to
df87bf0
Compare
|
Thanks for the feedback. I’ve updated the fix to cover non-plain COUNT expressions as well, not just plain COUNT(*). This now includes cases like Implementation-wise, for COUNT-containing scalar aggregate expressions in the fallback PostgreSQL rewrite path, we preserve no-match semantics via I also added regression coverage for these cases, including fallback-path validation with Could you please take another look? |
Fixes #378
Summary
This is not an ORCA issue; it occurs in the fallback PostgreSQL optimizer rewrite path.
Fix incorrect semantics in correlated scalar aggregate subquery pull-up when target expression contains
COUNT.This risk applies not only to manual
optimizer=off, but also to other cases where planning falls back from ORCA to PostgreSQL optimizer.What Changed
In
cdbsubselect.c(convert_EXPR_to_join), for COUNT-containing scalar aggregate expressions:LEFT JOINin rewriteCOALESCE(agg_expr, default_expr)default_exprfrom empty-input aggregate defaults:COUNT(...) -> 0NULL(aggregate result type)This preserves no-match semantics for both COUNT-only and mixed COUNT+other aggregate expressions.
Tests Updated
Added/updated
subselect_gpregression cases for:count(*) + 1(count(*) + 1)::bigintcase when count(*) > 0 then count(*) + 1 else 1 endabs(count(*) - 1)count(*) + coalesce(sum(...), 0)coalesce(count(*) + sum(...), -1)Files
src/backend/cdb/cdbsubselect.csrc/test/regress/sql/subselect_gp.sqlsrc/test/regress/expected/subselect_gp.outsrc/test/regress/expected/subselect_gp_optimizer.out