Re: plan shape work

From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Richard Guo <guofenglinux(at)gmail(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Alexandra Wang <alexandra(dot)wang(dot)oss(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, "bruce(at)momjian(dot)us" <bruce(at)momjian(dot)us>, lepihov(at)gmail(dot)com
Subject: Re: plan shape work
Date: 2025-09-10 14:11:54
Message-ID: CA+TgmobqKq4n5UophvdWhrxOxCa7ZvWJt+LNc9pc1Jq+5ZArqg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, Sep 10, 2025 at 3:16 AM Richard Guo <guofenglinux(at)gmail(dot)com> wrote:
> Hmm, this isn't quite what I had in mind. What I was thinking is that
> the outer join relids included in joinrel->relids can also be found
> from its outer or inner. For example, consider a query like:
>
> (A leftjoin B on (Pab)) leftjoin C on (Pbc)
>
> For the join with joinrel->relids being {1, 2, 3, 4, 5}, {1, 2, 3}
> comes from the outer side, {4} comes from the inner side, and {5} is
> the outer join being calculated at this join. So the Assert I
> proposed earlier becomes:
>
> {1, 2, 3} U {4} U {5} == {1, 2, 3, 4, 5}

Makes sense.

> However, if we have transformed it to:
>
> A leftjoin (B leftjoin C on (Pbc)) on (Pab)
>
> For this same join, {1} comes from the outer side, {2, 4} comes from
> the inner side, and {3, 5} are the outer joins being calculated at
> this join. So the Assert becomes:
>
> {1} U {2, 4} U {3, 5} == {1, 2, 3, 4, 5}

Hmm. As I understood it, Tom was proposing a single, optional ojrelid
for each join, with all outer joins having a value and no inner join
having one. What you are proposing seems to be a very similar concept,
but as I understand it, you're saying that each join would carry a
*set* of ojrelids, which might be empty and might contain more than
one element.

Experimenting with this example, it looks like you're correct and Tom,
or my understanding of Tom, is incorrect. What I see is that I get a
structure like this:

{MERGEPATH
:parent_relids (b 1 2 3 4 5)
:jpath.outerjoinpath
{PATH
:parent_relids (b 1)
:jpath.innerjoinpath
{MERGEPATH
:parent_relids (b 2 4)
:jpath.outerjoinpath
{PATH
:parent_relids (b 2)
}
:jpath.innerjoinpath
{PATH
:parent_relids (b 4)
}
}
}

So, for the assertion to pass, the more deeply nested merge join would
need to have ojrelids = {} and the less-deeply nested one would need
ojrelids={3,5}.

--
Robert Haas
EDB: http://www.enterprisedb.com

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Aleksander Alekseev 2025-09-10 14:12:44 Re: Proposal: Creating multiple indexes on a table using a single full table scan
Previous Message Ilia Evdokimov 2025-09-10 13:56:03 Re: Use merge-based matching for MCVs in eqjoinsel