From c86c7e7fb5112ae7e95704ae8f687f50f78da29c Mon Sep 17 00:00:00 2001 From: amitlan Date: Mon, 19 Oct 2020 17:17:33 +0900 Subject: [PATCH v2 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