From 9cbf2b6c67671bfd73f1cfcb0695ddcc0f435b87 Mon Sep 17 00:00:00 2001 From: amitlan Date: Mon, 19 Oct 2020 17:17:33 +0900 Subject: [PATCH v7 1/2] Call BeginDirectModify from ExecInitModifyTable This allows ModifyTable to directly install the target foreign table's ResultRelInfo into the ForeignScanState node that will be used to perform the "direct modify" operation rather than have ExecInitForeignScan() do it by getting it via es_result_relations. This is in preparation of a later commit to make ModifyTable node initialize ResultRelInfos lazily, whereby accessing a given target table's ResultRelInfo directly through es_result_relations while the ModifyTable is executing will become a deprecated pattern. --- src/backend/executor/nodeForeignscan.c | 15 ++++----------- src/backend/executor/nodeModifyTable.c | 32 +++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index 0b20f94..7101c68 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -215,24 +215,17 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) scanstate->fdwroutine = fdwroutine; scanstate->fdw_state = NULL; - /* - * For the FDW's convenience, look up the modification target relation's. - * ResultRelInfo. - */ - if (node->resultRelation > 0) - scanstate->resultRelInfo = estate->es_result_relations[node->resultRelation - 1]; - /* Initialize any outer plan. */ if (outerPlan(node)) outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags); /* - * Tell the FDW to initialize the scan. + * Tell the FDW to initialize the scan. For modify operations, it's the + * enclosing ModifyTable node's job to call the FDW after setting up the + * target foreign table's ResultRelInfo. */ - if (node->operation != CMD_SELECT) - fdwroutine->BeginDirectModify(scanstate, eflags); - else + if (node->operation == CMD_SELECT) fdwroutine->BeginForeignScan(scanstate, eflags); return scanstate; diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 29e07b7..05e68ef 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -2306,17 +2306,31 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) table_slot_callbacks(resultRelInfo->ri_RelationDesc)); /* Also let FDWs init themselves for foreign-table result rels */ - if (!resultRelInfo->ri_usesFdwDirectModify && - resultRelInfo->ri_FdwRoutine != NULL && - resultRelInfo->ri_FdwRoutine->BeginForeignModify != NULL) + if (resultRelInfo->ri_FdwRoutine != NULL) { - List *fdw_private = (List *) list_nth(node->fdwPrivLists, i); + if (resultRelInfo->ri_usesFdwDirectModify) + { + ForeignScanState *fscan = (ForeignScanState *) mtstate->mt_plans[i]; - resultRelInfo->ri_FdwRoutine->BeginForeignModify(mtstate, - resultRelInfo, - fdw_private, - i, - eflags); + /* + * For the FDW's convenience, set the ForeignScanState node's + * ResultRelInfo to let the FDW know which result relation it + * is going to work with. + */ + Assert(IsA(fscan, ForeignScanState)); + fscan->resultRelInfo = resultRelInfo; + resultRelInfo->ri_FdwRoutine->BeginDirectModify(fscan, eflags); + } + else if (resultRelInfo->ri_FdwRoutine->BeginForeignModify != NULL) + { + List *fdw_private = (List *) list_nth(node->fdwPrivLists, i); + + resultRelInfo->ri_FdwRoutine->BeginForeignModify(mtstate, + resultRelInfo, + fdw_private, + i, + eflags); + } } /* -- 1.8.3.1