From 0bf3ae88af330496517722e391e7c975e6bad219 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 18 Mar 2016 13:48:58 -0400 Subject: 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. --- src/backend/optimizer/plan/createplan.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/backend/optimizer/plan/createplan.c') 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; } -- cgit v1.2.3