diff options
author | Robert Haas <rhaas@postgresql.org> | 2018-05-01 13:21:46 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2018-05-01 13:21:46 -0400 |
commit | 37a3058bc7c8224d4c0d8b36176d821636a1f90e (patch) | |
tree | 1410ad72fa6d03214b0354a904a75b283c22998a /src/backend/executor/nodeModifyTable.c | |
parent | 6594ee280383b7548b006e7f96c8d06137fced57 (diff) | |
download | postgresql-37a3058bc7c8224d4c0d8b36176d821636a1f90e.tar.gz postgresql-37a3058bc7c8224d4c0d8b36176d821636a1f90e.zip |
Fix interaction of foreign tuple routing with remote triggers.
Without these fixes, changes to the inserted tuple made by remote
triggers are ignored when building local RETURNING tuples.
In the core code, call ExecInitRoutingInfo at a later point from
within ExecInitPartitionInfo so that the FDW callback gets invoked
after the returning list has been built. But move CheckValidResultRel
out of ExecInitRoutingInfo so that it can happen at an earlier stage.
In postgres_fdw, refactor assorted deparsing functions to work with
the RTE rather than the PlannerInfo, which saves us having to
construct a fake PlannerInfo in cases where we don't have a real one.
Then, we can pass down a constructed RTE that yields the correct
deparse result when no real one exists. Unfortunately, this
necessitates a hack that understands how the core code manages RT
indexes for update tuple routing, which is ugly, but we don't have a
better idea right now.
Original report, analysis, and patch by Etsuro Fujita. Heavily
refactored by me. Then worked over some more by Amit Langote.
Discussion: http://postgr.es/m/5AD4882B.10002@lab.ntt.co.jp
Diffstat (limited to 'src/backend/executor/nodeModifyTable.c')
-rw-r--r-- | src/backend/executor/nodeModifyTable.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index f6482f8411b..71314e73bcf 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1700,20 +1700,24 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate, partidx); /* - * 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). + * Check whether the partition is routable if we didn't yet * * 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 + * tuple to a new partition. This check would be applied to 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 + * the tuple to. The reason we do this check 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) + { + /* Verify the partition is a valid target for INSERT. */ + CheckValidResultRel(partrel, CMD_INSERT); + + /* Set up information needed for routing tuples to the partition. */ ExecInitRoutingInfo(mtstate, estate, proute, partrel, partidx); + } /* * Make it look like we are inserting into the partition. |