Remove new structure member from ResultRelInfo.
authorEtsuro Fujita <[email protected]>
Thu, 8 Dec 2022 07:15:00 +0000 (16:15 +0900)
committerEtsuro Fujita <[email protected]>
Thu, 8 Dec 2022 07:15:00 +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 872b879387bc3168befc1761992a19ef7e0773be..2c2b3a887468b867e76ce13a794b110d3775db49 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 88d0ea3adb1fae26f24ed887398e544e4c51ebbf..76d79b9741ff3541c1fc28f56231d476a879e22a 100644 (file)
@@ -1029,13 +1029,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 e296f44ebd957d7b87c706a69306bc4d2e67165a..87f4d53ca760b15383bfe9512a2157d57a09cd7d 100644 (file)
@@ -130,9 +130,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 a3988b117543a19710868348cbb79ed093655ca8..596b9a1efad48ea2dbf32901419185e5c625505c 100644 (file)
@@ -858,10 +858,12 @@ ExecInsert(ModifyTableContext *context,
 
                        /*
                         * 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)
                        {
@@ -870,6 +872,8 @@ ExecInsert(ModifyTableContext *context,
                                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));
@@ -1219,12 +1223,14 @@ ExecBatchInsert(ModifyTableState *mtstate,
 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,
@@ -1236,7 +1242,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;
 }
 
 /*
@@ -4342,13 +4350,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 08ad9d6be3f3d5b020b58e928f9d9b8b17cd2586..9a64a830a288f694967bdf62b5ad174e7af4edb5 100644 (file)
@@ -575,9 +575,6 @@ typedef struct ResultRelInfo
         * one of its ancestors; see ExecCrossPartitionUpdateForeignKey().
         */
        List       *ri_ancestorResultRels;
-
-       /* for use by nodeModifyTable.c when performing batch-inserts */
-       struct ModifyTableState *ri_ModifyTableState;
 } ResultRelInfo;
 
 /* ----------------
@@ -703,10 +700,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;