Re: assertion failure with unique index + partitioning + join
Richard Guo <guofenglinux@gmail.com>
From: Richard Guo <guofenglinux@gmail.com>
To: Tender Wang <tndrwang@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@postgresql.org>, Alexander Kuzmenkov <akuzmenkov@tigerdata.com>
Date: 2026-06-16T08:27:46Z
Lists: pgsql-hackers
Attachments
- v1-0001-Strip-removed-relation-references-from-PlaceHolde.patch (application/octet-stream) patch v1-0001
On Tue, Jun 16, 2026 at 10:58 AM Tender Wang <tndrwang@gmail.com> wrote: > It was distributed to (rel:2, table t), but I think "[phrels] > Bitmapset [4 3 2]" is incorrect. After leftjoin is removed, we no > longer need rel=4 (outerjoin) and rel=3 (t r). > But the qual has already been distributed to the (rel: 2) when > deconstruct_jointree (). Then the qual is inherited by its child(table > p) > It seems that we have no logic to process this distributed > restrictinfo in remove_useless_joins(). When removing the left join, remove_rel_from_query() fixes up the relid sets of RestrictInfos and EquivalenceMembers, and the canonical PlaceHolderVars, but it does not rewrite the PlaceHolderVars embedded in clause and EC-member expressions. This is usually fine, because later processing consults those relid sets rather than the embedded PHVs. The trouble is that such an expression can later be translated for an appendrel child and have its relids recomputed by pull_varnos(). If the embedded PlaceHolderVar's phrels still mentions the removed relation, pull_varnos() folds it back in, so the rebuilt clause references a no-longer-existent rel. That produces a parameterized path keyed on the removed relation, which trips the assertion. I think we can fix it by stripping the removed relids from the PHVs in surviving rels' baserestrictinfo and in EquivalenceClass member expressions. See attached. (I went back and forth on instead making pull_varnos() robust to the stale phrels, but that turned out fragile: it can't reliably distinguish a removed relid from a not-yet-built appendrel child, and it broke unrelated partitionwise-join plans.) Thoughts? - Richard
Commits
-
Strip removed-relation references from PlaceHolderVars at join removal
- e0252679559a 18 (unreleased) landed
- 9a60f295bcb1 19 (unreleased) landed
-
Clean up remove_rel_from_query() after self-join elimination commit
- 20efbdffeb64 19 (unreleased) cited
-
Fix incorrect handling of subquery pullup
- cc5d98525d43 18.0 cited