Remove new structure member from ResultRelInfo.
authorEtsuro Fujita
Thu, 8 Dec 2022 07:15:03 +0000 (16:15 +0900)
committerEtsuro Fujita
Thu, 8 Dec 2022 07:15:03 +0000 (16:15 +0900)
In commit ffbb7e65a, I added a ModifyTableState member to ResultRelInfo
to save the owning ModifyTableState for use by nodeModifyTable.c when
performing batch inserts, but as pointed out by Tom Lane, that changed
the array stride of es_result_relations, and that would break any
previously-compiled extension code that accesses that array.  Fix by
removing that member from ResultRelInfo and instead adding a List member
at the end of EState to save such ModifyTableStates.

Per report from Tom Lane.  Back-patch to v14, like the previous commit;
I chose to apply the patch to HEAD as well, to make back-patching easy.

Discussion: http://postgr.es/m/4065383.1669395453%40sss.pgh.pa.us

src/backend/executor/execMain.c
src/backend/executor/execPartition.c
src/backend/executor/execUtils.c
src/backend/executor/nodeModifyTable.c
src/include/nodes/execnodes.h

index 83d21d612b143f1bfe044a2fb10db93699f49a71..b3ce4bae53078a2914ad54f7fad5061ff4271d76 100644 (file)
@@ -1257,7 +1257,6 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
    resultRelInfo->ri_ChildToRootMap = NULL;
    resultRelInfo->ri_ChildToRootMapValid = false;
    resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
-   resultRelInfo->ri_ModifyTableState = NULL;
 }
 
 /*
index 216da08d0cf811bcf0b5ce20a2ac7218b1b3129d..606c920b06805942a37e3616872ff44db0446e4c 100644 (file)
@@ -934,13 +934,6 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
 
    Assert(partRelInfo->ri_BatchSize >= 1);
 
-   /*
-    * If doing batch insert, setup back-link so we can easily find the
-    * mtstate again.
-    */
-   if (partRelInfo->ri_BatchSize > 1)
-       partRelInfo->ri_ModifyTableState = mtstate;
-
    partRelInfo->ri_CopyMultiInsertBuffer = NULL;
 
    /*
index 64a8c2e59312a8efdbc136cc27bbbfeb06177cd8..85f9c0817c22884b0729cafc8d48c99e938a24ed 100644 (file)
@@ -127,9 +127,11 @@ CreateExecutorState(void)
    estate->es_result_relations = NULL;
    estate->es_opened_result_relations = NIL;
    estate->es_tuple_routing_result_relations = NIL;
-   estate->es_insert_pending_result_relations = NIL;
    estate->es_trig_target_relations = NIL;
 
+   estate->es_insert_pending_result_relations = NIL;
+   estate->es_insert_pending_modifytables = NIL;
+
    estate->es_param_list_info = NULL;
    estate->es_param_exec_vals = NULL;
 
index ee0f04220408e0f0b7defdc370944ba94bac3e11..54cbe51febb2a9b1f6782f6197674ca379f9c7d7 100644 (file)
@@ -742,10 +742,12 @@ ExecInsert(ModifyTableState *mtstate,
 
            /*
             * If these are the first tuples stored in the buffers, add the
-            * target rel to the es_insert_pending_result_relations list,
-            * except in the case where flushing was done above, in which case
-            * the target rel would already have been added to the list, so no
-            * need to do this.
+            * target rel and the mtstate to the
+            * es_insert_pending_result_relations and
+            * es_insert_pending_modifytables lists respectively, execpt in
+            * the case where flushing was done above, in which case they
+            * would already have been added to the lists, so no need to do
+            * this.
             */
            if (resultRelInfo->ri_NumSlots == 0 && !flushed)
            {
@@ -754,6 +756,8 @@ ExecInsert(ModifyTableState *mtstate,
                estate->es_insert_pending_result_relations =
                    lappend(estate->es_insert_pending_result_relations,
                            resultRelInfo);
+               estate->es_insert_pending_modifytables =
+                   lappend(estate->es_insert_pending_modifytables, mtstate);
            }
            Assert(list_member_ptr(estate->es_insert_pending_result_relations,
                                   resultRelInfo));
@@ -1445,12 +1449,14 @@ ldelete:;
 static void
 ExecPendingInserts(EState *estate)
 {
-   ListCell   *lc;
+   ListCell   *l1,
+              *l2;
 
-   foreach(lc, estate->es_insert_pending_result_relations)
+   forboth(l1, estate->es_insert_pending_result_relations,
+           l2, estate->es_insert_pending_modifytables)
    {
-       ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(lc);
-       ModifyTableState *mtstate = resultRelInfo->ri_ModifyTableState;
+       ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l1);
+       ModifyTableState *mtstate = (ModifyTableState *) lfirst(l2);
 
        Assert(mtstate);
        ExecBatchInsert(mtstate, resultRelInfo,
@@ -1462,7 +1468,9 @@ ExecPendingInserts(EState *estate)
    }
 
    list_free(estate->es_insert_pending_result_relations);
+   list_free(estate->es_insert_pending_modifytables);
    estate->es_insert_pending_result_relations = NIL;
+   estate->es_insert_pending_modifytables = NIL;
 }
 
 /*
@@ -3183,13 +3191,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
        }
        else
            resultRelInfo->ri_BatchSize = 1;
-
-       /*
-        * If doing batch insert, setup back-link so we can easily find the
-        * mtstate again.
-        */
-       if (resultRelInfo->ri_BatchSize > 1)
-           resultRelInfo->ri_ModifyTableState = mtstate;
    }
 
    /*
index 71d0cf44dd55a2751580e512a9b72a6eb6166387..9a40a19303c92c8b7b22cb4afdbf5fbd191b9986 100644 (file)
@@ -524,9 +524,6 @@ typedef struct ResultRelInfo
 
    /* for use by copyfrom.c when performing multi-inserts */
    struct CopyMultiInsertBuffer *ri_CopyMultiInsertBuffer;
-
-   /* for use by nodeModifyTable.c when performing batch-inserts */
-   struct ModifyTableState *ri_ModifyTableState;
 } ResultRelInfo;
 
 /* ----------------
@@ -650,10 +647,11 @@ typedef struct EState
    struct JitInstrumentation *es_jit_worker_instr;
 
    /*
-    * The following list contains ResultRelInfos for foreign tables on which
-    * batch-inserts are to be executed.
+    * Lists of ResultRelInfos for foreign tables on which batch-inserts are
+    * to be executed and owning ModifyTableStates, stored in the same order.
     */
    List       *es_insert_pending_result_relations;
+   List       *es_insert_pending_modifytables;
 } EState;