diff options
Diffstat (limited to 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r-- | contrib/postgres_fdw/postgres_fdw.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index fb8cd37fb68..3b0145207b0 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -5308,6 +5308,55 @@ add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel, useful_pathkeys_list = get_useful_pathkeys_for_relation(root, rel); + /* + * Before creating sorted paths, arrange for the passed-in EPQ path, if + * any, to return columns needed by the parent ForeignScan node so that + * they will propagate up through Sort nodes injected below, if necessary. + */ + if (epq_path != NULL && useful_pathkeys_list != NIL) + { + PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private; + PathTarget *target = copy_pathtarget(epq_path->pathtarget); + + /* Include columns required for evaluating PHVs in the tlist. */ + add_new_columns_to_pathtarget(target, + pull_var_clause((Node *) target->exprs, + PVC_RECURSE_PLACEHOLDERS)); + + /* Include columns required for evaluating the local conditions. */ + foreach(lc, fpinfo->local_conds) + { + RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc); + + add_new_columns_to_pathtarget(target, + pull_var_clause((Node *) rinfo->clause, + PVC_RECURSE_PLACEHOLDERS)); + } + + /* + * If we have added any new columns, adjust the tlist of the EPQ path. + * + * Note: the plan created using this path will only be used to execute + * EPQ checks, where accuracy of the plan cost and width estimates + * would not be important, so we do not do set_pathtarget_cost_width() + * for the new pathtarget here. See also postgresGetForeignPlan(). + */ + if (list_length(target->exprs) > list_length(epq_path->pathtarget->exprs)) + { + /* The EPQ path is a join path, so it is projection-capable. */ + Assert(is_projection_capable_path(epq_path)); + + /* + * Use create_projection_path() here, so as to avoid modifying it + * in place. + */ + epq_path = (Path *) create_projection_path(root, + rel, + epq_path, + target); + } + } + /* Create one path for each set of pathkeys we found above. */ foreach(lc, useful_pathkeys_list) { |