Seems to me it should, at least conditionally.  At least if there's a function
scan or a relation or ..

I mentioned a bit about our use-case here:
https://www.postgresql.org/message-id/20200219173742.GA30939%40telsasoft.com
=> I'd prefer our loaders to write their own data rather than dirtying large
fractions of buffer cache and leaving it around for other backends to clean up.

commit 7f9e061363e58f30eee0cccc8a0e46f637bf137b
Author: Justin Pryzby <pryz...@telsasoft.com>
Date:   Fri May 8 02:17:32 2020 -0500

    Make INSERT SELECT use a BulkInsertState

diff --git a/src/backend/executor/nodeModifyTable.c 
b/src/backend/executor/nodeModifyTable.c
index 20a4c474cc..6da4325225 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -578,7 +578,7 @@ ExecInsert(ModifyTableState *mtstate,
                        table_tuple_insert_speculative(resultRelationDesc, slot,
                                                                                
   estate->es_output_cid,
                                                                                
   0,
-                                                                               
   NULL,
+                                                                               
   mtstate->bistate,
                                                                                
   specToken);
 
                        /* insert index entries for tuple */
@@ -617,7 +617,7 @@ ExecInsert(ModifyTableState *mtstate,
                        /* insert the tuple normally */
                        table_tuple_insert(resultRelationDesc, slot,
                                                           
estate->es_output_cid,
-                                                          0, NULL);
+                                                          0, mtstate->bistate);
 
                        /* insert index entries for tuple */
                        if (resultRelInfo->ri_NumIndices > 0)
@@ -2332,6 +2332,14 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, 
int eflags)
 
        mtstate->mt_arowmarks = (List **) palloc0(sizeof(List *) * nplans);
        mtstate->mt_nplans = nplans;
+       mtstate->bistate = NULL;
+       if (operation == CMD_INSERT)
+       {
+               Plan *p = linitial(node->plans);
+               Assert(nplans == 1);
+               if (!IsA(p, Result) && !IsA(p, ValuesScan))
+                       mtstate->bistate = GetBulkInsertState();
+       }
 
        /* set up epqstate with dummy subplan data for the moment */
        EvalPlanQualInit(&mtstate->mt_epqstate, estate, NULL, NIL, 
node->epqParam);
@@ -2809,6 +2817,9 @@ ExecEndModifyTable(ModifyTableState *node)
         */
        for (i = 0; i < node->mt_nplans; i++)
                ExecEndNode(node->mt_plans[i]);
+
+       if (node->bistate)
+               FreeBulkInsertState(node->bistate);
 }
 
 void
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 4fee043bb2..daf365f181 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -14,6 +14,7 @@
 #ifndef EXECNODES_H
 #define EXECNODES_H
 
+#include "access/heapam.h"
 #include "access/tupconvert.h"
 #include "executor/instrument.h"
 #include "fmgr.h"
@@ -1177,6 +1178,7 @@ typedef struct ModifyTableState
        List      **mt_arowmarks;       /* per-subplan ExecAuxRowMark lists */
        EPQState        mt_epqstate;    /* for evaluating EvalPlanQual rechecks 
*/
        bool            fireBSTriggers; /* do we need to fire stmt triggers? */
+       BulkInsertState bistate;        /* State for bulk insert like INSERT 
SELECT */
 
        /*
         * Slot for storing tuples in the root partitioned table's rowtype 
during


Reply via email to