Re: Assert failure in try_nestloop_path()

From: Tender Wang <tndrwang(at)gmail(dot)com>
To: Richard Guo <guofenglinux(at)gmail(dot)com>
Cc: Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: Assert failure in try_nestloop_path()
Date: 2026-09-04 09:30:00
Message-ID: CAHewXNmvw-tA733uT=iBNHQf2M=FAyxYz_Ko36CdXL5iPrR17g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Richard Guo <guofenglinux(at)gmail(dot)com> 于2026年9月4日周五 15:49写道:
>
> On Thu, Sep 3, 2026 at 6:39 PM Tender Wang <tndrwang(at)gmail(dot)com> wrote:
> > I also noticed that the resulting plan contains a duplicated filter:
>
> > This is not introduced by v1; I can reproduce the same duplicate qual on
> > pg16.14 as well, so it seems to be a pre-existing issue.
>
> Right, this is a pre-existing issue, and is exposed by the new test
> case.
>
> + -> Subquery Scan on t3
> + Filter: ((b.q1 = t3.cnt) AND (b.q1 = t3.cnt))
>
> I looked into it. What happens here is that outer-join identity 3
> permits the join to t3 to commute with the a/b left join, so we
> generate multiple clones of "b.q1 = t3.cnt", differing in the
> nullingrels of b.q1. Only one of them should be applied in any given
> plan. However, when movable join clauses are pushed down into a
> parameterized path, we fail to choose among the clones. In this
> example, t3's lateral reference to a PlaceHolderVar evaluated at the
> a/b join forces every path for t3 to be parameterized by a set that
> includes that outer join's relid, making both clones movable into the
> scan. The same thing can also happen for clauses moved down into a
> parameterized join.

Yes, I learned the code and got the same conclusion.

>
> I think we need to fix this. It wastes effort evaluating the same
> qual clause repeatedly. What is worse, it applies the clause's
> selectivity multiple times, underestimating the result's row count.
>

Agree

> Attached is a patch that teaches get_baserel_parampathinfo and
> get_joinrel_parampathinfo to check incompatible_relids. A clone
> should not be enforced if an outer join it is incompatible with has
> already been computed.
>
> Thoughts?

The patch looks good to me.

One minor comment about the wording:
...
A clone clause must not be enforced here if an outer join it is
incompatible with has already been computed ...
...

I found "an outer join it is incompatible with has ..." a bit difficult
to parse. Would it be clearer to add "that" here?
...
A clone clause must not be enforced here if an outer join that it is
incompatible with has already been computed ...
...

--
Thanks,
Tender Wang

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Xuneng Zhou 2026-09-04 09:38:39 Re: WAIT FOR NO_THROW option could use some documentation
Previous Message David Rowley 2026-09-04 08:55:07 Re: SUM(int2)/SUM(int4) do not detect overflow of the int8 accumulator