diff options
author | Robert Haas <rhaas@postgresql.org> | 2016-03-18 13:48:58 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2016-03-18 13:55:52 -0400 |
commit | 0bf3ae88af330496517722e391e7c975e6bad219 (patch) | |
tree | 46220c3ebfc9616af8d683c74395b18045c59a8a /src/backend/optimizer/plan/createplan.c | |
parent | 3422fecccadb021b7b4cdbc73b2c29f66f031761 (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.c | 21 |
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; } |