On Mon, Aug 31, 2026 at 10:55 AM Tender Wang <[email protected]> wrote:
> regression=# explain SELECT
> FROM public.rtest_vview4 AS ref_0
>      LEFT JOIN (fkpart5.pk AS sample_0
>                 LEFT JOIN pg_catalog.pg_stat_user_functions AS ref_1 ON NULL)
>         ON NULL
>      INNER JOIN public.skip_wal_skip_rewrite_index AS sample_5 ON
> sample_0.a IS NULL,
>      LATERAL (SELECT
>               WHERE ref_1.schemaname IS NULL) AS subq_1;
> server closed the connection unexpectedly

Interesting.  What's happening is that "sample_0.a IS NULL" causes the
upper left join to be reduced to an antijoin.  "n.nspname IS NULL"
then becomes redundant and is discarded by check_redundant_nullability_qual,
so its Var is not counted in attr_needed; but the qual itself still
exists in the jointree.  Join removal thus sees no reference to n and
removes the p/n join, and then ChangeVarNodes finds n.nspname still
sitting in the tree and hits the Assert.

According to that, I can reproduce this same issue with the query
below:

create table t (a int primary key);

select 1 from t t1 left join
  (t t2 left join t t3 on t3.a = t2.a) on true
where t2.a is null and t3.a is null;

I think the real problem is that we leave a qual in the tree after
deciding that it is redundant.  So the attached patch removes such
quals from the jointree at the end of reduce_outer_joins.

With the quals removed before deconstruct_jointree,
check_redundant_nullability_qual has nothing left to do, so I think we
can get rid of it in passing.

- Richard

Attachment: v1-0001-Remove-quals-made-redundant-by-reducing-outer-joi.patch
Description: Binary data

Reply via email to