Tender Wang <[email protected]> 于2026年6月16日周二 12:06写道:
>
> Hi all,
>
> Tender Wang <[email protected]> 于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 <[email protected]>
> 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


Reply via email to