Let table AM insertion methods control index insertion
authorAlexander Korotkov <[email protected]>
Sat, 30 Mar 2024 20:39:03 +0000 (22:39 +0200)
committerAlexander Korotkov <[email protected]>
Sat, 30 Mar 2024 20:53:56 +0000 (22:53 +0200)
Previously, the executor did index insert unconditionally after calling
table AM interface methods tuple_insert() and multi_insert().  This commit
introduces the new parameter insert_indexes for these two methods.  Setting
'*insert_indexes' to true saves the current logic.  Setting it to false
indicates that table AM cares about index inserts itself and doesn't want the
caller to do that.

Discussion: https://postgr.es/m/CAPpHfdurb9ycV8udYqM%3Do0sPS66PJ4RCBM1g-bBpvzUfogY0EA%40mail.gmail.com
Reviewed-by: Pavel Borisov, Matthias van de Meent, Mark Dilger
12 files changed:
src/backend/access/heap/heapam.c
src/backend/access/heap/heapam_handler.c
src/backend/access/table/tableam.c
src/backend/catalog/indexing.c
src/backend/commands/copyfrom.c
src/backend/commands/createas.c
src/backend/commands/matview.c
src/backend/commands/tablecmds.c
src/backend/executor/execReplication.c
src/backend/executor/nodeModifyTable.c
src/include/access/heapam.h
src/include/access/tableam.h

index 2f6527df0dc2d9c2b23320def2e8e8aaf81e7f45..b661d9811eb6fbe4e19acd300585285ad858aea7 100644 (file)
@@ -2088,7 +2088,8 @@ heap_multi_insert_pages(HeapTuple *heaptuples, int done, int ntuples, Size saveF
  */
 void
 heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
-                 CommandId cid, int options, BulkInsertState bistate)
+                 CommandId cid, int options, BulkInsertState bistate,
+                 bool *insert_indexes)
 {
    TransactionId xid = GetCurrentTransactionId();
    HeapTuple  *heaptuples;
@@ -2437,6 +2438,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
        slots[i]->tts_tid = heaptuples[i]->t_self;
 
    pgstat_count_heap_insert(relation, ntuples);
+   *insert_indexes = true;
 }
 
 /*
index 26b3be9779d0bfd50067481cd738eb174e679357..41a4bb0981dd06d561be205c430658e4ba6052ca 100644 (file)
@@ -245,7 +245,7 @@ heapam_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot,
 
 static TupleTableSlot *
 heapam_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid,
-                   int options, BulkInsertState bistate)
+                   int options, BulkInsertState bistate, bool *insert_indexes)
 {
    bool        shouldFree = true;
    HeapTuple   tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree);
@@ -261,6 +261,8 @@ heapam_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid,
    if (shouldFree)
        pfree(tuple);
 
+   *insert_indexes = true;
+
    return slot;
 }
 
index 8d3675be959c16486db3e9168013eac2e5705b19..805d222cebc466cc2d3da2d965656b61de9f51e4 100644 (file)
@@ -273,9 +273,11 @@ table_tuple_get_latest_tid(TableScanDesc scan, ItemPointer tid)
  * default command ID and not allowing access to the speedup options.
  */
 void
-simple_table_tuple_insert(Relation rel, TupleTableSlot *slot)
+simple_table_tuple_insert(Relation rel, TupleTableSlot *slot,
+                         bool *insert_indexes)
 {
-   table_tuple_insert(rel, slot, GetCurrentCommandId(true), 0, NULL);
+   table_tuple_insert(rel, slot, GetCurrentCommandId(true), 0, NULL,
+                      insert_indexes);
 }
 
 /*
index d0d1abda58af3d6647b88e101e09e8b276b65af6..4d404f22f835f2a39f6385ef136ce0cfb822b8c6 100644 (file)
@@ -273,12 +273,14 @@ void
 CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot,
                                 int ntuples, CatalogIndexState indstate)
 {
+   bool        insertIndexes;
+
    /* Nothing to do */
    if (ntuples <= 0)
        return;
 
    heap_multi_insert(heapRel, slot, ntuples,
-                     GetCurrentCommandId(true), 0, NULL);
+                     GetCurrentCommandId(true), 0, NULL, &insertIndexes);
 
    /*
     * There is no equivalent to heap_multi_insert for the catalog indexes, so
index 8908a440e19a03cc72f3d0e5dd2b8760fa583489..b6736369771f1ca93537930ca21e7b88c7b3d861 100644 (file)
@@ -397,6 +397,7 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo,
        bool        line_buf_valid = cstate->line_buf_valid;
        uint64      save_cur_lineno = cstate->cur_lineno;
        MemoryContext oldcontext;
+       bool        insertIndexes;
 
        Assert(buffer->bistate != NULL);
 
@@ -416,7 +417,8 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo,
                           nused,
                           mycid,
                           ti_options,
-                          buffer->bistate);
+                          buffer->bistate,
+                          &insertIndexes);
        MemoryContextSwitchTo(oldcontext);
 
        for (i = 0; i < nused; i++)
@@ -425,7 +427,7 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo,
             * If there are any indexes, update them for all the inserted
             * tuples, and run AFTER ROW INSERT triggers.
             */
-           if (resultRelInfo->ri_NumIndices > 0)
+           if (insertIndexes && resultRelInfo->ri_NumIndices > 0)
            {
                List       *recheckIndexes;
 
@@ -1265,11 +1267,14 @@ CopyFrom(CopyFromState cstate)
                    }
                    else
                    {
+                       bool        insertIndexes;
+
                        /* OK, store the tuple and create index entries for it */
                        table_tuple_insert(resultRelInfo->ri_RelationDesc,
-                                          myslot, mycid, ti_options, bistate);
+                                          myslot, mycid, ti_options, bistate,
+                                          &insertIndexes);
 
-                       if (resultRelInfo->ri_NumIndices > 0)
+                       if (insertIndexes && resultRelInfo->ri_NumIndices > 0)
                            recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
                                                                   myslot,
                                                                   estate,
index 62050f4dc590b8a17326e64405562e91cc4923b9..afd3dace079e1bc1a7c6f2185a3304327cc798c1 100644 (file)
@@ -578,6 +578,7 @@ static bool
 intorel_receive(TupleTableSlot *slot, DestReceiver *self)
 {
    DR_intorel *myState = (DR_intorel *) self;
+   bool        insertIndexes;
 
    /* Nothing to insert if WITH NO DATA is specified. */
    if (!myState->into->skipData)
@@ -594,7 +595,8 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self)
                           slot,
                           myState->output_cid,
                           myState->ti_options,
-                          myState->bistate);
+                          myState->bistate,
+                          &insertIndexes);
    }
 
    /* We know this is a newly created relation, so there are no indexes */
index 6d09b755564e32bbe81bf1c3c3a59e29e4709a17..9ec13d098467d4417511af25145f98f9a6b5c61d 100644 (file)
@@ -476,6 +476,7 @@ static bool
 transientrel_receive(TupleTableSlot *slot, DestReceiver *self)
 {
    DR_transientrel *myState = (DR_transientrel *) self;
+   bool        insertIndexes;
 
    /*
     * Note that the input slot might not be of the type of the target
@@ -490,7 +491,8 @@ transientrel_receive(TupleTableSlot *slot, DestReceiver *self)
                       slot,
                       myState->output_cid,
                       myState->ti_options,
-                      myState->bistate);
+                      myState->bistate,
+                      &insertIndexes);
 
    /* We know this is a newly created relation, so there are no indexes */
 
index 3fcb9cd078340032aec834de304f7d174061bd88..a28f405e27fab7069e1949e65c3fdcd8e7dc311b 100644 (file)
@@ -6360,8 +6360,12 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 
            /* Write the tuple out to the new relation */
            if (newrel)
+           {
+               bool        insertIndexes;
+
                table_tuple_insert(newrel, insertslot, mycid,
-                                  ti_options, bistate);
+                                  ti_options, bistate, &insertIndexes);
+           }
 
            ResetExprContext(econtext);
 
index 0cad843fb6981acc9b951e1f81eaaa5048cfdf4d..db685473fc0debfb4b51df5f498ccdf9834e4d02 100644 (file)
@@ -509,6 +509,7 @@ ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo,
    if (!skip_tuple)
    {
        List       *recheckIndexes = NIL;
+       bool        insertIndexes;
 
        /* Compute stored generated columns */
        if (rel->rd_att->constr &&
@@ -523,9 +524,10 @@ ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo,
            ExecPartitionCheck(resultRelInfo, slot, estate, true);
 
        /* OK, store the tuple and create index entries for it */
-       simple_table_tuple_insert(resultRelInfo->ri_RelationDesc, slot);
+       simple_table_tuple_insert(resultRelInfo->ri_RelationDesc, slot,
+                                 &insertIndexes);
 
-       if (resultRelInfo->ri_NumIndices > 0)
+       if (insertIndexes && resultRelInfo->ri_NumIndices > 0)
            recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
                                                   slot, estate, false, false,
                                                   NULL, NIL, false);
index 325d380b0a97e4c4e5c4611afb6efd74902baf29..df63844b35013f48874ea3524866ecc92400c9f7 100644 (file)
@@ -1135,13 +1135,15 @@ ExecInsert(ModifyTableContext *context,
        }
        else
        {
+           bool        insertIndexes;
+
            /* insert the tuple normally */
            slot = table_tuple_insert(resultRelationDesc, slot,
                                      estate->es_output_cid,
-                                     0, NULL);
+                                     0, NULL, &insertIndexes);
 
            /* insert index entries for tuple */
-           if (resultRelInfo->ri_NumIndices > 0)
+           if (insertIndexes && resultRelInfo->ri_NumIndices > 0)
                recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
                                                       slot, estate, false,
                                                       false, NULL, NIL,
index 91fbc95034345e560cd29347830a60349bc2e56d..32a3fbce961d9e1d9087c67f3da59be143742558 100644 (file)
@@ -282,7 +282,7 @@ extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid,
                        int options, BulkInsertState bistate);
 extern void heap_multi_insert(Relation relation, struct TupleTableSlot **slots,
                              int ntuples, CommandId cid, int options,
-                             BulkInsertState bistate);
+                             BulkInsertState bistate, bool *insert_indexes);
 extern TM_Result heap_delete(Relation relation, ItemPointer tid,
                             CommandId cid, Snapshot crosscheck, int options,
                             struct TM_FailureData *tmfd, bool changingPart,
index cf68ec48ebf7152f05f6bdf3ac39942201d6440b..cf76fc29d4b76421ba5f2c8dba437882380d2dbd 100644 (file)
@@ -512,7 +512,8 @@ typedef struct TableAmRoutine
    /* see table_tuple_insert() for reference about parameters */
    TupleTableSlot *(*tuple_insert) (Relation rel, TupleTableSlot *slot,
                                     CommandId cid, int options,
-                                    struct BulkInsertStateData *bistate);
+                                    struct BulkInsertStateData *bistate,
+                                    bool *insert_indexes);
 
    /* see table_tuple_insert_speculative() for reference about parameters */
    void        (*tuple_insert_speculative) (Relation rel,
@@ -530,7 +531,8 @@ typedef struct TableAmRoutine
 
    /* see table_multi_insert() for reference about parameters */
    void        (*multi_insert) (Relation rel, TupleTableSlot **slots, int nslots,
-                                CommandId cid, int options, struct BulkInsertStateData *bistate);
+                                CommandId cid, int options, struct BulkInsertStateData *bistate,
+                                bool *insert_indexes);
 
    /* see table_tuple_delete() for reference about parameters */
    TM_Result   (*tuple_delete) (Relation rel,
@@ -1384,6 +1386,12 @@ table_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
  * behavior) is also just passed through to RelationGetBufferForTuple. If
  * `bistate` is provided, table_finish_bulk_insert() needs to be called.
  *
+ * The table AM's implementation of tuple_insert should set `*insert_indexes`
+ * to true if it expects the caller to insert the relevant index tuples
+ * (as heap table AM does).  It should set `*insert_indexes` to false if
+ * it cares about index inserts itself and doesn't want the caller to do
+ * index inserts.
+ *
  * Returns the slot containing the inserted tuple, which may differ from the
  * given slot. For instance, the source slot may be VirtualTupleTableSlot, but
  * the result slot may correspond to the table AM. On return the slot's
@@ -1393,10 +1401,11 @@ table_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
  */
 static inline TupleTableSlot *
 table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid,
-                  int options, struct BulkInsertStateData *bistate)
+                  int options, struct BulkInsertStateData *bistate,
+                  bool *insert_indexes)
 {
    return rel->rd_tableam->tuple_insert(rel, slot, cid, options,
-                                        bistate);
+                                        bistate, insert_indexes);
 }
 
 /*
@@ -1448,10 +1457,11 @@ table_tuple_complete_speculative(Relation rel, TupleTableSlot *slot,
  */
 static inline void
 table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots,
-                  CommandId cid, int options, struct BulkInsertStateData *bistate)
+                  CommandId cid, int options, struct BulkInsertStateData *bistate,
+                  bool *insert_indexes)
 {
    rel->rd_tableam->multi_insert(rel, slots, nslots,
-                                 cid, options, bistate);
+                                 cid, options, bistate, insert_indexes);
 }
 
 /*
@@ -2096,7 +2106,8 @@ table_scan_sample_next_tuple(TableScanDesc scan,
  * ----------------------------------------------------------------------------
  */
 
-extern void simple_table_tuple_insert(Relation rel, TupleTableSlot *slot);
+extern void simple_table_tuple_insert(Relation rel, TupleTableSlot *slot,
+                                     bool *insert_indexes);
 extern void simple_table_tuple_delete(Relation rel, ItemPointer tid,
                                      Snapshot snapshot,
                                      TupleTableSlot *oldSlot);