Re: Tracking per-RelOptInfo uniqueness during planning

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Antonin Houska <ah(at)cybertec(dot)at>
Cc: Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Andy Fan <zhihuifan1213(at)163(dot)com>, David Rowley <dgrowleyml(at)gmail(dot)com>
Subject: Re: Tracking per-RelOptInfo uniqueness during planning
Date: 2026-08-18 01:14:58
Message-ID: CAMbWs4-m3PfL6j+UuTiL567+d9qM1y3uGwZ7g_wQqYNt2jWFCw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, Aug 14, 2026 at 9:17 AM Richard Guo <guofenglinux(at)gmail(dot)com> wrote:
> Yeah, that's still in my to-do list, which also includes support for
> appendrels, partitionwise child joins, UNION ALL parents, RTE_VALUES,
> or RTE_RESULT, etc.

Here is v3 of this patchset.

0001 is the same as v2, except that it also restores NULL-awareness to
a key that lost it at semijoins, in addition to inner joins.

0002 teaches UniqueKeys about appendrel children and child joins. For
now it simply has the child relations, and the child join relations
built for a partitionwise join, inherit their parent's keys. This
works because a child relation emits a subset of its parent's rows,
and a subset of a distinct set is distinct.

In theory, we can inspect the child relation's unique indexes and
build UniqueKeys of its own. A partition can have a unique index that
its parent cannot. Such keys hold for the child alone and must not
reach the parent. I have left that out. Deducing those keys afresh
means running the join deduction once per child join, which spends
planning time on every child join to reproduce the parent's answer in
nearly every case.

0003 teaches UniqueKeys about the grouped relations that eager
aggregation builds. Partial aggregation keeps one row per group, so a
grouped relation is distinct over its grouping expressions. Unlike
the query's own grouping step, this one has joins above it, so the key
can prove such a join inner-unique.

A nice suprise is that this fits eager aggregation quite well. Eager
aggregation is already obliged to group by every column an upper join
needs, so the key we deduce always contains the ECs of the clauses of
the joins above it. So whenever the grouped relation contributes
nothing further, we can always get an inner-unique join.

Please ignore the costsize.c changes in 0003. That's a fix to a known
right-semi/right-anti hash join costing issue. See [1].

[1] https://postgr.es/m/CAMbWs49XwhSC=e8_yeEaGKmKNyWR3DHH0p+e4k-bR_pgRiN8nQ@mail.gmail.com

- Richard

Attachment Content-Type Size
v3-0001-Introduce-UniqueKeys-to-track-the-distinctness-of.patch application/octet-stream 125.7 KB
v3-0002-Teach-UniqueKeys-about-appendrel-children-and-chi.patch application/octet-stream 12.4 KB
v3-0003-Teach-UniqueKeys-about-eager-aggregation-s-groupe.patch application/octet-stream 37.5 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Zhijie Hou (Fujitsu) 2026-08-18 03:27:43 RE: Logical replication row filter loses unchanged toasted columns
Previous Message Tender Wang 2026-08-18 00:54:00 Unsafe qual pushdown through DISTINCT with simple CASE expressions