aboutsummaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw/postgres_fdw.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-08-17 20:22:37 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2013-08-17 20:22:37 -0400
commit9e7e29c75ad441450f9b8287bd51c13521641e3b (patch)
tree223fb78221fdf2363d2985150603cb30edd295bc /contrib/postgres_fdw/postgres_fdw.c
parent175ec8de470fa5212797d672a2e5f1c79842a9ec (diff)
downloadpostgresql-9e7e29c75ad441450f9b8287bd51c13521641e3b.tar.gz
postgresql-9e7e29c75ad441450f9b8287bd51c13521641e3b.zip
Fix planner problems with LATERAL references in PlaceHolderVars.
The planner largely failed to consider the possibility that a PlaceHolderVar's expression might contain a lateral reference to a Var coming from somewhere outside the PHV's syntactic scope. We had a previous report of a problem in this area, which I tried to fix in a quick-hack way in commit 4da6439bd8553059766011e2a42c6e39df08717f, but Antonin Houska pointed out that there were still some problems, and investigation turned up other issues. This patch largely reverts that commit in favor of a more thoroughly thought-through solution. The new theory is that a PHV's ph_eval_at level cannot be higher than its original syntactic level. If it contains lateral references, those don't change the ph_eval_at level, but rather they create a lateral-reference requirement for the ph_eval_at join relation. The code in joinpath.c needs to handle that. Another issue is that createplan.c wasn't handling nested PlaceHolderVars properly. In passing, push knowledge of lateral-reference checks for join clauses into join_clause_is_movable_to. This is mainly so that FDWs don't need to deal with it. This patch doesn't fix the original join-qual-placement problem reported by Jeremy Evans (and indeed, one of the new regression test cases shows the wrong answer because of that). But the PlaceHolderVar problems need to be fixed before that issue can be addressed, so committing this separately seems reasonable.
Diffstat (limited to 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r--contrib/postgres_fdw/postgres_fdw.c31
1 files changed, 3 insertions, 28 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 1c93e0c5ac3..8713eabc646 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -540,7 +540,6 @@ postgresGetForeignPaths(PlannerInfo *root,
{
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) baserel->fdw_private;
ForeignPath *path;
- Relids lateral_referencers;
List *join_quals;
Relids required_outer;
double rows;
@@ -579,34 +578,13 @@ postgresGetForeignPaths(PlannerInfo *root,
* consider combinations of clauses, probably.
*/
- /*
- * If there are any rels that have LATERAL references to this one, we
- * cannot use join quals referencing them as remote quals for this one,
- * since such rels would have to be on the inside not the outside of a
- * nestloop join relative to this one. Create a Relids set listing all
- * such rels, for use in checks of potential join clauses.
- */
- lateral_referencers = NULL;
- foreach(lc, root->lateral_info_list)
- {
- LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(lc);
-
- if (bms_is_member(baserel->relid, ljinfo->lateral_lhs))
- lateral_referencers = bms_add_member(lateral_referencers,
- ljinfo->lateral_rhs);
- }
-
/* Scan the rel's join clauses */
foreach(lc, baserel->joininfo)
{
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
/* Check if clause can be moved to this rel */
- if (!join_clause_is_movable_to(rinfo, baserel->relid))
- continue;
-
- /* Not useful if it conflicts with any LATERAL references */
- if (bms_overlap(rinfo->clause_relids, lateral_referencers))
+ if (!join_clause_is_movable_to(rinfo, baserel))
continue;
/* See if it is safe to send to remote */
@@ -667,7 +645,7 @@ postgresGetForeignPaths(PlannerInfo *root,
baserel,
ec_member_matches_foreign,
(void *) &arg,
- lateral_referencers);
+ baserel->lateral_referencers);
/* Done if there are no more expressions in the foreign rel */
if (arg.current == NULL)
@@ -682,12 +660,9 @@ postgresGetForeignPaths(PlannerInfo *root,
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
/* Check if clause can be moved to this rel */
- if (!join_clause_is_movable_to(rinfo, baserel->relid))
+ if (!join_clause_is_movable_to(rinfo, baserel))
continue;
- /* Shouldn't conflict with any LATERAL references */
- Assert(!bms_overlap(rinfo->clause_relids, lateral_referencers));
-
/* See if it is safe to send to remote */
if (!is_foreign_expr(root, baserel, rinfo->clause))
continue;