v10-0001-Set-ForeignScanState.resultRelInfo-lazily.patch
application/octet-stream
Filename: v10-0001-Set-ForeignScanState.resultRelInfo-lazily.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v10-0001
Subject: Set ForeignScanState.resultRelInfo lazily
| File | + | − |
|---|---|---|
| doc/src/sgml/fdwhandler.sgml | 4 | 3 |
| src/backend/executor/nodeForeignscan.c | 28 | 11 |
From 84c124caf06216eef944d57517311f389968b01d Mon Sep 17 00:00:00 2001
From: amitlan <amitlangote09@gmail.com>
Date: Mon, 19 Oct 2020 17:17:33 +0900
Subject: [PATCH v10 1/3] Set ForeignScanState.resultRelInfo lazily
Instead of doing it in ExecInitForeignScan(), do it on the first
ForeignNext() call. This also moves the BeginDirectModify() call
into ForeignNext().
This is in preparation of a later commit to make ModifyTable node
initialize ResultRelInfos lazily, that is as it begins executing,
instead of in ExecInitModifyTable().
---
doc/src/sgml/fdwhandler.sgml | 7 +++---
src/backend/executor/nodeForeignscan.c | 39 ++++++++++++++++++++++++----------
2 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml
index 9c92934..b1d7c84 100644
--- a/doc/src/sgml/fdwhandler.sgml
+++ b/doc/src/sgml/fdwhandler.sgml
@@ -890,9 +890,10 @@ BeginDirectModify(ForeignScanState *node,
</programlisting>
Prepare to execute a direct modification on the remote server.
- This is called during executor startup. It should perform any
- initialization needed prior to the direct modification (that should be
- done upon the first call to <function>IterateDirectModify</function>).
+ This is called right before the first time <function>IterateDirectModify</function>
+ is called on the node. It should perform any initialization needed prior to the
+ direct modification (that should be done upon the first call to
+ <function>IterateDirectModify</function>).
The <structname>ForeignScanState</structname> node has already been created, but
its <structfield>fdw_state</structfield> field is still NULL. Information about
the table to modify is accessible through the
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c
index 0b20f94..5259abf 100644
--- a/src/backend/executor/nodeForeignscan.c
+++ b/src/backend/executor/nodeForeignscan.c
@@ -49,7 +49,31 @@ ForeignNext(ForeignScanState *node)
/* Call the Iterate function in short-lived context */
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
if (plan->operation != CMD_SELECT)
+ {
+ /*
+ * For FDW's convenience, look up the result relation info and set
+ * ForeignScanState.resultRelInfo if not already done. This is also
+ * a good time to call BeginDirectModify().
+ */
+ Assert(plan->resultRelation > 0);
+ if (node->resultRelInfo == NULL)
+ {
+ EState *estate = node->ss.ps.state;
+ ResultRelInfo *rInfo = estate->es_result_relations[plan->resultRelation - 1];
+
+ /* ExecInitModifyTable() must have initialized one already. */
+ Assert(rInfo != NULL);
+ node->resultRelInfo = rInfo;
+
+ oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
+ Assert(rInfo->ri_FdwRoutine != NULL &&
+ rInfo->ri_FdwRoutine->BeginDirectModify != NULL);
+ rInfo->ri_FdwRoutine->BeginDirectModify(node,
+ estate->es_top_eflags);
+ MemoryContextSwitchTo(oldcontext);
+ }
slot = node->fdwroutine->IterateDirectModify(node);
+ }
else
slot = node->fdwroutine->IterateForeignScan(node);
MemoryContextSwitchTo(oldcontext);
@@ -215,24 +239,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, any
+ * additional initializations are performed right before calling
+ * IterateDirectModify() for the first time.
*/
- if (node->operation != CMD_SELECT)
- fdwroutine->BeginDirectModify(scanstate, eflags);
- else
+ if (node->operation == CMD_SELECT)
fdwroutine->BeginForeignScan(scanstate, eflags);
return scanstate;
--
1.8.3.1