aboutsummaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw/deparse.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-03-18 13:48:58 -0400
committerRobert Haas <rhaas@postgresql.org>2016-03-18 13:55:52 -0400
commit0bf3ae88af330496517722e391e7c975e6bad219 (patch)
tree46220c3ebfc9616af8d683c74395b18045c59a8a /contrib/postgres_fdw/deparse.c
parent3422fecccadb021b7b4cdbc73b2c29f66f031761 (diff)
downloadpostgresql-0bf3ae88af330496517722e391e7c975e6bad219.tar.gz
postgresql-0bf3ae88af330496517722e391e7c975e6bad219.zip
Directly modify foreign tables.
postgres_fdw can now sent an UPDATE or DELETE statement directly to the foreign server in simple cases, rather than sending a SELECT FOR UPDATE statement and then updating or deleting rows one-by-one. Etsuro Fujita, reviewed by Rushabh Lathia, Shigeru Hanada, Kyotaro Horiguchi, Albe Laurenz, Thom Brown, and me.
Diffstat (limited to 'contrib/postgres_fdw/deparse.c')
-rw-r--r--contrib/postgres_fdw/deparse.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index 17081e48bd1..d1c82597ec3 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -1315,6 +1315,69 @@ deparseUpdateSql(StringInfo buf, PlannerInfo *root,
}
/*
+ * deparse remote UPDATE statement
+ *
+ * The statement text is appended to buf, and we also create an integer List
+ * of the columns being retrieved by RETURNING (if any), which is returned
+ * to *retrieved_attrs.
+ */
+void
+deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root,
+ Index rtindex, Relation rel,
+ List *targetlist,
+ List *targetAttrs,
+ List *remote_conds,
+ List **params_list,
+ List *returningList,
+ List **retrieved_attrs)
+{
+ RelOptInfo *baserel = root->simple_rel_array[rtindex];
+ deparse_expr_cxt context;
+ int nestlevel;
+ bool first;
+ ListCell *lc;
+
+ /* Set up context struct for recursion */
+ context.root = root;
+ context.foreignrel = baserel;
+ context.buf = buf;
+ context.params_list = params_list;
+
+ appendStringInfoString(buf, "UPDATE ");
+ deparseRelation(buf, rel);
+ appendStringInfoString(buf, " SET ");
+
+ /* Make sure any constants in the exprs are printed portably */
+ nestlevel = set_transmission_modes();
+
+ first = true;
+ foreach(lc, targetAttrs)
+ {
+ int attnum = lfirst_int(lc);
+ TargetEntry *tle = get_tle_by_resno(targetlist, attnum);
+
+ if (!first)
+ appendStringInfoString(buf, ", ");
+ first = false;
+
+ deparseColumnRef(buf, rtindex, attnum, root, false);
+ appendStringInfoString(buf, " = ");
+ deparseExpr((Expr *) tle->expr, &context);
+ }
+
+ reset_transmission_modes(nestlevel);
+
+ if (remote_conds)
+ {
+ appendStringInfo(buf, " WHERE ");
+ appendConditions(remote_conds, &context);
+ }
+
+ deparseReturningList(buf, root, rtindex, rel, false,
+ returningList, retrieved_attrs);
+}
+
+/*
* deparse remote DELETE statement
*
* The statement text is appended to buf, and we also create an integer List
@@ -1337,6 +1400,43 @@ deparseDeleteSql(StringInfo buf, PlannerInfo *root,
}
/*
+ * deparse remote DELETE statement
+ *
+ * The statement text is appended to buf, and we also create an integer List
+ * of the columns being retrieved by RETURNING (if any), which is returned
+ * to *retrieved_attrs.
+ */
+void
+deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root,
+ Index rtindex, Relation rel,
+ List *remote_conds,
+ List **params_list,
+ List *returningList,
+ List **retrieved_attrs)
+{
+ RelOptInfo *baserel = root->simple_rel_array[rtindex];
+ deparse_expr_cxt context;
+
+ /* Set up context struct for recursion */
+ context.root = root;
+ context.foreignrel = baserel;
+ context.buf = buf;
+ context.params_list = params_list;
+
+ appendStringInfoString(buf, "DELETE FROM ");
+ deparseRelation(buf, rel);
+
+ if (remote_conds)
+ {
+ appendStringInfo(buf, " WHERE ");
+ appendConditions(remote_conds, &context);
+ }
+
+ deparseReturningList(buf, root, rtindex, rel, false,
+ returningList, retrieved_attrs);
+}
+
+/*
* Add a RETURNING clause, if needed, to an INSERT/UPDATE/DELETE.
*/
static void