]> granicus.if.org Git - postgresql/commitdiff
Allow custom and foreign scans to have shutdown callbacks.
authorRobert Haas <rhaas@postgresql.org>
Sun, 26 Feb 2017 08:06:49 +0000 (13:36 +0530)
committerRobert Haas <rhaas@postgresql.org>
Sun, 26 Feb 2017 08:11:12 +0000 (13:41 +0530)
This is expected to be useful mostly when performing such scans in
parallel, because in that case it allows (in combination with commit
acf555bc53acb589b5a2827e65d655fa8c9adee0) nodes below a Gather to get
control just before the DSM segment goes away.

KaiGai Kohei, except that I rewrote the documentation.  Reviewed by
Claudio Freire.

Discussion: http://postgr.es/m/CADyhKSXJK0jUJ8rWv4AmKDhsUh124_rEn39eqgfC5D8fu6xVuw@mail.gmail.com

doc/src/sgml/custom-scan.sgml
doc/src/sgml/fdwhandler.sgml
src/backend/executor/execProcnode.c
src/backend/executor/nodeCustom.c
src/backend/executor/nodeForeignscan.c
src/include/executor/nodeCustom.h
src/include/executor/nodeForeignscan.h
src/include/foreign/fdwapi.h
src/include/nodes/extensible.h

index 1ca9247124583f5957d2af2623f0892b414de826..6159c3a24ebf09cfe0e96bf9d56534d459628020 100644 (file)
@@ -340,6 +340,19 @@ void (*InitializeWorkerCustomScan) (CustomScanState *node,
 
    <para>
 <programlisting>
+void (*ShutdownCustomScan) (CustomScanState *node);
+</programlisting>
+    Release resources when it is anticipated the node will not be executed
+    to completion.  This is not called in all cases; sometimes,
+    <literal>EndCustomScan</> may be called without this function having
+    been called first.  Since the DSM segment used by parallel query is
+    destroyed just after this callback is invoked, custom scan providers that
+    wish to take some action before the DSM segment goes away should implement
+    this method.
+   </para>
+
+   <para>
+<programlisting>
 void (*ExplainCustomScan) (CustomScanState *node,
                            List *ancestors,
                            ExplainState *es);
index 0c1db070ed88657965c02e16d611e3dc258fa371..dbeaab555db6775624d05a297c4174fcc62292e8 100644 (file)
@@ -1254,6 +1254,20 @@ InitializeWorkerForeignScan(ForeignScanState *node, shm_toc *toc,
     This callback is optional, and needs only be supplied if this
     custom path supports parallel execution.
    </para>
+
+   <para>
+<programlisting>
+void
+ShutdownForeignScan(ForeignScanState *node);
+</programlisting>
+    Release resources when it is anticipated the node will not be executed
+    to completion.  This is not called in all cases; sometimes,
+    <literal>EndForeignScan</> may be called without this function having
+    been called first.  Since the DSM segment used by parallel query is
+    destroyed just after this callback is invoked, foreign data wrappers that
+    wish to take some action before the DSM segment goes away should implement
+    this method.
+   </para>
    </sect2>
 
    </sect1>
index 5ccc2e846dc981b4c9bd27e869e50de3db297e48..ef6f35a5a0b0f7f717d0b9bc8f026e650cde005b 100644 (file)
@@ -822,6 +822,12 @@ ExecShutdownNode(PlanState *node)
                case T_GatherState:
                        ExecShutdownGather((GatherState *) node);
                        break;
+               case T_ForeignScanState:
+                       ExecShutdownForeignScan((ForeignScanState *) node);
+                       break;
+               case T_CustomScanState:
+                       ExecShutdownCustomScan((CustomScanState *) node);
+                       break;
                default:
                        break;
        }
index 16343a56df73fa5d83c2359786e03e083007cd8e..d4647482905bb692f7d84541aab6c90e47328ffb 100644 (file)
@@ -202,3 +202,12 @@ ExecCustomScanInitializeWorker(CustomScanState *node, shm_toc *toc)
                methods->InitializeWorkerCustomScan(node, toc, coordinate);
        }
 }
+
+void
+ExecShutdownCustomScan(CustomScanState *node)
+{
+       const CustomExecMethods *methods = node->methods;
+
+       if (methods->ShutdownCustomScan)
+               methods->ShutdownCustomScan(node);
+}
index 86a77e356c02a250048f6d748fbf20c60ee1c33b..3b6d1390eb41285444a6daa55080984eabace7b9 100644 (file)
@@ -353,3 +353,19 @@ ExecForeignScanInitializeWorker(ForeignScanState *node, shm_toc *toc)
                fdwroutine->InitializeWorkerForeignScan(node, toc, coordinate);
        }
 }
+
+/* ----------------------------------------------------------------
+ *             ExecShutdownForeignScan
+ *
+ *             Gives FDW chance to stop asynchronous resource consumption
+ *             and release any resources still held.
+ * ----------------------------------------------------------------
+ */
+void
+ExecShutdownForeignScan(ForeignScanState *node)
+{
+       FdwRoutine *fdwroutine = node->fdwroutine;
+
+       if (fdwroutine->ShutdownForeignScan)
+               fdwroutine->ShutdownForeignScan(node);
+}
index 19d5d047b5cd924749f8532a0ef158ae9f54ad0c..c2f2ca1eede4cea3f811e206dee15272bdf568a4 100644 (file)
@@ -37,5 +37,6 @@ extern void ExecCustomScanInitializeDSM(CustomScanState *node,
                                                        ParallelContext *pcxt);
 extern void ExecCustomScanInitializeWorker(CustomScanState *node,
                                                           shm_toc *toc);
+extern void ExecShutdownCustomScan(CustomScanState *node);
 
 #endif   /* NODECUSTOM_H */
index f0e942a8bcb26fddb41ec921ece2fd1cd595d827..1b167b8143ab201ab9699d87645cdcefd050b79e 100644 (file)
@@ -28,5 +28,6 @@ extern void ExecForeignScanInitializeDSM(ForeignScanState *node,
                                                         ParallelContext *pcxt);
 extern void ExecForeignScanInitializeWorker(ForeignScanState *node,
                                                                shm_toc *toc);
+extern void ExecShutdownForeignScan(ForeignScanState *node);
 
 #endif   /* NODEFOREIGNSCAN_H */
index 523d4155756dfe8827ceb968a95d12e8b5422c9c..6ca44f734f96c682bafc473dc11e87c22b5ff45b 100644 (file)
@@ -151,6 +151,7 @@ typedef void (*InitializeDSMForeignScan_function) (ForeignScanState *node,
 typedef void (*InitializeWorkerForeignScan_function) (ForeignScanState *node,
                                                                                                                                shm_toc *toc,
                                                                                                                   void *coordinate);
+typedef void (*ShutdownForeignScan_function) (ForeignScanState *node);
 typedef bool (*IsForeignScanParallelSafe_function) (PlannerInfo *root,
                                                                                                                         RelOptInfo *rel,
                                                                                                                 RangeTblEntry *rte);
@@ -224,6 +225,7 @@ typedef struct FdwRoutine
        EstimateDSMForeignScan_function EstimateDSMForeignScan;
        InitializeDSMForeignScan_function InitializeDSMForeignScan;
        InitializeWorkerForeignScan_function InitializeWorkerForeignScan;
+       ShutdownForeignScan_function ShutdownForeignScan;
 } FdwRoutine;
 
 
index 7e860b0dca72ee2788104a891007510896b5ffb7..0b02cc18e99cfb2445abdd8571cf58da5eeb357e 100644 (file)
@@ -139,6 +139,7 @@ typedef struct CustomExecMethods
        void            (*InitializeWorkerCustomScan) (CustomScanState *node,
                                                                                                                   shm_toc *toc,
                                                                                                                   void *coordinate);
+       void            (*ShutdownCustomScan) (CustomScanState *node);
 
        /* Optional: print additional information in EXPLAIN */
        void            (*ExplainCustomScan) (CustomScanState *node,