Re: plan shape work - Mailing list pgsql-hackers

From Robert Haas
Subject Re: plan shape work
Date
Msg-id CA+TgmobqKq4n5UophvdWhrxOxCa7ZvWJt+LNc9pc1Jq+5ZArqg@mail.gmail.com
Whole thread Raw
In response to Re: plan shape work  (Richard Guo <guofenglinux@gmail.com>)
List pgsql-hackers
On Wed, Sep 10, 2025 at 3:16 AM Richard Guo <guofenglinux@gmail.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



pgsql-hackers by date:

Previous
From: Ilia Evdokimov
Date:
Subject: Re: Use merge-based matching for MCVs in eqjoinsel
Next
From: Aleksander Alekseev
Date:
Subject: Re: Proposal: Creating multiple indexes on a table using a single full table scan