From 4fcf48450d38e28e69e629c779a7866183d8ea41 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 11 Dec 2015 15:52:16 -0500 Subject: Get rid of the planner's LateralJoinInfo data structure. I originally modeled this data structure on SpecialJoinInfo, but after commit acfcd45cacb6df23 that looks like a pretty poor decision. All we really need is relid sets identifying laterally-referenced rels; and most of the time, what we want to know about includes indirect lateral references, a case the LateralJoinInfo data was unsuited to compute with any efficiency. The previous commit redefined RelOptInfo.lateral_relids as the transitive closure of lateral references, so that it easily supports checking indirect references. For the places where we really do want just direct references, add a new RelOptInfo field direct_lateral_relids, which is easily set up as a copy of lateral_relids before we perform the transitive closure calculation. Then we can just drop lateral_info_list and LateralJoinInfo and the supporting code. This makes the planner's handling of lateral references noticeably more efficient, and shorter too. Such a change can't be back-patched into stable branches for fear of breaking extensions that might be looking at the planner's data structures; but it seems not too late to push it into 9.5, so I've done so. --- src/backend/optimizer/util/relnode.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/backend/optimizer/util/relnode.c') diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index a2be2ede85e..f2bdfcc745a 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -111,6 +111,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind) rel->cheapest_total_path = NULL; rel->cheapest_unique_path = NULL; rel->cheapest_parameterized_paths = NIL; + rel->direct_lateral_relids = NULL; rel->lateral_relids = NULL; rel->relid = relid; rel->rtekind = rte->rtekind; @@ -373,6 +374,10 @@ build_join_rel(PlannerInfo *root, joinrel->cheapest_total_path = NULL; joinrel->cheapest_unique_path = NULL; joinrel->cheapest_parameterized_paths = NIL; + /* init direct_lateral_relids from children; we'll finish it up below */ + joinrel->direct_lateral_relids = + bms_union(outer_rel->direct_lateral_relids, + inner_rel->direct_lateral_relids); joinrel->lateral_relids = min_join_parameterization(root, joinrel->relids, outer_rel, inner_rel); joinrel->relid = 0; /* indicates not a baserel */ @@ -422,6 +427,18 @@ build_join_rel(PlannerInfo *root, build_joinrel_tlist(root, joinrel, inner_rel); add_placeholders_to_joinrel(root, joinrel); + /* + * add_placeholders_to_joinrel also took care of adding the ph_lateral + * sets of any PlaceHolderVars computed here to direct_lateral_relids, so + * now we can finish computing that. This is much like the computation of + * the transitively-closed lateral_relids in min_join_parameterization, + * except that here we *do* have to consider the added PHVs. + */ + joinrel->direct_lateral_relids = + bms_del_members(joinrel->direct_lateral_relids, joinrel->relids); + if (bms_is_empty(joinrel->direct_lateral_relids)) + joinrel->direct_lateral_relids = NULL; + /* * Construct restrict and join clause lists for the new joinrel. (The * caller might or might not need the restrictlist, but I need it anyway -- cgit v1.2.3