summaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw/deparse.c
diff options
context:
space:
mode:
authorEtsuro Fujita <efujita@postgresql.org>2019-04-02 20:30:45 +0900
committerEtsuro Fujita <efujita@postgresql.org>2019-04-02 20:30:45 +0900
commitd50d172e517c1d2aabff3ceb3ad3113b909c5017 (patch)
tree7a65adb1310d1fa0f08effc93ee75e7558cc8d9f /contrib/postgres_fdw/deparse.c
parentaef65db6769e3f2c855dd89edcf95a536a9ab74f (diff)
downloadpostgresql-d50d172e517c1d2aabff3ceb3ad3113b909c5017.tar.gz
postgres_fdw: Perform the (FINAL, 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 (FINAL, NULL) upperrel, which is responsible for doing LockRows, LIMIT, and/or ModifyTable. This provides the ability for postgres_fdw to handle SELECT commands so that it 1) skips the LockRows step (if any) (note that this is safe since it performs early locking) and 2) pushes down the LIMIT and/or OFFSET restrictions (if any) to the remote side. This doesn't handle the INSERT/UPDATE/DELETE cases. Author: Etsuro Fujita Reviewed-By: Antonin Houska and Jeff Janes Discussion: https://postgr.es/m/87pnz1aby9.fsf@news-spur.riddles.org.uk
Diffstat (limited to 'contrib/postgres_fdw/deparse.c')
-rw-r--r--contrib/postgres_fdw/deparse.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index 97dd07bee8..079406f4f3 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -169,6 +169,7 @@ static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_att
static void deparseLockingClause(deparse_expr_cxt *context);
static void appendOrderByClause(List *pathkeys, bool has_final_sort,
deparse_expr_cxt *context);
+static void appendLimitClause(deparse_expr_cxt *context);
static void appendConditions(List *exprs, deparse_expr_cxt *context);
static void deparseFromExprForRel(StringInfo buf, PlannerInfo *root,
RelOptInfo *foreignrel, bool use_alias,
@@ -930,7 +931,7 @@ build_tlist_to_deparse(RelOptInfo *foreignrel)
void
deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel,
List *tlist, List *remote_conds, List *pathkeys,
- bool has_final_sort, bool is_subquery,
+ bool has_final_sort, bool has_limit, bool is_subquery,
List **retrieved_attrs, List **params_list)
{
deparse_expr_cxt context;
@@ -988,6 +989,10 @@ deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel,
if (pathkeys)
appendOrderByClause(pathkeys, has_final_sort, &context);
+ /* Add LIMIT clause if necessary */
+ if (has_limit)
+ appendLimitClause(&context);
+
/* Add any necessary FOR UPDATE/SHARE. */
deparseLockingClause(&context);
}
@@ -1591,7 +1596,8 @@ deparseRangeTblRef(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel,
/* Deparse the subquery representing the relation. */
appendStringInfoChar(buf, '(');
deparseSelectStmtForRel(buf, root, foreignrel, NIL,
- fpinfo->remote_conds, NIL, false, true,
+ fpinfo->remote_conds, NIL,
+ false, false, true,
&retrieved_attrs, params_list);
appendStringInfoChar(buf, ')');
@@ -3161,6 +3167,33 @@ appendOrderByClause(List *pathkeys, bool has_final_sort,
}
/*
+ * Deparse LIMIT/OFFSET clause.
+ */
+static void
+appendLimitClause(deparse_expr_cxt *context)
+{
+ PlannerInfo *root = context->root;
+ StringInfo buf = context->buf;
+ int nestlevel;
+
+ /* Make sure any constants in the exprs are printed portably */
+ nestlevel = set_transmission_modes();
+
+ if (root->parse->limitCount)
+ {
+ appendStringInfoString(buf, " LIMIT ");
+ deparseExpr((Expr *) root->parse->limitCount, context);
+ }
+ if (root->parse->limitOffset)
+ {
+ appendStringInfoString(buf, " OFFSET ");
+ deparseExpr((Expr *) root->parse->limitOffset, context);
+ }
+
+ reset_transmission_modes(nestlevel);
+}
+
+/*
* appendFunctionName
* Deparses function name from given function oid.
*/