aboutsummaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw/postgres_fdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r--contrib/postgres_fdw/postgres_fdw.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index e8a0d5482a8..a15ce28a48b 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -352,7 +352,8 @@ static bool postgresRecheckForeignScan(ForeignScanState *node,
static void postgresGetForeignUpperPaths(PlannerInfo *root,
UpperRelationKind stage,
RelOptInfo *input_rel,
- RelOptInfo *output_rel);
+ RelOptInfo *output_rel,
+ void *extra);
/*
* Helper functions
@@ -419,7 +420,8 @@ static void conversion_error_callback(void *arg);
static bool foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel,
JoinType jointype, RelOptInfo *outerrel, RelOptInfo *innerrel,
JoinPathExtraData *extra);
-static bool foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel);
+static bool foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel,
+ Node *havingQual);
static List *get_useful_pathkeys_for_relation(PlannerInfo *root,
RelOptInfo *rel);
static List *get_useful_ecs_for_relation(PlannerInfo *root, RelOptInfo *rel);
@@ -427,7 +429,8 @@ static void add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel,
Path *epq_path);
static void add_foreign_grouping_paths(PlannerInfo *root,
RelOptInfo *input_rel,
- RelOptInfo *grouped_rel);
+ RelOptInfo *grouped_rel,
+ GroupPathExtraData *extra);
static void apply_server_options(PgFdwRelationInfo *fpinfo);
static void apply_table_options(PgFdwRelationInfo *fpinfo);
static void merge_fdw_options(PgFdwRelationInfo *fpinfo,
@@ -2775,12 +2778,15 @@ estimate_path_cost_size(PlannerInfo *root,
else if (IS_UPPER_REL(foreignrel))
{
PgFdwRelationInfo *ofpinfo;
- PathTarget *ptarget = root->upper_targets[UPPERREL_GROUP_AGG];
+ PathTarget *ptarget = foreignrel->reltarget;
AggClauseCosts aggcosts;
double input_rows;
int numGroupCols;
double numGroups = 1;
+ /* Make sure the core code set the pathtarget. */
+ Assert(ptarget != NULL);
+
/*
* This cost model is mixture of costing done for sorted and
* hashed aggregates in cost_agg(). We are not sure which
@@ -2805,6 +2811,12 @@ estimate_path_cost_size(PlannerInfo *root,
{
get_agg_clause_costs(root, (Node *) fpinfo->grouped_tlist,
AGGSPLIT_SIMPLE, &aggcosts);
+
+ /*
+ * The cost of aggregates in the HAVING qual will be the same
+ * for each child as it is for the parent, so there's no need
+ * to use a translated version of havingQual.
+ */
get_agg_clause_costs(root, (Node *) root->parse->havingQual,
AGGSPLIT_SIMPLE, &aggcosts);
}
@@ -5017,11 +5029,12 @@ postgresGetForeignJoinPaths(PlannerInfo *root,
* this function to PgFdwRelationInfo of the input relation.
*/
static bool
-foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel)
+foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel,
+ Node *havingQual)
{
Query *query = root->parse;
- PathTarget *grouping_target = root->upper_targets[UPPERREL_GROUP_AGG];
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) grouped_rel->fdw_private;
+ PathTarget *grouping_target = grouped_rel->reltarget;
PgFdwRelationInfo *ofpinfo;
List *aggvars;
ListCell *lc;
@@ -5131,11 +5144,11 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel)
* Classify the pushable and non-pushable HAVING clauses and save them in
* remote_conds and local_conds of the grouped rel's fpinfo.
*/
- if (root->hasHavingQual && query->havingQual)
+ if (havingQual)
{
ListCell *lc;
- foreach(lc, (List *) query->havingQual)
+ foreach(lc, (List *) havingQual)
{
Expr *expr = (Expr *) lfirst(lc);
RestrictInfo *rinfo;
@@ -5232,7 +5245,8 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel)
*/
static void
postgresGetForeignUpperPaths(PlannerInfo *root, UpperRelationKind stage,
- RelOptInfo *input_rel, RelOptInfo *output_rel)
+ RelOptInfo *input_rel, RelOptInfo *output_rel,
+ void *extra)
{
PgFdwRelationInfo *fpinfo;
@@ -5252,7 +5266,8 @@ postgresGetForeignUpperPaths(PlannerInfo *root, UpperRelationKind stage,
fpinfo->pushdown_safe = false;
output_rel->fdw_private = fpinfo;
- add_foreign_grouping_paths(root, input_rel, output_rel);
+ add_foreign_grouping_paths(root, input_rel, output_rel,
+ (GroupPathExtraData *) extra);
}
/*
@@ -5264,13 +5279,13 @@ postgresGetForeignUpperPaths(PlannerInfo *root, UpperRelationKind stage,
*/
static void
add_foreign_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel,
- RelOptInfo *grouped_rel)
+ RelOptInfo *grouped_rel,
+ GroupPathExtraData *extra)
{
Query *parse = root->parse;
PgFdwRelationInfo *ifpinfo = input_rel->fdw_private;
PgFdwRelationInfo *fpinfo = grouped_rel->fdw_private;
ForeignPath *grouppath;
- PathTarget *grouping_target;
double rows;
int width;
Cost startup_cost;
@@ -5281,7 +5296,8 @@ add_foreign_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel,
!root->hasHavingQual)
return;
- grouping_target = root->upper_targets[UPPERREL_GROUP_AGG];
+ Assert(extra->patype == PARTITIONWISE_AGGREGATE_NONE ||
+ extra->patype == PARTITIONWISE_AGGREGATE_FULL);
/* save the input_rel as outerrel in fpinfo */
fpinfo->outerrel = input_rel;
@@ -5295,8 +5311,13 @@ add_foreign_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel,
fpinfo->user = ifpinfo->user;
merge_fdw_options(fpinfo, ifpinfo, NULL);
- /* Assess if it is safe to push down aggregation and grouping. */
- if (!foreign_grouping_ok(root, grouped_rel))
+ /*
+ * Assess if it is safe to push down aggregation and grouping.
+ *
+ * Use HAVING qual from extra. In case of child partition, it will have
+ * translated Vars.
+ */
+ if (!foreign_grouping_ok(root, grouped_rel, extra->havingQual))
return;
/* Estimate the cost of push down */
@@ -5312,7 +5333,7 @@ add_foreign_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel,
/* Create and add foreign path to the grouping relation. */
grouppath = create_foreignscan_path(root,
grouped_rel,
- grouping_target,
+ grouped_rel->reltarget,
rows,
startup_cost,
total_cost,