| From: | wenhui qiu <qiuwenhuifx(at)gmail(dot)com> |
|---|---|
| To: | Richard Guo <guofenglinux(at)gmail(dot)com> |
| Cc: | Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: "failed to build any N-way joins" from a five-relation query |
| Date: | 2026-10-08 08:50:16 |
| Message-ID: | CAGjGUAL=ZbJvtk2h3QNLzxRMHR8vnC=ioWyEB3ZFKcVXqxnKjw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Richard Guo
> Thanks for the patch and the detailed analysis.
>
> The problem diagnosis and the example query (t1 --LJ--> t2 <--lateral-- s1
> --LJ--> t3 <--lateral-- s2) are very clear. Rejecting joins whose lateral
> references are trapped inside outer joins or downstream lateral
> dependencies is topologically sound and nicely fixes the "failed to build
> any 5-way joins" failure.
>
> *Just a couple of small thoughts regarding the implementation and
> back-patching, for your consideration:*
>
> 1. Leveraging existing lateral_referencers
>
> In the patch, the search loops over simple_rel_array on every iteration of
> do ... while (more):
>
>
> + /* add rels that laterally reference any rel found so
> far */
> + for (int rti = 1; rti < root->simple_rel_array_size;
> rti++)
> + {
> + RelOptInfo *brel = root->simple_rel_array[rti];
> ...
> + if (!bms_is_member(rti, join_plus_rhs) &&
> + bms_overlap(brel->lateral_relids,
> join_plus_rhs))
> + {
> + join_plus_rhs =
> bms_add_member(join_plus_rhs, rti);
> + more = true;
> + }
> + }
>
> Since join_is_legal() is on the critical hot path of join search, doing a
> full linear scan of simple_rel_array and checking bms_overlap() on every
> iteration could introduce overhead, especially for queries on partitioned
> tables where simple_rel_array_size can be large.
>
> In src/backend/optimizer/plan/initsplan.c, create_lateral_join_info()
> already builds the inverse mapping with transitive closure already computed:
>
>
> /*
> * Now that we've identified all lateral references, mark each baserel
> * with the set of relids of rels that reference it laterally (possibly
> * indirectly) --- that is, the inverse mapping of lateral_relids.
> */
> brel2->lateral_referencers = bms_add_member(brel2->lateral_referencers,
> rti);
>
> Could we take advantage of brel->lateral_referencers for the relations
> already present in join_plus_rhs instead of scanning all baserels from
> scratch? That would directly yield all direct and indirect lateral
> referencers without repeatedly inspecting unrelated baserels.
>
> 2. Interactions with PG 17+ Outer Join infrastructure (ojrelid)
>
> The patch targets Backpatch-through: 14. However, in PG 17 and master, the
> outer join infrastructure was significantly refactored by Tom Lane to give
> outer joins their own ojrelid (root->outer_join_rels, sjinfo->ojrelid).
>
> Notice the check that immediately follows this loop in v17/master:
>
>
> if (bms_overlap(join_lateral_rels, root->outer_join_rels))
> {
> foreach(l, root->join_info_list)
> {
> SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l);
> if (!bms_is_member(sjinfo->ojrelid, join_lateral_rels))
> continue;
> if (bms_overlap(join_plus_rhs, sjinfo->min_lefthand) ||
> bms_overlap(join_plus_rhs, sjinfo->min_righthand))
> return false; /* OJ can't be formed outside join */
> }
> }
>
> In PG 17 and master, join_plus_rhs can contain ojrelids in addition to
> baserel relids. The proposed loop skips anything where brel == NULL ||
> brel->reloptkind != RELOPT_BASEREL. While this assumption holds cleanly on
> v14–v16, on v17/master:
>
> If join_plus_rhs contains an ojrelid, looking only at baserel
> lateral_relids might miss lateral dependencies that reference an outer join
> (for instance, via a PlaceHolderVar evaluated at that outer join).
> Conversely, whether join_plus_rhs containing ojrelids needs explicit
> propagation through lateral references should probably be verified or
> documented to ensure complete branch compatibility between v14–v16 and
> v17/master.
>
> What are your thoughts on these two points?
>
Thanks
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Анатолий Олегович Краев | 2026-10-08 08:54:43 | [PATCH v1] Doc: use double quotes for ulink URLs in features.sgml |
| Previous Message | jian he | 2026-10-08 08:34:32 | Re: Row pattern recognition |