aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2018-05-16 11:32:38 -0400
committerRobert Haas <rhaas@postgresql.org>2018-05-16 11:32:38 -0400
commit7fc7dac1a711d0dbd01d2daf6dc97d27d6c6409c (patch)
treeb7d6b20978bc54bd81788f88c77d5db974869d46 /src
parent09b12d52db1cf1a4c72d876f3fb6c9d06919e51a (diff)
downloadpostgresql-7fc7dac1a711d0dbd01d2daf6dc97d27d6c6409c.tar.gz
postgresql-7fc7dac1a711d0dbd01d2daf6dc97d27d6c6409c.zip
Pass the correct PlannerInfo to PlanForeignModify/PlanDirectModify.
Previously, we passed the toplevel PlannerInfo, but we actually want to pass the relevant subroot. One problem with passing the toplevel PlannerInfo is that the FDW which wants to push down an UPDATE or DELETE against a join won't find the relevant joinrel there. As of commit 1bc0100d270e5bcc980a0629b8726a32a497e788, postgres_fdw tries to do exactly this and can be made to fail an assertion as a result. It's possible that this should be regarded as a bug fix and back-patched to earlier releases, but for lack of a test case that fails in earlier releases, no back-patch for now. Etsuro Fujita, reviewed by Amit Langote. Discussion: http://postgr.es/m/5AF43E02.30000@lab.ntt.co.jp
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/plan/createplan.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 0317763f43c..ca2e0527dbc 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -289,7 +289,7 @@ static ModifyTable *make_modifytable(PlannerInfo *root,
CmdType operation, bool canSetTag,
Index nominalRelation, List *partitioned_rels,
bool partColsUpdated,
- List *resultRelations, List *subplans,
+ List *resultRelations, List *subplans, List *subroots,
List *withCheckOptionLists, List *returningLists,
List *rowMarks, OnConflictExpr *onconflict, int epqParam);
static GatherMerge *create_gather_merge_plan(PlannerInfo *root,
@@ -2484,6 +2484,7 @@ create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path)
best_path->partColsUpdated,
best_path->resultRelations,
subplans,
+ best_path->subroots,
best_path->withCheckOptionLists,
best_path->returningLists,
best_path->rowMarks,
@@ -6558,7 +6559,7 @@ make_modifytable(PlannerInfo *root,
CmdType operation, bool canSetTag,
Index nominalRelation, List *partitioned_rels,
bool partColsUpdated,
- List *resultRelations, List *subplans,
+ List *resultRelations, List *subplans, List *subroots,
List *withCheckOptionLists, List *returningLists,
List *rowMarks, OnConflictExpr *onconflict, int epqParam)
{
@@ -6566,9 +6567,11 @@ make_modifytable(PlannerInfo *root,
List *fdw_private_list;
Bitmapset *direct_modify_plans;
ListCell *lc;
+ ListCell *lc2;
int i;
Assert(list_length(resultRelations) == list_length(subplans));
+ Assert(list_length(resultRelations) == list_length(subroots));
Assert(withCheckOptionLists == NIL ||
list_length(resultRelations) == list_length(withCheckOptionLists));
Assert(returningLists == NIL ||
@@ -6627,9 +6630,10 @@ make_modifytable(PlannerInfo *root,
fdw_private_list = NIL;
direct_modify_plans = NULL;
i = 0;
- foreach(lc, resultRelations)
+ forboth(lc, resultRelations, lc2, subroots)
{
Index rti = lfirst_int(lc);
+ PlannerInfo *subroot = lfirst_node(PlannerInfo, lc2);
FdwRoutine *fdwroutine;
List *fdw_private;
bool direct_modify;
@@ -6641,16 +6645,16 @@ make_modifytable(PlannerInfo *root,
* so it's not a baserel; and there are also corner cases for
* updatable views where the target rel isn't a baserel.)
*/
- if (rti < root->simple_rel_array_size &&
- root->simple_rel_array[rti] != NULL)
+ if (rti < subroot->simple_rel_array_size &&
+ subroot->simple_rel_array[rti] != NULL)
{
- RelOptInfo *resultRel = root->simple_rel_array[rti];
+ RelOptInfo *resultRel = subroot->simple_rel_array[rti];
fdwroutine = resultRel->fdwroutine;
}
else
{
- RangeTblEntry *rte = planner_rt_fetch(rti, root);
+ RangeTblEntry *rte = planner_rt_fetch(rti, subroot);
Assert(rte->rtekind == RTE_RELATION);
if (rte->relkind == RELKIND_FOREIGN_TABLE)
@@ -6672,15 +6676,15 @@ make_modifytable(PlannerInfo *root,
fdwroutine->IterateDirectModify != NULL &&
fdwroutine->EndDirectModify != NULL &&
withCheckOptionLists == NIL &&
- !has_row_triggers(root, rti, operation))
- direct_modify = fdwroutine->PlanDirectModify(root, node, rti, i);
+ !has_row_triggers(subroot, rti, operation))
+ direct_modify = fdwroutine->PlanDirectModify(subroot, node, rti, i);
if (direct_modify)
direct_modify_plans = bms_add_member(direct_modify_plans, i);
if (!direct_modify &&
fdwroutine != NULL &&
fdwroutine->PlanForeignModify != NULL)
- fdw_private = fdwroutine->PlanForeignModify(root, node, rti, i);
+ fdw_private = fdwroutine->PlanForeignModify(subroot, node, rti, i);
else
fdw_private = NIL;
fdw_private_list = lappend(fdw_private_list, fdw_private);