summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-03-18 13:48:58 -0400
committerRobert Haas <rhaas@postgresql.org>2016-03-18 13:55:52 -0400
commit0bf3ae88af330496517722e391e7c975e6bad219 (patch)
tree46220c3ebfc9616af8d683c74395b18045c59a8a /src/backend/optimizer/plan/createplan.c
parent3422fecccadb021b7b4cdbc73b2c29f66f031761 (diff)
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 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index f08f0ea01f6..087cb9c4419 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -4906,6 +4906,7 @@ make_foreignscan(List *qptlist,
plan->lefttree = outer_plan;
plan->righttree = NULL;
node->scan.scanrelid = scanrelid;
+ node->operation = CMD_SELECT;
/* fs_server will be filled in by create_foreignscan_plan */
node->fs_server = InvalidOid;
node->fdw_exprs = fdw_exprs;
@@ -6021,6 +6022,7 @@ make_modifytable(PlannerInfo *root,
{
ModifyTable *node = makeNode(ModifyTable);
List *fdw_private_list;
+ Bitmapset *direct_modify_plans;
ListCell *lc;
int i;
@@ -6078,12 +6080,14 @@ make_modifytable(PlannerInfo *root,
* construct private plan data, and accumulate it all into a list.
*/
fdw_private_list = NIL;
+ direct_modify_plans = NULL;
i = 0;
foreach(lc, resultRelations)
{
Index rti = lfirst_int(lc);
FdwRoutine *fdwroutine;
List *fdw_private;
+ bool direct_modify;
/*
* If possible, we want to get the FdwRoutine from our RelOptInfo for
@@ -6110,7 +6114,23 @@ make_modifytable(PlannerInfo *root,
fdwroutine = NULL;
}
+ /*
+ * If the target foreign table has any row-level triggers, we can't
+ * modify the foreign table directly.
+ */
+ direct_modify = false;
if (fdwroutine != NULL &&
+ fdwroutine->PlanDirectModify != NULL &&
+ fdwroutine->BeginDirectModify != NULL &&
+ fdwroutine->IterateDirectModify != NULL &&
+ fdwroutine->EndDirectModify != NULL &&
+ !has_row_triggers(root, rti, operation))
+ direct_modify = fdwroutine->PlanDirectModify(root, 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);
else
@@ -6119,6 +6139,7 @@ make_modifytable(PlannerInfo *root,
i++;
}
node->fdwPrivLists = fdw_private_list;
+ node->fdwDirectModifyPlans = direct_modify_plans;
return node;
}