Re: Enable partitionwise join for partition keys wrapped by RelabelType

From: "Matheus Alcantara" <matheusssilv97(at)gmail(dot)com>
To: "Jan Nidzwetzki" <jan(at)planetscale(dot)com>, "jian he" <jian(dot)universality(at)gmail(dot)com>
Cc: <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Enable partitionwise join for partition keys wrapped by RelabelType
Date: 2026-08-24 17:04:08
Message-ID: DKXC52ZN2FZK.1OZZVBFVYPRZU@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu Aug 20, 2026 at 10:31 AM -03, Jan Nidzwetzki wrote:
> Hello Hackers,
>
> Thanks for the patch, this is a nice planner improvement. The v3 version
> applies to the current master branch and check-world passes. I could
> also confirm that the provided test case demonstrates the intended
> change of the query plan.
>

Hi Jan,

Thanks a lot for the review and for sharing the regression.

> On 27.01.26 16:42, Matheus Alcantara wrote:
>> I think that unwrapping all Relabel types may ignore intermediate
>> states. For example, consider Relabel A -> Relabel B -> Base expression:
>> This code will unwrap Relabel A and Relabel B and check the expression
>> collation directly on Base expression, shouldn't we check every layer,
>> e.g Relabel A, Relabel B and Base Expression? Please see the attached v3
>> version with a simplified version of v2 that also check every layer of a
>> RelabelType node.
>
> Checking every layer seems reasonable to me. Independently of that, I
> believe I've identified a regression caused by the patch: in
> exprs_known_equal(), RelabelType is stripped from 'expr' but not from
> item1 and item2. A few lines later, 'equal(item1, expr)' and
> 'equal(item2, expr)' are performed. If item1 or item2 is a RelabelType,
> these comparisons now return false.
>
> This can happen when the code is called from have_partkey_equi_join() on
> a partitioned table. item1/item2 come from rel->partexprs, and for an
> expression partition key like '((c)::text)' on a varchar column, the
> stored partition expression is itself a RelabelType node.
>
> I could reproduce the issue as follows. On master, the query plan below
> is a partition-wise nested loop; after applying this patch, the plan no
> longer contains a partition-wise join:
>
> [ ... ]
>
> I think the RelabelType nodes also need to be stripped from item1/item2
> before the comparison. find_ec_member_matching_expr() performs something
> similar and the RelabelType is stripped for both arguments of the
> equal() call.
>
> Best regards
> Jan

You're right, exprs_known_equal() was stripping the RelabelType only
from the EC member's expression, but not from item1/item2. item1/item2
in the have_partkey_equi_join() path come directly from rel->partexprs,
which for an expression partition key like ((c::text)) on a varchar
column are themselves RelabelType-wrapped, so the raw equal() check
happened to succeed by accident (both sides kept the wrapper). Once
em_expr got stripped and item1/item2 didn't, that symmetry broke, and I
could reproduce the regression you reported. Thanks.

The attached v4 patch strips RelabelType from item1 and item2 as well,
so both sides of the equal() check are treated consistently.

While debbuging this down I found a second, related issue: partition
pruning has the same asymmetry. match_clause_to_partition_key() in
partprune.c strips RelabelType from the clause's operands but never from
the partition key expression itself, so for the same class of
RelabelType-wrapped expression keys, pruning silently fails to eliminate
any partitions at all. That's actually what was behind an odd behavior
I ran into while testing your case with data loaded: without
pruning, all partitions stay in the Append, and at small/empty-table row
counts the planner's cost estimate for the partitionwise nested loop and
the non-partitionwise one are close enough that either can be chosen,
which made it look like the join fix wasn't reliable. With pruning fixed
too, pb1.c::text = '0002' now correctly prunes to a single partition on
each side regardless of scale, so the ambiguity goes away entirely. v4
includes that fix as well.

--
Matheus Alcantara
EDB: https://www.enterprisedb.com

Attachment Content-Type Size
v4-0001-Enable-partitionwise-join-for-partition-keys-wrap.patch text/plain 16.2 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Sami Imseih 2026-08-24 17:07:06 Re: postgres_fdw: Fix flaky push down FUNCTION RTE test
Previous Message Greg Burd 2026-08-24 16:58:47 Add a Nix flake