Allow table AM tuple_insert() method to return the different slot
authorAlexander Korotkov <akorotkov@postgresql.org>
Thu, 21 Mar 2024 21:00:40 +0000 (23:00 +0200)
committerAlexander Korotkov <akorotkov@postgresql.org>
Thu, 21 Mar 2024 21:00:40 +0000 (23:00 +0200)
This allows table AM to return a native tuple slot even if
VirtualTupleTableSlot is given as an input.  Native tuple slots have knowledge
about system attributes, which could be accessed in the future.
table_multi_insert() method already can modify the input 'slots' array.

Discussion: https://postgr.es/m/CAPpHfdurb9ycV8udYqM%3Do0sPS66PJ4RCBM1g-bBpvzUfogY0EA%40mail.gmail.com
Reviewed-by: Matthias van de Meent, Mark Dilger, Pavel Borisov
Reviewed-by: Nikita Malakhov, Japin Li
src/backend/access/heap/heapam_handler.c
src/backend/executor/nodeModifyTable.c
src/include/access/tableam.h

index 4dd1341f606cb371ee6687f5098459017b9d08f5..2b7c7026429fe9cc4787bfd226759a94f13eb511 100644 (file)
@@ -237,7 +237,7 @@ heapam_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot,
  * ----------------------------------------------------------------------------
  */
 
-static void
+static TupleTableSlot *
 heapam_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid,
                    int options, BulkInsertState bistate)
 {
@@ -254,6 +254,8 @@ heapam_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid,
 
    if (shouldFree)
        pfree(tuple);
+
+   return slot;
 }
 
 static void
index 4abfe82f7fbd033bc2b057d4b1fe3d45d18b5a75..5568dd7b9577e9817d4cb312828b6b72dc44723f 100644 (file)
@@ -1125,9 +1125,9 @@ ExecInsert(ModifyTableContext *context,
        else
        {
            /* insert the tuple normally */
-           table_tuple_insert(resultRelationDesc, slot,
-                              estate->es_output_cid,
-                              0, NULL);
+           slot = table_tuple_insert(resultRelationDesc, slot,
+                                     estate->es_output_cid,
+                                     0, NULL);
 
            /* insert index entries for tuple */
            if (resultRelInfo->ri_NumIndices > 0)
index fd474b74883c6dcbc43daf0a4ef45af0176f0fe3..65834caeb1c495ba37ec4e55fbc1474868b2d731 100644 (file)
@@ -500,9 +500,9 @@ typedef struct TableAmRoutine
     */
 
    /* see table_tuple_insert() for reference about parameters */
-   void        (*tuple_insert) (Relation rel, TupleTableSlot *slot,
-                                CommandId cid, int options,
-                                struct BulkInsertStateData *bistate);
+   TupleTableSlot *(*tuple_insert) (Relation rel, TupleTableSlot *slot,
+                                    CommandId cid, int options,
+                                    struct BulkInsertStateData *bistate);
 
    /* see table_tuple_insert_speculative() for reference about parameters */
    void        (*tuple_insert_speculative) (Relation rel,
@@ -1392,16 +1392,19 @@ 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.
  *
- * On return the slot's tts_tid and tts_tableOid are updated to reflect the
- * insertion. But note that any toasting of fields within the slot is NOT
- * reflected in the slots contents.
+ * 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
+ * tts_tid and tts_tableOid are updated to reflect the insertion. But note
+ * that any toasting of fields within the slot is NOT reflected in the slots
+ * contents.
  */
-static inline void
+static inline TupleTableSlot *
 table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid,
                   int options, struct BulkInsertStateData *bistate)
 {
-   rel->rd_tableam->tuple_insert(rel, slot, cid, options,
-                                 bistate);
+   return rel->rd_tableam->tuple_insert(rel, slot, cid, options,
+                                        bistate);
 }
 
 /*