diff options
Diffstat (limited to 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r-- | contrib/postgres_fdw/postgres_fdw.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 674eb982d06..2ac9d7bbe7a 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -1229,11 +1229,9 @@ postgresGetForeignPlan(PlannerInfo *root, /* * Ensure that the outer plan produces a tuple whose descriptor - * matches our scan tuple slot. This is safe because all scans and - * joins support projection, so we never need to insert a Result node. - * Also, remove the local conditions from outer plan's quals, lest - * they will be evaluated twice, once by the local plan and once by - * the scan. + * matches our scan tuple slot. Also, remove the local conditions + * from outer plan's quals, lest they be evaluated twice, once by the + * local plan and once by the scan. */ if (outer_plan) { @@ -1246,23 +1244,42 @@ postgresGetForeignPlan(PlannerInfo *root, */ Assert(!IS_UPPER_REL(foreignrel)); - outer_plan->targetlist = fdw_scan_tlist; - + /* + * First, update the plan's qual list if possible. In some cases + * the quals might be enforced below the topmost plan level, in + * which case we'll fail to remove them; it's not worth working + * harder than this. + */ foreach(lc, local_exprs) { - Join *join_plan = (Join *) outer_plan; Node *qual = lfirst(lc); outer_plan->qual = list_delete(outer_plan->qual, qual); /* * For an inner join the local conditions of foreign scan plan - * can be part of the joinquals as well. + * can be part of the joinquals as well. (They might also be + * in the mergequals or hashquals, but we can't touch those + * without breaking the plan.) */ - if (join_plan->jointype == JOIN_INNER) - join_plan->joinqual = list_delete(join_plan->joinqual, - qual); + if (IsA(outer_plan, NestLoop) || + IsA(outer_plan, MergeJoin) || + IsA(outer_plan, HashJoin)) + { + Join *join_plan = (Join *) outer_plan; + + if (join_plan->jointype == JOIN_INNER) + join_plan->joinqual = list_delete(join_plan->joinqual, + qual); + } } + + /* + * Now fix the subplan's tlist --- this might result in inserting + * a Result node atop the plan tree. + */ + outer_plan = change_plan_targetlist(outer_plan, fdw_scan_tlist, + best_path->path.parallel_safe); } } |