From 83204e100c7855a50ccffd761bcd45474955b5fb Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 7 Mar 2014 16:35:58 -0500 Subject: Fix contrib/postgres_fdw to handle multiple join conditions properly. The previous coding supposed that it could consider just a single join condition in any one parameterized path for the foreign table. But in reality, the parameterized-path machinery forces all join clauses that are "movable to" the foreign table to be evaluated at that node; including clauses that we might not consider safe to send across. Such cases would result in an Assert failure in an assert-enabled build, and otherwise in sending an unsafe clause to the foreign server, which might result in errors or silently-wrong answers. A lesser problem was that the cost/rowcount estimates generated for the parameterized path failed to account for any additional join quals that get assigned to the scan. To fix, rewrite postgresGetForeignPaths so that it correctly collects all the movable quals for any one outer relation when generating parameterized paths; we'll now generate just one path per outer relation not one per join qual. Also fix bogus assumptions in postgresGetForeignPlan and estimate_path_cost_size that only safe-to-send join quals will be presented. Based on complaint from Etsuro Fujita that the path costs were being miscalculated, though this is significantly different from his proposed patch. --- contrib/postgres_fdw/deparse.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'contrib/postgres_fdw/deparse.c') diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index e5e9c2d4e6b..2dfe80da0af 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -134,14 +134,15 @@ static void deparseArrayExpr(ArrayExpr *node, deparse_expr_cxt *context); /* - * Examine each restriction clause in baserel's baserestrictinfo list, - * and classify them into two groups, which are returned as two lists: + * Examine each qual clause in input_conds, and classify them into two groups, + * which are returned as two lists: * - remote_conds contains expressions that can be evaluated remotely * - local_conds contains expressions that can't be evaluated remotely */ void classifyConditions(PlannerInfo *root, RelOptInfo *baserel, + List *input_conds, List **remote_conds, List **local_conds) { @@ -150,7 +151,7 @@ classifyConditions(PlannerInfo *root, *remote_conds = NIL; *local_conds = NIL; - foreach(lc, baserel->baserestrictinfo) + foreach(lc, input_conds) { RestrictInfo *ri = (RestrictInfo *) lfirst(lc); -- cgit v1.2.3