diff options
author | Robert Haas <rhaas@postgresql.org> | 2016-03-18 13:48:58 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2016-03-18 13:55:52 -0400 |
commit | 0bf3ae88af330496517722e391e7c975e6bad219 (patch) | |
tree | 46220c3ebfc9616af8d683c74395b18045c59a8a /contrib/postgres_fdw/deparse.c | |
parent | 3422fecccadb021b7b4cdbc73b2c29f66f031761 (diff) | |
download | postgresql-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.c | 100 |
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 |