Support for custom slots in the custom executor nodes
authorAlexander Korotkov <akorotkov@postgresql.org>
Wed, 23 Nov 2022 21:36:11 +0000 (00:36 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Wed, 23 Nov 2022 21:36:11 +0000 (00:36 +0300)
Some custom table access method may have their tuple format and use custom
executor nodes for their custom scan types. The ability to set a custom slot
would save them from tuple format conversion. Other users of custom executor
nodes may also benefit.

Discussion: https://postgr.es/m/CAPpHfduJUU6ToecvTyRE_yjxTS80FyPpct4OHaLFk3OEheMTNA@mail.gmail.com
Author: Alexander Korotkov
Reviewed-by: Pavel Borisov
src/backend/executor/nodeCustom.c
src/include/nodes/execnodes.h

index 8f56bd8a23a46c40e60d0134e911e1a38dd72e03..a76ec43b9fe884cb48f09d215ea3393f8641d5de 100644 (file)
@@ -29,6 +29,7 @@ CustomScanState *
 ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
 {
    CustomScanState *css;
+   const TupleTableSlotOps *slotOps;
    Relation    scan_rel = NULL;
    Index       scanrelid = cscan->scan.scanrelid;
    int         tlistvarno;
@@ -63,6 +64,14 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
        css->ss.ss_currentRelation = scan_rel;
    }
 
+   /*
+    * Use a custom slot if specified in CustomScanState or use virtual slot
+    * otherwise.
+    */
+   slotOps = css->slotOps;
+   if (!slotOps)
+       slotOps = &TTSOpsVirtual;
+
    /*
     * Determine the scan tuple type.  If the custom scan provider provided a
     * targetlist describing the scan tuples, use that; else use base
@@ -73,14 +82,14 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
        TupleDesc   scan_tupdesc;
 
        scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist);
-       ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc, &TTSOpsVirtual);
+       ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc, slotOps);
        /* Node's targetlist will contain Vars with varno = INDEX_VAR */
        tlistvarno = INDEX_VAR;
    }
    else
    {
        ExecInitScanTupleSlot(estate, &css->ss, RelationGetDescr(scan_rel),
-                             &TTSOpsVirtual);
+                             slotOps);
        /* Node's targetlist will contain Vars with varno = scanrelid */
        tlistvarno = scanrelid;
    }
index 01b1727fc09face14c0eb50554653c4519e39d02..0f10d4432bda7877285f13d4b7f4cd3eb2811755 100644 (file)
@@ -1949,6 +1949,7 @@ typedef struct CustomScanState
    List       *custom_ps;      /* list of child PlanState nodes, if any */
    Size        pscan_len;      /* size of parallel coordination information */
    const struct CustomExecMethods *methods;
+   const struct TupleTableSlotOps *slotOps;
 } CustomScanState;
 
 /* ----------------------------------------------------------------