Commit ffab494a authored by Etsuro Fujita's avatar Etsuro Fujita

postgres_fdw: Perform the (ORDERED, NULL) upperrel operations remotely.

The upper-planner pathification allows FDWs to arrange to push down
different types of upper-stage operations to the remote side.  This
commit teaches postgres_fdw to do it for the (ORDERED, NULL) upperrel,
which is responsible for evaluating the query's ORDER BY ordering.
Since postgres_fdw is already able to evaluate that ordering remotely
for foreign baserels and foreign joinrels (see commit aa09cd24 et al.),
this adds support for that for foreign grouping relations.

Author: Etsuro Fujita
Reviewed-By: Antonin Houska and Jeff Janes
Discussion: https://postgr.es/m/87pnz1aby9.fsf@news-spur.riddles.org.uk
parent e2d28c0f
...@@ -167,7 +167,8 @@ static void printRemotePlaceholder(Oid paramtype, int32 paramtypmod, ...@@ -167,7 +167,8 @@ static void printRemotePlaceholder(Oid paramtype, int32 paramtypmod,
static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs, static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs,
deparse_expr_cxt *context); deparse_expr_cxt *context);
static void deparseLockingClause(deparse_expr_cxt *context); static void deparseLockingClause(deparse_expr_cxt *context);
static void appendOrderByClause(List *pathkeys, deparse_expr_cxt *context); static void appendOrderByClause(List *pathkeys, bool has_final_sort,
deparse_expr_cxt *context);
static void appendConditions(List *exprs, deparse_expr_cxt *context); static void appendConditions(List *exprs, deparse_expr_cxt *context);
static void deparseFromExprForRel(StringInfo buf, PlannerInfo *root, static void deparseFromExprForRel(StringInfo buf, PlannerInfo *root,
RelOptInfo *foreignrel, bool use_alias, RelOptInfo *foreignrel, bool use_alias,
...@@ -929,8 +930,8 @@ build_tlist_to_deparse(RelOptInfo *foreignrel) ...@@ -929,8 +930,8 @@ build_tlist_to_deparse(RelOptInfo *foreignrel)
void void
deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel, deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel,
List *tlist, List *remote_conds, List *pathkeys, List *tlist, List *remote_conds, List *pathkeys,
bool is_subquery, List **retrieved_attrs, bool has_final_sort, bool is_subquery,
List **params_list) List **retrieved_attrs, List **params_list)
{ {
deparse_expr_cxt context; deparse_expr_cxt context;
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private; PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
...@@ -985,7 +986,7 @@ deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel, ...@@ -985,7 +986,7 @@ deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel,
/* Add ORDER BY clause if we found any useful pathkeys */ /* Add ORDER BY clause if we found any useful pathkeys */
if (pathkeys) if (pathkeys)
appendOrderByClause(pathkeys, &context); appendOrderByClause(pathkeys, has_final_sort, &context);
/* Add any necessary FOR UPDATE/SHARE. */ /* Add any necessary FOR UPDATE/SHARE. */
deparseLockingClause(&context); deparseLockingClause(&context);
...@@ -1590,7 +1591,7 @@ deparseRangeTblRef(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, ...@@ -1590,7 +1591,7 @@ deparseRangeTblRef(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel,
/* Deparse the subquery representing the relation. */ /* Deparse the subquery representing the relation. */
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
deparseSelectStmtForRel(buf, root, foreignrel, NIL, deparseSelectStmtForRel(buf, root, foreignrel, NIL,
fpinfo->remote_conds, NIL, true, fpinfo->remote_conds, NIL, false, true,
&retrieved_attrs, params_list); &retrieved_attrs, params_list);
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
...@@ -3109,7 +3110,8 @@ appendGroupByClause(List *tlist, deparse_expr_cxt *context) ...@@ -3109,7 +3110,8 @@ appendGroupByClause(List *tlist, deparse_expr_cxt *context)
* base relation are obtained and deparsed. * base relation are obtained and deparsed.
*/ */
static void static void
appendOrderByClause(List *pathkeys, deparse_expr_cxt *context) appendOrderByClause(List *pathkeys, bool has_final_sort,
deparse_expr_cxt *context)
{ {
ListCell *lcell; ListCell *lcell;
int nestlevel; int nestlevel;
...@@ -3126,7 +3128,19 @@ appendOrderByClause(List *pathkeys, deparse_expr_cxt *context) ...@@ -3126,7 +3128,19 @@ appendOrderByClause(List *pathkeys, deparse_expr_cxt *context)
PathKey *pathkey = lfirst(lcell); PathKey *pathkey = lfirst(lcell);
Expr *em_expr; Expr *em_expr;
em_expr = find_em_expr_for_rel(pathkey->pk_eclass, baserel); if (has_final_sort)
{
/*
* By construction, context->foreignrel is the input relation to
* the final sort.
*/
em_expr = find_em_expr_for_input_target(context->root,
pathkey->pk_eclass,
context->foreignrel->reltarget);
}
else
em_expr = find_em_expr_for_rel(pathkey->pk_eclass, baserel);
Assert(em_expr != NULL); Assert(em_expr != NULL);
appendStringInfoString(buf, delim); appendStringInfoString(buf, delim);
......
This diff is collapsed.
...@@ -49,6 +49,9 @@ typedef struct PgFdwRelationInfo ...@@ -49,6 +49,9 @@ typedef struct PgFdwRelationInfo
/* Bitmap of attr numbers we need to fetch from the remote server. */ /* Bitmap of attr numbers we need to fetch from the remote server. */
Bitmapset *attrs_used; Bitmapset *attrs_used;
/* True means that the query_pathkeys is safe to push down */
bool qp_is_pushdown_safe;
/* Cost and selectivity of local_conds. */ /* Cost and selectivity of local_conds. */
QualCost local_conds_cost; QualCost local_conds_cost;
Selectivity local_conds_sel; Selectivity local_conds_sel;
...@@ -92,6 +95,9 @@ typedef struct PgFdwRelationInfo ...@@ -92,6 +95,9 @@ typedef struct PgFdwRelationInfo
/* joinclauses contains only JOIN/ON conditions for an outer join */ /* joinclauses contains only JOIN/ON conditions for an outer join */
List *joinclauses; /* List of RestrictInfo */ List *joinclauses; /* List of RestrictInfo */
/* Upper relation information */
UpperRelationKind stage;
/* Grouping information */ /* Grouping information */
List *grouped_tlist; List *grouped_tlist;
...@@ -175,10 +181,14 @@ extern void deparseAnalyzeSql(StringInfo buf, Relation rel, ...@@ -175,10 +181,14 @@ extern void deparseAnalyzeSql(StringInfo buf, Relation rel,
List **retrieved_attrs); List **retrieved_attrs);
extern void deparseStringLiteral(StringInfo buf, const char *val); extern void deparseStringLiteral(StringInfo buf, const char *val);
extern Expr *find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel); extern Expr *find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel);
extern Expr *find_em_expr_for_input_target(PlannerInfo *root,
EquivalenceClass *ec,
PathTarget *target);
extern List *build_tlist_to_deparse(RelOptInfo *foreignrel); extern List *build_tlist_to_deparse(RelOptInfo *foreignrel);
extern void deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, extern void deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root,
RelOptInfo *foreignrel, List *tlist, RelOptInfo *foreignrel, List *tlist,
List *remote_conds, List *pathkeys, bool is_subquery, List *remote_conds, List *pathkeys,
bool has_final_sort, bool is_subquery,
List **retrieved_attrs, List **params_list); List **retrieved_attrs, List **params_list);
extern const char *get_jointype_name(JoinType jointype); extern const char *get_jointype_name(JoinType jointype);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment