Thread
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
-
assertion failure with unique index + partitioning + join
Alexander Kuzmenkov <akuzmenkov@tigerdata.com> — 2026-06-15T15:39:01Z
Hi hackers, While I was running some random testing on the TimescaleDB extension, I noticed that I can easily hit an assertion failure in plain Postgres REL_18_STABLE. I haven't analyzed it at all, but thought I should report this: CREATE TABLE t (a bool UNIQUE) PARTITION BY LIST (a); CREATE TABLE p PARTITION OF t DEFAULT; SELECT FROM ( SELECT * FROM t LEFT JOIN t r USING (a) ) WHERE a GROUP BY (); TRAP: failed Assert("bms_is_member(i, root->outer_join_rels)"), File: "../pg/src/backend/optimizer/path/equivclass.c", Line: 3631, PID: 1813021 Stack trace: #6 0x000055d44911f565 in get_eclass_indexes_for_relids (root=root@entry=0x55d45c0a2d58, relids=relids@entry=0x55d45c0af3f0) at ../pg/src/backend/optimizer/path/equivclass.c:3631 #7 0x000055d44911f338 in get_common_eclass_indexes (root=0x55d45c0a2d58, relids1=0x55d45c0a47e8, relids2=0x55d45c0af3f0) at ../pg/src/backend/optimizer/path/equivclass.c:3662 #8 generate_join_implied_equalities (root=root@entry=0x55d45c0a2d58, join_relids=join_relids@entry=0x55d45c0af520, outer_relids=outer_relids@entry=0x55d45c0af3f0, inner_rel=inner_rel@entry=0x55d45c0a5c28, sjinfo=sjinfo@entry=0x0) at ../pg/src/backend/optimizer/path/equivclass.c:1599 #9 0x000055d44917a42f in get_baserel_parampathinfo (root=root@entry=0x55d45c0a2d58, baserel=baserel@entry=0x55d45c0a5c28, required_outer=0x55d45c0af3f0) at ../pg/src/backend/optimizer/util/relnode.c:1590 #10 0x000055d44916d0ab in create_index_path (root=root@entry=0x55d45c0a2d58, index=index@entry=0x55d45c0ad048, indexclauses=0x55d45c0af4b0, indexorderbys=0x0, indexorderbycols=indexorderbycols@entry=0x0, pathkeys=0x0, indexscandir=ForwardScanDirection, indexonly=<optimized out>, required_outer=0x55d45c0af3f0, loop_count=<error reading variable: That operation is not available on integers of more than 8 bytes.>, loop_count@entry=1, partial_path=<optimized out>) at ../pg/src/backend/optimizer/util/pathnode.c:1070 #11 0x000055d449126dae in build_index_paths (root=root@entry=0x55d45c0a2d58, rel=rel@entry=0x55d45c0a5c28, index=index@entry=0x55d45c0ad048, clauses=clauses@entry=0x7ffc6f09da70, useful_predicate=false, scantype=scantype@entry=ST_ANYSCAN, skip_nonnative_saop=0x7ffc6f09da37) at ../pg/src/backend/optimizer/path/indxpath.c:969 #12 0x000055d449123cc2 in get_index_paths (root=root@entry=0x55d45c0a2d58, rel=rel@entry=0x55d45c0a5c28, index=0x6, index@entry=0x55d45c0ad048, clauses=clauses@entry=0x7ffc6f09da70, bitindexpaths=bitindexpaths@entry=0x7ffc6f09ddb0) at ../pg/src/backend/optimizer/path/indxpath.c:728 #13 0x000055d449123700 in create_index_paths (root=0x55d45c0a2d58, rel=0x55d45c0a5c28) at ../pg/src/backend/optimizer/path/indxpath.c:285 #14 0x000055d4491141ce in set_rel_pathlist (root=root@entry=0x55d45c0a2d58, rel=rel@entry=0x55d45c0a5c28, rti=5, rte=0x55d45c0a5660) at ../pg/src/backend/optimizer/path/allpaths.c:499 #15 0x000055d449114053 in set_append_rel_pathlist (root=0x55d45c0a2d58, rel=0x55d45c0a4cd0, rti=2, rte=0x55d45bff3dc8) at ../pg/src/backend/optimizer/path/allpaths.c:1290 #16 set_rel_pathlist (root=root@entry=0x55d45c0a2d58, rel=0x55d45c0a4cd0, rti=rti@entry=2, rte=0x55d45bff3dc8) at ../pg/src/backend/optimizer/path/allpaths.c:479 #17 0x000055d44910fd69 in set_base_rel_pathlists (root=0x55d45c0a2d58) at ../pg/src/backend/optimizer/path/allpaths.c:351 #18 make_one_rel (root=root@entry=0x55d45c0a2d58, joinlist=joinlist@entry=0x55d45c0ad6b8) at ../pg/src/backend/optimizer/path/allpaths.c:221 #19 0x000055d449144f89 in query_planner (root=0x55d45c0a2d58, qp_callback=<optimized out>, qp_extra=qp_extra@entry=0x7ffc6f09df48) at ../pg/src/backend/optimizer/plan/planmain.c:288 #20 0x000055d44914817e in grouping_planner (root=root@entry=0x55d45c0a2d58, tuple_fraction=<optimized out>, tuple_fraction@entry=0, setops=setops@entry=0x0) at ../pg/src/backend/optimizer/plan/planner.c:1896 #21 0x000055d449146ae2 in subquery_planner (glob=glob@entry=0x55d45bfbc1e8, parse=parse@entry=0x55d45bfbc2f8, parent_root=parent_root@entry=0x0, hasRecursion=false, tuple_fraction=<error reading variable: That operation is not available on integers of more than 8 bytes.>, setops=setops@entry=0x0) at ../pg/src/backend/optimizer/plan/planner.c:1274 #22 0x000055d44914519a in standard_planner (parse=0x55d45bfbc2f8, query_string=<optimized out>, cursorOptions=2048, boundParams=<optimized out>) at ../pg/src/backend/optimizer/plan/planner.c:453 #23 0x000055d44914503e in planner (parse=0x1baa1d, parse@entry=0x55d45bfbc2f8, query_string=0x1baa1d <error: Cannot access memory at address 0x1baa1d>, query_string@entry=0x55d45bfbaba0 "SELECT", ' ' <repeats 91 times>, "\n FROM (\n SELECT *", ' ' <repeats 79 times>..., cursorOptions=6, cursorOptions@entry=2048, boundParams=0x7f05ac2969fc <__GI___pthread_kill+300>, boundParams@entry=0x0) at ../pg/src/backend/optimizer/plan/planner.c:313 Best regards Alexander Kuzmenkov -
Re: assertion failure with unique index + partitioning + join
Tender Wang <tndrwang@gmail.com> — 2026-06-16T01:58:07Z
Alexander Kuzmenkov <akuzmenkov@tigerdata.com> 于2026年6月15日周一 23:39写道: > > Hi hackers, > > While I was running some random testing on the TimescaleDB extension, I noticed that I can easily hit an assertion failure in plain Postgres REL_18_STABLE. I haven't analyzed it at all, but thought I should report this: > > CREATE TABLE t (a bool UNIQUE) PARTITION BY LIST (a); > CREATE TABLE p PARTITION OF t DEFAULT; > SELECT > FROM ( > SELECT * > FROM t > LEFT JOIN t r USING (a) > ) > WHERE a > GROUP BY (); > > > TRAP: failed Assert("bms_is_member(i, root->outer_join_rels)"), File: "../pg/src/backend/optimizer/path/equivclass.c", Line: 3631, PID: 1813021 > I can reproduce this issue on HEAD. The root->outer_join_rels is empty, and the i is 3(rel: t r). The left join can be removed in remove_useless_joins(), in which root->outer_join_rels is changed to be empty. But the from->qual in this case has already been distributed to its rel. (gdb) pgprint brel->baserestrictinfo RestrictInfo [is_pushed_down=true can_join=false pseudoconstant=false has_clone=false is_clone=false leakproof=false has_volatile=VOLATILITY_UNKNOWN security_level=0 num_base_rels=1 rinfo_serial=1 eval_cost={startup = -1, per_tuple = 0} norm_selec=-1 outer_selec=-1 outer_is_left=false hashjoinoperator=0 left_bucketsize=-1 right_bucketsize=-1 left_mcvfreq=-1 right_mcvfreq=-1 left_hasheqoperator=0 right_hasheqoperator=0] [clause] PlaceHolderVar [phid=1 phlevelsup=0] [phexpr] Var [varno=2 varattno=1 vartype=16 varreturningtype=VAR_RETURNING_DEFAULT varnosyn=2 varattnosyn=1] [phrels] Bitmapset [4 3 2] [clause_relids] Bitmapset [2] [required_relids] Bitmapset [2] 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(). I need to dig deeper to find out how to fix it. -- Thanks, Tender Wang -
Re: assertion failure with unique index + partitioning + join
Tender Wang <tndrwang@gmail.com> — 2026-06-16T04:06:28Z
Hi all, Tender Wang <tndrwang@gmail.com> 于2026年6月16日周二 09:58写道: > > I can reproduce this issue on HEAD. > The root->outer_join_rels is empty, and the i is 3(rel: t r). > The left join can be removed in remove_useless_joins(), in which > root->outer_join_rels is changed to be empty. > But the from->qual in this case has already been distributed to its rel. > (gdb) pgprint brel->baserestrictinfo > RestrictInfo [is_pushed_down=true can_join=false pseudoconstant=false > has_clone=false is_clone=false leakproof=false > has_volatile=VOLATILITY_UNKNOWN security_level=0 > num_base_rels=1 rinfo_serial=1 eval_cost={startup = -1, > per_tuple = 0} norm_selec=-1 outer_selec=-1 outer_is_left=false > hashjoinoperator=0 left_bucketsize=-1 > right_bucketsize=-1 left_mcvfreq=-1 right_mcvfreq=-1 > left_hasheqoperator=0 right_hasheqoperator=0] > [clause] > PlaceHolderVar [phid=1 phlevelsup=0] > [phexpr] Var [varno=2 varattno=1 vartype=16 > varreturningtype=VAR_RETURNING_DEFAULT varnosyn=2 varattnosyn=1] > [phrels] Bitmapset [4 3 2] > [clause_relids] Bitmapset [2] > [required_relids] Bitmapset [2] > I need to dig deeper to find out how to fix it. I tried on the old version (pg1212), I got the correct plan, no crash. And after pulling up the subquery, no PlaceHolderVar. I found after commit cc5d98525d43, commit cc5d98525d43c22b98f360ef0f2c8d7dc57f04dc Author: Richard Guo <rguo@postgresql.org> Date: Thu Mar 13 16:36:03 2025 +0900 Fix incorrect handling of subquery pullup the from->qual will include PHV, because this query contains groupingsets. I reverted this commit, I got correct plan, too: postgres=# explain SELECT FROM ( SELECT * FROM t LEFT JOIN t r USING (a) ) ss WHERE a GROUP BY (); QUERY PLAN ------------------------------------------ Result (cost=0.00..0.01 rows=1 width=0) (1 row) I added Richard to the cc list. He may know more about this. -- Thanks, Tender Wang -
Re: assertion failure with unique index + partitioning + join
Tender Wang <tndrwang@gmail.com> — 2026-06-16T07:45:27Z
Tender Wang <tndrwang@gmail.com> 于2026年6月16日周二 12:06写道: > > Hi all, > > Tender Wang <tndrwang@gmail.com> 于2026年6月16日周二 09:58写道: > > > > I can reproduce this issue on HEAD. > > The root->outer_join_rels is empty, and the i is 3(rel: t r). > > The left join can be removed in remove_useless_joins(), in which > > root->outer_join_rels is changed to be empty. > > But the from->qual in this case has already been distributed to its rel. > > (gdb) pgprint brel->baserestrictinfo > > RestrictInfo [is_pushed_down=true can_join=false pseudoconstant=false > > has_clone=false is_clone=false leakproof=false > > has_volatile=VOLATILITY_UNKNOWN security_level=0 > > num_base_rels=1 rinfo_serial=1 eval_cost={startup = -1, > > per_tuple = 0} norm_selec=-1 outer_selec=-1 outer_is_left=false > > hashjoinoperator=0 left_bucketsize=-1 > > right_bucketsize=-1 left_mcvfreq=-1 right_mcvfreq=-1 > > left_hasheqoperator=0 right_hasheqoperator=0] > > [clause] > > PlaceHolderVar [phid=1 phlevelsup=0] > > [phexpr] Var [varno=2 varattno=1 vartype=16 > > varreturningtype=VAR_RETURNING_DEFAULT varnosyn=2 varattnosyn=1] > > [phrels] Bitmapset [4 3 2] > > [clause_relids] Bitmapset [2] > > [required_relids] Bitmapset [2] > > I need to dig deeper to find out how to fix it. > > I tried on the old version (pg1212), I got the correct plan, no crash. > And after pulling up the subquery, no PlaceHolderVar. I found after > commit cc5d98525d43, > > commit cc5d98525d43c22b98f360ef0f2c8d7dc57f04dc > Author: Richard Guo <rguo@postgresql.org> > Date: Thu Mar 13 16:36:03 2025 +0900 > > Fix incorrect handling of subquery pullup > > the from->qual will include PHV, because this query contains groupingsets. > I reverted this commit, I got correct plan, too: > postgres=# explain SELECT > FROM ( > SELECT * > FROM t > LEFT JOIN t r USING (a) > ) ss > WHERE a > GROUP BY (); > QUERY PLAN > ------------------------------------------ > Result (cost=0.00..0.01 rows=1 width=0) > (1 row) > > > I added Richard to the cc list. He may know more about this. In apply_child_basequals(), the restricintinfo->clause_relids of the child is different from the parent's. The parent's restricintinfo->clause_relids only contains rel:2, but the child contains (3,4,5). The difference is due to pull_varnos_walker() when processing the PlaceholdVar case. I do a quick fix as below: diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c index 6a7b9edff3f..fcf0ad7a187 100644 --- a/src/backend/optimizer/util/inherit.c +++ b/src/backend/optimizer/util/inherit.c @@ -861,6 +861,21 @@ apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, ListCell *lc2; Assert(IsA(rinfo, RestrictInfo)); + if (IsA(rinfo->clause, PlaceHolderVar)) + { + PlaceHolderVar *phv = (PlaceHolderVar *) rinfo->clause; + PlaceHolderInfo *phinfo = NULL; + if (phv->phlevelsup == 0) + { + if (phv->phid < root->placeholder_array_size) + phinfo = root->placeholder_array[phv->phid]; + } + if (phinfo != NULL) + { + phv->phrels = bms_copy(phinfo->ph_var->phrels); + } + + } The issue has gone, and regression tests all pass. But this is very simply fixed. What do you think? -- Thanks, Tender Wang -
Re: assertion failure with unique index + partitioning + join
Richard Guo <guofenglinux@gmail.com> — 2026-06-16T08:27:46Z
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
-
Re: assertion failure with unique index + partitioning + join
Tender Wang <tndrwang@gmail.com> — 2026-06-16T09:32:06Z
Richard Guo <guofenglinux@gmail.com> 于2026年6月16日周二 16:27写道: > > 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. Yes, I came to the same conclusion. > > 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. The fix I proposed was somewhat specific to this particular issue, whereas your patch takes a more general approach. I took a quick pass over the patch and didn't notice any obvious issues. I won't have time to review it in detail today, but I'll try to take a closer look tomorrow morning. > > (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.) Interesting, I hadn't thought of that approach. -- Thanks, Tender Wang
-
Re: assertion failure with unique index + partitioning + join
Tender Wang <tndrwang@gmail.com> — 2026-06-17T02:00:35Z
Hi all, Richard Guo <guofenglinux@gmail.com> 于2026年6月16日周二 16:27写道: > 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 spent some time reviewing the patch in detail. A couple of minor suggestions: In remove_rel_from_eclass(), we have ... if (!IsA(em->em_expr, Var)) em->em_expr = (Expr *) remove_rel_from_phvs((Node *) em->em_expr, relid, ojrelid); ... "where s.id = 1" in the test case, the Const node seems to be able to skip, too. Other than the minor suggestions above, the patch looks good to me. I have another question, although it's unrelated to this bug. The logic in remove_rel_from_query() makes me a bit uneasy. It currently has to handle both self-join and outer-join cases, and it seems possible that inner-join-specific handling could end up being added there in the future as well. The function appears to be taking on multiple distinct responsibilities, which makes the overall design feel somewhat awkward. Perhaps this could be improved as part of your future inner-join removal patch. -- Thanks, Tender Wang -
Re: assertion failure with unique index + partitioning + join
Richard Guo <guofenglinux@gmail.com> — 2026-06-17T05:51:45Z
On Wed, Jun 17, 2026 at 11:00 AM Tender Wang <tndrwang@gmail.com> wrote: > In remove_rel_from_eclass(), we have > ... > if (!IsA(em->em_expr, Var)) > em->em_expr = (Expr *) > remove_rel_from_phvs((Node *) em->em_expr, relid, ojrelid); > ... > "where s.id = 1" in the test case, the Const node seems to be able to skip, too. Good point. Patch updated. > I have another question, although it's unrelated to this bug. > The logic in remove_rel_from_query() makes me a bit uneasy. It > currently has to handle both self-join and outer-join cases, > and it seems possible that inner-join-specific handling could end up > being added there in the future as well. > The function appears to be taking on multiple distinct > responsibilities, which makes the overall design feel somewhat > awkward. Yeah. remove_rel_from_query() was originally written for left-join removal only. The self-join elimination (SJE) commit grafted self-join removal onto it, which made it do more than one thing within one function. Commit 20efbdffe cleaned it up, clarifying the separation between the left-join removal and self-join elimination code paths within it. That cleanup was also meant to make it better structured for adding new types of join removal, such as inner-join removal, in the future. That said, I agree that the current shape is not ideal. A better structure might be to make remove_rel_from_query() handle only the bookkeeping that is common to all removal types, and push the type-specific work into the per-type callers. I think that is worth pursuing as separate future work, kept apart from the current bug fix. - Richard
-
Re: assertion failure with unique index + partitioning + join
Tender Wang <tndrwang@gmail.com> — 2026-06-18T13:01:11Z
Richard Guo <guofenglinux@gmail.com> 于2026年6月17日周三 13:51写道: > > On Wed, Jun 17, 2026 at 11:00 AM Tender Wang <tndrwang@gmail.com> wrote: > > In remove_rel_from_eclass(), we have > > ... > > if (!IsA(em->em_expr, Var)) > > em->em_expr = (Expr *) > > remove_rel_from_phvs((Node *) em->em_expr, relid, ojrelid); > > ... > > "where s.id = 1" in the test case, the Const node seems to be able to skip, too. > > Good point. Patch updated. In remove_rel_from_phvs_mutator(), we have: else if (IsA(node, Query)) { Query *newnode; ... } I want to find what kind of SQL can enter the above else-if block. So I added "assert(0)" to the else-if block. But no regression test crashed. We test rel->baserestrictinfo here. Is it possible that the clause includes a Query structure? I know some xxx_mutator() functions in the planner have the same logic processing pattern. Is there a need to add a test case to cover the above code? > Yeah. remove_rel_from_query() was originally written for left-join > removal only. The self-join elimination (SJE) commit grafted > self-join removal onto it, which made it do more than one thing within > one function. Commit 20efbdffe cleaned it up, clarifying the > separation between the left-join removal and self-join elimination > code paths within it. That cleanup was also meant to make it better > structured for adding new types of join removal, such as inner-join > removal, in the future. > > That said, I agree that the current shape is not ideal. A better > structure might be to make remove_rel_from_query() handle only the > bookkeeping that is common to all removal types, and push the > type-specific work into the per-type callers. I think that is worth > pursuing as separate future work, kept apart from the current bug fix. Agree. -- Thanks, Tender Wang -
Re: assertion failure with unique index + partitioning + join
Richard Guo <guofenglinux@gmail.com> — 2026-06-19T03:03:13Z
On Thu, Jun 18, 2026 at 10:01 PM Tender Wang <tndrwang@gmail.com> wrote: > In remove_rel_from_phvs_mutator(), we have: > > else if (IsA(node, Query)) > { > Query *newnode; > > ... > } > > I want to find what kind of SQL can enter the above else-if block. > So I added "assert(0)" to the else-if block. But no regression test crashed. > We test rel->baserestrictinfo here. Is it possible that the clause > includes a Query structure? Good point. I considered this, and the answer is no. Any SubLink that could contain a Query has already been expanded into a SubPlan by the time we reach left-join removal, so we never encounter a Query here. I think what I had in mind when I wrote that branch was a SubLink wrapped in a PHV with phlevelsup > 0, since SS_process_sublinks does not recurse into the arguments of such an outer-level PHV. But that case cannot arise here either: at left-join removal we only ever see phlevelsup == 0 PHVs, because upper-level ones have already been replaced with Params. So we can drop the 'else if' branch. And we can remove sublevels_up from remove_rel_from_phvs_context, and that makes it a one-field struct, so we can remove the struct as well and just pass the Relids directly. Patch updated. - Richard -
Re: assertion failure with unique index + partitioning + join
Richard Guo <guofenglinux@gmail.com> — 2026-06-22T06:37:04Z
On Fri, Jun 19, 2026 at 12:03 PM Richard Guo <guofenglinux@gmail.com> wrote: > Patch updated. I've committed this patch after some cosmetic tweaks. Thanks for the report (and well-contained repro), and thanks for the reviews. - Richard