aboutsummaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw/deparse.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-01-30 10:32:38 -0500
committerRobert Haas <rhaas@postgresql.org>2016-01-30 10:32:38 -0500
commitcc592c48c58d9c1920f8e2063756dcbcce79e4dd (patch)
treeb3c640bb4c286ffc04bae290a6f84c24e4ee83bc /contrib/postgres_fdw/deparse.c
parent2251179e6ad3a865d2f55e1832fab34608fcce43 (diff)
downloadpostgresql-cc592c48c58d9c1920f8e2063756dcbcce79e4dd.tar.gz
postgresql-cc592c48c58d9c1920f8e2063756dcbcce79e4dd.zip
postgres_fdw: More preliminary refactoring for upcoming join pushdown.
The code that generates a complete SQL query for a given foreign relation was repeated in two places, and they didn't quite agree: the EXPLAIN case left out the locking clause. Centralize the code so we get the same behavior everywhere, and adjust calling conventions and which functions are static vs. extern accordingly . Centralize the code so we get the same behavior everywhere, and adjust calling conventions and which functions are static vs. extern accordingly. Ashutosh Bapat, reviewed and slightly adjusted by me.
Diffstat (limited to 'contrib/postgres_fdw/deparse.c')
-rw-r--r--contrib/postgres_fdw/deparse.c127
1 files changed, 76 insertions, 51 deletions
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index e577a039566..df3d1ee1846 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -141,6 +141,11 @@ static void printRemoteParam(int paramindex, Oid paramtype, int32 paramtypmod,
deparse_expr_cxt *context);
static void printRemotePlaceholder(Oid paramtype, int32 paramtypmod,
deparse_expr_cxt *context);
+static void deparseSelectSql(Bitmapset *attrs_used, List **retrieved_attrs,
+ deparse_expr_cxt *context);
+static void deparseLockingClause(deparse_expr_cxt *context);
+static void appendWhereClause(List *exprs, deparse_expr_cxt *context);
+static void appendOrderByClause(List *pathkeys, deparse_expr_cxt *context);
/*
@@ -697,6 +702,51 @@ deparse_type_name(Oid type_oid, int32 typemod)
return format_type_with_typemod_qualified(type_oid, typemod);
}
+/*
+ * Deparse SELECT statement for given relation into buf.
+ *
+ * remote_conds is the list of conditions to be deparsed as WHERE clause.
+ *
+ * pathkeys is the list of pathkeys to order the result by.
+ *
+ * List of columns selected is returned in retrieved_attrs.
+ *
+ * If params_list is not NULL, it receives a list of Params and other-relation
+ * Vars used in the clauses; these values must be transmitted to the remote
+ * server as parameter values.
+ *
+ * If params_list is NULL, we're generating the query for EXPLAIN purposes,
+ * so Params and other-relation Vars should be replaced by dummy values.
+ */
+extern void
+deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel,
+ List *remote_conds, List *pathkeys,
+ List **retrieved_attrs, List **params_list)
+{
+ PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
+ deparse_expr_cxt context;
+
+ /* Initialize params_list if caller needs one */
+ if (params_list)
+ *params_list = NIL;
+
+ context.buf = buf;
+ context.root = root;
+ context.foreignrel = rel;
+ context.params_list = params_list;
+
+ deparseSelectSql(fpinfo->attrs_used, retrieved_attrs, &context);
+
+ if (remote_conds)
+ appendWhereClause(remote_conds, &context);
+
+ /* Add ORDER BY clause if we found any useful pathkeys */
+ if (pathkeys)
+ appendOrderByClause(pathkeys, &context);
+
+ /* Add any necessary FOR UPDATE/SHARE. */
+ deparseLockingClause(&context);
+}
/*
* Construct a simple SELECT statement that retrieves desired columns
@@ -707,13 +757,13 @@ deparse_type_name(Oid type_oid, int32 typemod)
* returned to *retrieved_attrs.
*/
void
-deparseSelectSql(StringInfo buf,
- PlannerInfo *root,
- RelOptInfo *baserel,
- Bitmapset *attrs_used,
- List **retrieved_attrs)
+deparseSelectSql(Bitmapset *attrs_used, List **retrieved_attrs,
+ deparse_expr_cxt *context)
{
- RangeTblEntry *rte = planner_rt_fetch(baserel->relid, root);
+ StringInfo buf = context->buf;
+ RelOptInfo *foreignrel = context->foreignrel;
+ PlannerInfo *root = context->root;
+ RangeTblEntry *rte = planner_rt_fetch(foreignrel->relid, root);
Relation rel;
/*
@@ -726,7 +776,7 @@ deparseSelectSql(StringInfo buf,
* Construct SELECT list
*/
appendStringInfoString(buf, "SELECT ");
- deparseTargetList(buf, root, baserel->relid, rel, attrs_used,
+ deparseTargetList(buf, root, foreignrel->relid, rel, attrs_used,
retrieved_attrs);
/*
@@ -811,11 +861,15 @@ deparseTargetList(StringInfo buf,
/*
* Deparse the appropriate locking clause (FOR SELECT or FOR SHARE) for a
- * given relation.
+ * given relation (context->foreignrel).
*/
-void
-deparseLockingClause(StringInfo buf, PlannerInfo *root, RelOptInfo *rel)
+static void
+deparseLockingClause(deparse_expr_cxt *context)
{
+ StringInfo buf = context->buf;
+ PlannerInfo *root = context->root;
+ RelOptInfo *rel = context->foreignrel;
+
/*
* Add FOR UPDATE/SHARE if appropriate. We apply locking during the
* initial row fetch, rather than later on as is done for local tables.
@@ -868,39 +922,16 @@ deparseLockingClause(StringInfo buf, PlannerInfo *root, RelOptInfo *rel)
}
/*
- * Deparse WHERE clauses in given list of RestrictInfos and append them to buf.
- *
- * baserel is the foreign table we're planning for.
- *
- * If no WHERE clause already exists in the buffer, is_first should be true.
- *
- * If params is not NULL, it receives a list of Params and other-relation Vars
- * used in the clauses; these values must be transmitted to the remote server
- * as parameter values.
- *
- * If params is NULL, we're generating the query for EXPLAIN purposes,
- * so Params and other-relation Vars should be replaced by dummy values.
+ * Deparse WHERE clauses in given list of RestrictInfos and append them to
+ * context->buf.
*/
-void
-appendWhereClause(StringInfo buf,
- PlannerInfo *root,
- RelOptInfo *baserel,
- List *exprs,
- bool is_first,
- List **params)
+static void
+appendWhereClause(List *exprs, deparse_expr_cxt *context)
{
- deparse_expr_cxt context;
int nestlevel;
ListCell *lc;
-
- if (params)
- *params = NIL; /* initialize result list to empty */
-
- /* Set up context struct for recursion */
- context.root = root;
- context.foreignrel = baserel;
- context.buf = buf;
- context.params_list = params;
+ bool is_first = true;
+ StringInfo buf = context->buf;
/* Make sure any constants in the exprs are printed portably */
nestlevel = set_transmission_modes();
@@ -916,7 +947,7 @@ appendWhereClause(StringInfo buf,
appendStringInfoString(buf, " AND ");
appendStringInfoChar(buf, '(');
- deparseExpr(ri->clause, &context);
+ deparseExpr(ri->clause, context);
appendStringInfoChar(buf, ')');
is_first = false;
@@ -1946,20 +1977,14 @@ printRemotePlaceholder(Oid paramtype, int32 paramtypmod,
* relation. From given pathkeys expressions belonging entirely to the given
* base relation are obtained and deparsed.
*/
-void
-appendOrderByClause(StringInfo buf, PlannerInfo *root, RelOptInfo *baserel,
- List *pathkeys)
+static void
+appendOrderByClause(List *pathkeys, deparse_expr_cxt *context)
{
ListCell *lcell;
- deparse_expr_cxt context;
int nestlevel;
char *delim = " ";
-
- /* Set up context struct for recursion */
- context.root = root;
- context.foreignrel = baserel;
- context.buf = buf;
- context.params_list = NULL;
+ RelOptInfo *baserel = context->foreignrel;
+ StringInfo buf = context->buf;
/* Make sure any constants in the exprs are printed portably */
nestlevel = set_transmission_modes();
@@ -1974,7 +1999,7 @@ appendOrderByClause(StringInfo buf, PlannerInfo *root, RelOptInfo *baserel,
Assert(em_expr != NULL);
appendStringInfoString(buf, delim);
- deparseExpr(em_expr, &context);
+ deparseExpr(em_expr, context);
if (pathkey->pk_strategy == BTLessStrategyNumber)
appendStringInfoString(buf, " ASC");
else