Skip to content

Unprocessed SubLink from whole-row join alias expansion - #416

Open
pg-hub-mirror[bot] wants to merge 1 commit into
masterfrom
pg-hub/mirror-patch-ad025eb7a547af0c
Open

pg-hub-mirror[bot] wants to merge 1 commit into
masterfrom
pg-hub/mirror-patch-ad025eb7a547af0c

Conversation

@pg-hub-mirror

@pg-hub-mirror pg-hub-mirror Bot commented Sep 18, 2026

Copy link
Copy Markdown

Read-only mirror. Reply and review on pgsql-hackers; activity here is not sent upstream.

  • Original author: Richard Guo <guofenglinux(at)gmail(dot)com>
  • Mailing list: pgsql-hackers
  • Message-ID: CAMbWs49PgeNFhQTZ2gSzwatF0_LXyegMPGt++jSfxUN7NZuQ5Q@mail.gmail.com
  • Original email

Patch files:


Further fuzzing with Claude on the join alias found this bug. The
following queries fail in various ways on master and all supported
branches:
create table t (a int, b int);
select 1 from ((select (select 1) as x) s cross join t) j
where (select 1 where j is null) is null;
ERROR: cannot handle unplanned sub-select
select 1 from ((select (select 1) as x) s cross join t) j
where (1, 1) in (select (j is null)::int, count(*) from t);
TRAP: failed Assert("!IsA(node, SubLink)"), File: "prepagg.c"
select 1 from ((select (select 1) as x) s cross join t) j
where exists (select 1 from t tablesample system ((j is null)::int * 100));
ERROR: unrecognized node type: 22
Once subquery s is flattened, the joinaliasvars entry for j.x is no
longer a Var but the SubLink (select 1), so expanding a reference to j
inside a sub-select inserts a SubLink into that sub-select.
But flatten_join_alias_vars_mutator fails to notice this and thus does
not set the sub-select's hasSubLinks flag. So preprocess_expression
skips SS_process_sublinks, and the SubLink survives into code that
can't cope with one.
The fix is to make the same checkExprHasSubLink() test in the
whole-row path. See attached.

  • Richard

If a subquery has been flattened into its parent, the joinaliasvars
entries of a join above it can be arbitrary expressions rather than
plain Vars, so expanding a reference to such a join alias may insert a
SubLink into a lower-level subquery.  flatten_join_alias_vars_mutator
detects that and sets the subquery's hasSubLinks flag, but only in the
single-column code path; the whole-row path just asserted in a comment
that its recursive call would handle this, which is true only when the
alias entry is itself a Var referencing another join.

Hence a whole-row reference to such a join appearing in a sub-select
left that sub-select's hasSubLinks false, so preprocess_expression
skipped SS_process_sublinks for it, and the unprocessed SubLink
reached code that is not prepared for one: this produced "cannot
handle unplanned sub-select" from cost_qual_eval, an assertion failure
in preprocess_aggrefs, or "unrecognized node type" at execution,
depending on where in the sub-select the SubLink ended up.

To fix, make the same check in the whole-row expansion path.
@pg-hub-mirror pg-hub-mirror Bot added source:pgsql-hackers Mirrored from pgsql-hackers type:patch Mail thread contains a PostgreSQL patch area:planner Planner and optimizer area:testing Tests and buildfarm area:sql SQL language or commands labels Sep 18, 2026
@pg-hub-mirror pg-hub-mirror Bot locked and limited conversation to collaborators Sep 18, 2026
@pg-hub-mirror pg-hub-mirror Bot unlocked this conversation Sep 18, 2026
@pg-hub-mirror

pg-hub-mirror Bot commented Sep 18, 2026

Copy link
Copy Markdown
Author

Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com> via pgsql-hackers · original email

Hi,
On Fri, 18 Sept 2026 at 06:22, Richard Guo <guofenglinux(at)gmail(dot)com> wrote:

Further fuzzing with Claude on the join alias found this bug. The
following queries fail in various ways on master and all supported
branches:

create table t (a int, b int);

select 1 from ((select (select 1) as x) s cross join t) j
where (select 1 where j is null) is null;
ERROR: cannot handle unplanned sub-select

select 1 from ((select (select 1) as x) s cross join t) j
where (1, 1) in (select (j is null)::int, count(*) from t);
TRAP: failed Assert("!IsA(node, SubLink)"), File: "prepagg.c"

select 1 from ((select (select 1) as x) s cross join t) j
where exists (select 1 from t tablesample system ((j is null)::int * 100));
ERROR: unrecognized node type: 22

Once subquery s is flattened, the joinaliasvars entry for j.x is no
longer a Var but the SubLink (select 1), so expanding a reference to j
inside a sub-select inserts a SubLink into that sub-select.

But flatten_join_alias_vars_mutator fails to notice this and thus does
not set the sub-select's hasSubLinks flag. So preprocess_expression
skips SS_process_sublinks, and the SubLink survives into code that
can't cope with one.

The fix is to make the same checkExprHasSubLink() test in the
whole-row path. See attached.
This looks reasonable to me. I can see how the recursive call might
look sufficient here, but once the alias entry already contains a
SubLink, there needn't be another join Var to expand and trigger the
check. Handling it like the single-column case seems a good fit.
Patch LGTM.
Regards,
Ayush

@pg-hub-mirror pg-hub-mirror Bot locked and limited conversation to collaborators Sep 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area:planner Planner and optimizer area:sql SQL language or commands area:testing Tests and buildfarm source:pgsql-hackers Mirrored from pgsql-hackers type:patch Mail thread contains a PostgreSQL patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant