Re: BUG #18187: Unexpected error: "variable not found in subplan target lists" triggered by JOIN

Richard Guo <guofenglinux@gmail.com>

From: Richard Guo <guofenglinux@gmail.com>
To: Andrei Lepikhov <a.lepikhov@postgrespro.ru>
Cc: zuming.jiang@inf.ethz.ch, pgsql-bugs@lists.postgresql.org, PG Bug reporting form <noreply@postgresql.org>
Date: 2023-11-09T03:54:08Z
Lists: pgsql-bugs

Attachments

On Wed, Nov 8, 2023 at 11:42 PM Andrei Lepikhov <a.lepikhov@postgrespro.ru>
wrote:

> The issue looks like previous one, related to new SJE feature.
>
> Reduced case:
> CREATE TABLE t2 (vkey int4, c9 text, primary key(vkey));
> SELECT * FROM (
>    SELECT CASE WHEN '1' = ref_0.c9 THEN 1 ELSE 1 END AS c_3
> FROM t2 as ref_0
>    JOIN t2 AS ref_1
>    ON ref_0.vkey = ref_1.vkey
>      RIGHT OUTER JOIN t2 AS ref_2
>      ON ref_1.vkey = ref_2.vkey) AS t5
>    RIGHT OUTER JOIN (SELECT 1 AS c_2) AS t4
>    ON t4.c_2 IS NOT NULL;
>
> The key problem lies in the 'CASE' statement.


I've looked into this a little bit.  I think it's caused by the SJE
logic not properly removing references from PHVs.  Specifically, it
fails to replace the ref_0's Vars within phv->phexpr, leading them to be
added in ref_2/ref_1 join's targetlist.

Also, I noticed that in remove_rel_from_query() we perform replace_relid
for phv->phrels twice at line 475 and 478, which seems not right to me.

 475   phv->phrels = replace_relid(phv->phrels, relid, subst);
 476   phv->phrels = replace_relid(phv->phrels, ojrelid, subst);
 477   phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst);
 478   phinfo->ph_var->phrels = replace_relid(phinfo->ph_var->phrels,
relid, subst);

Attached is a hotfix.

Thanks
Richard

Commits

  1. Fix a comment for remove_self_joins_recurse()

  2. Don't constrain self-join removal due to PHVs

  3. Handle PlaceHolderVar case in replace_varno_walker

  4. Fix how SJE checks against PHVs

  5. citext: Allow tests to pass in OpenSSL FIPS mode