aboutsummaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rewriteHandler.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-03-10 14:14:53 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2013-03-10 14:16:02 -0400
commit21734d2fb896e0ecdddd3251caa72a3576e2d415 (patch)
treeaed4ee5509e618c0fd9746c8be17c5bf23a08a3f /src/backend/rewrite/rewriteHandler.c
parent7f49a67f954db3e92fd96963169fb8302959576e (diff)
downloadpostgresql-21734d2fb896e0ecdddd3251caa72a3576e2d415.tar.gz
postgresql-21734d2fb896e0ecdddd3251caa72a3576e2d415.zip
Support writable foreign tables.
This patch adds the core-system infrastructure needed to support updates on foreign tables, and extends contrib/postgres_fdw to allow updates against remote Postgres servers. There's still a great deal of room for improvement in optimization of remote updates, but at least there's basic functionality there now. KaiGai Kohei, reviewed by Alexander Korotkov and Laurenz Albe, and rather heavily revised by Tom Lane.
Diffstat (limited to 'src/backend/rewrite/rewriteHandler.c')
-rw-r--r--src/backend/rewrite/rewriteHandler.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 83c83a6a8a4..b99b9930d6a 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -16,6 +16,7 @@
#include "access/sysattr.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
+#include "foreign/fdwapi.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "parser/analyze.h"
@@ -1156,6 +1157,7 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos)
* is a regular table, the junk TLE emits the ctid attribute of the original
* row. When the target relation is a view, there is no ctid, so we instead
* emit a whole-row Var that will contain the "old" values of the view row.
+ * If it's a foreign table, we let the FDW decide what to add.
*
* For UPDATE queries, this is applied after rewriteTargetListIU. The
* ordering isn't actually critical at the moment.
@@ -1183,6 +1185,21 @@ rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
attrname = "ctid";
}
+ else if (target_relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ {
+ /*
+ * Let the foreign table's FDW add whatever junk TLEs it wants.
+ */
+ FdwRoutine *fdwroutine;
+
+ fdwroutine = GetFdwRoutineForRelation(target_relation, false);
+
+ if (fdwroutine->AddForeignUpdateTargets != NULL)
+ fdwroutine->AddForeignUpdateTargets(parsetree, target_rte,
+ target_relation);
+
+ return;
+ }
else
{
/*
@@ -1444,17 +1461,13 @@ markQueryForLocking(Query *qry, Node *jtnode,
if (rte->rtekind == RTE_RELATION)
{
- /* ignore foreign tables */
- if (rte->relkind != RELKIND_FOREIGN_TABLE)
- {
- applyLockingClause(qry, rti, strength, noWait, pushedDown);
- rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
- }
+ applyLockingClause(qry, rti, strength, noWait, pushedDown);
+ rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
}
else if (rte->rtekind == RTE_SUBQUERY)
{
applyLockingClause(qry, rti, strength, noWait, pushedDown);
- /* FOR [KEY] UPDATE/SHARE of subquery is propagated to subquery's rels */
+ /* FOR UPDATE/SHARE of subquery is propagated to subquery's rels */
markQueryForLocking(rte->subquery, (Node *) rte->subquery->jointree,
strength, noWait, true);
}