aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/relnode.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-12-11 15:52:16 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2015-12-11 15:52:39 -0500
commitdc4518814ecc2ae319c4d1679ee079e47dbd78e9 (patch)
tree5158f9a835583bc58b7f715784608c5d4b48cdf3 /src/backend/optimizer/util/relnode.c
parent12a54c888cf7bd9c37c4ce420e84cb52debe0184 (diff)
downloadpostgresql-dc4518814ecc2ae319c4d1679ee079e47dbd78e9.tar.gz
postgresql-dc4518814ecc2ae319c4d1679ee079e47dbd78e9.zip
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.
Diffstat (limited to 'src/backend/optimizer/util/relnode.c')
-rw-r--r--src/backend/optimizer/util/relnode.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index f7439f8a0e3..3c34711ab3b 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -109,6 +109,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;
@@ -370,6 +371,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 */
@@ -420,6 +425,18 @@ build_join_rel(PlannerInfo *root,
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
* for set_joinrel_size_estimates().)