aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeModifyTable.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2018-04-06 19:16:11 -0400
committerRobert Haas <rhaas@postgresql.org>2018-04-06 19:22:03 -0400
commit3d956d9562aa4811b5eaaaf5314d361c61be2ae0 (patch)
treebcc272ff028283ce7799b2900b0f6ca084b55feb /src/backend/executor/nodeModifyTable.c
parentcb1ff1e5af83f2c548fcb15596d474c198a021c5 (diff)
downloadpostgresql-3d956d9562aa4811b5eaaaf5314d361c61be2ae0.tar.gz
postgresql-3d956d9562aa4811b5eaaaf5314d361c61be2ae0.zip
Allow insert and update tuple routing and COPY for foreign tables.
Also enable this for postgres_fdw. Etsuro Fujita, based on an earlier patch by Amit Langote. The larger patch series of which this is a part has been reviewed by Amit Langote, David Fetter, Maksim Milyutin, Álvaro Herrera, Stephen Frost, and me. Minor documentation changes to the final version by me. Discussion: http://postgr.es/m/29906a26-da12-8c86-4fb9-d8f88442f2b9@lab.ntt.co.jp
Diffstat (limited to 'src/backend/executor/nodeModifyTable.c')
-rw-r--r--src/backend/executor/nodeModifyTable.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 0ebf37bd240..bf4c2bf6082 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -1826,11 +1826,21 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
proute, estate,
partidx);
- /* We do not yet have a way to insert into a foreign partition */
- if (partrel->ri_FdwRoutine)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot route inserted tuples to a foreign table")));
+ /*
+ * Set up information needed for routing tuples to the partition if we
+ * didn't yet (ExecInitRoutingInfo would abort the operation if the
+ * partition isn't routable).
+ *
+ * Note: an UPDATE of a partition key invokes an INSERT that moves the
+ * tuple to a new partition. This setup would be needed for a subplan
+ * partition of such an UPDATE that is chosen as the partition to route
+ * the tuple to. The reason we do this setup here rather than in
+ * ExecSetupPartitionTupleRouting is to avoid aborting such an UPDATE
+ * unnecessarily due to non-routable subplan partitions that may not be
+ * chosen for update tuple movement after all.
+ */
+ if (!partrel->ri_PartitionReadyForRouting)
+ ExecInitRoutingInfo(mtstate, estate, proute, partrel, partidx);
/*
* Make it look like we are inserting into the partition.
@@ -2531,6 +2541,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
{
List *rlist = (List *) lfirst(l);
+ resultRelInfo->ri_returningList = rlist;
resultRelInfo->ri_projectReturning =
ExecBuildProjectionInfo(rlist, econtext, slot, &mtstate->ps,
resultRelInfo->ri_RelationDesc->rd_att);
@@ -2830,7 +2841,7 @@ ExecEndModifyTable(ModifyTableState *node)
/* Close all the partitioned tables, leaf partitions, and their indices */
if (node->mt_partition_tuple_routing)
- ExecCleanupTupleRouting(node->mt_partition_tuple_routing);
+ ExecCleanupTupleRouting(node, node->mt_partition_tuple_routing);
/*
* Free the exprcontext