LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeCustom.c (source / functions) Coverage Total Hit UNC UIC UBC EUB
Current: Differential Code Coverage HEAD vs 15 Lines: 0.0 % 88 0 4 49 35 53
Current Date: 2023-04-08 15:15:32 Functions: 0.0 % 11 0 1 10 10
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /* ------------------------------------------------------------------------
       2                 :  *
       3                 :  * nodeCustom.c
       4                 :  *      Routines to handle execution of custom scan node
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       7                 :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :  *
       9                 :  * ------------------------------------------------------------------------
      10                 :  */
      11                 : #include "postgres.h"
      12                 : 
      13                 : #include "access/parallel.h"
      14                 : #include "executor/executor.h"
      15                 : #include "executor/nodeCustom.h"
      16                 : #include "miscadmin.h"
      17                 : #include "nodes/execnodes.h"
      18                 : #include "nodes/extensible.h"
      19                 : #include "nodes/plannodes.h"
      20                 : #include "parser/parsetree.h"
      21                 : #include "utils/hsearch.h"
      22                 : #include "utils/memutils.h"
      23                 : #include "utils/rel.h"
      24                 : 
      25                 : static TupleTableSlot *ExecCustomScan(PlanState *pstate);
      26                 : 
      27                 : 
      28                 : CustomScanState *
      29 UBC           0 : ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
      30                 : {
      31                 :     CustomScanState *css;
      32                 :     const TupleTableSlotOps *slotOps;
      33 UIC           0 :     Relation    scan_rel = NULL;
      34 UBC           0 :     Index       scanrelid = cscan->scan.scanrelid;
      35 EUB             :     int         tlistvarno;
      36                 : 
      37                 :     /*
      38                 :      * Allocate the CustomScanState object.  We let the custom scan provider
      39                 :      * do the palloc, in case it wants to make a larger object that embeds
      40                 :      * CustomScanState as the first field.  It must set the node tag and the
      41                 :      * methods field correctly at this time.  Other standard fields should be
      42                 :      * set to zero.
      43                 :      */
      44 UIC           0 :     css = castNode(CustomScanState,
      45 EUB             :                    cscan->methods->CreateCustomScanState(cscan));
      46                 : 
      47                 :     /* ensure flags is filled correctly */
      48 UIC           0 :     css->flags = cscan->flags;
      49 EUB             : 
      50                 :     /* fill up fields of ScanState */
      51 UIC           0 :     css->ss.ps.plan = &cscan->scan.plan;
      52 UBC           0 :     css->ss.ps.state = estate;
      53               0 :     css->ss.ps.ExecProcNode = ExecCustomScan;
      54 EUB             : 
      55                 :     /* create expression context for node */
      56 UIC           0 :     ExecAssignExprContext(estate, &css->ss.ps);
      57 EUB             : 
      58                 :     /*
      59                 :      * open the scan relation, if any
      60                 :      */
      61 UIC           0 :     if (scanrelid > 0)
      62 EUB             :     {
      63 UIC           0 :         scan_rel = ExecOpenScanRelation(estate, scanrelid, eflags);
      64 UBC           0 :         css->ss.ss_currentRelation = scan_rel;
      65 EUB             :     }
      66                 : 
      67                 :     /*
      68                 :      * Use a custom slot if specified in CustomScanState or use virtual slot
      69                 :      * otherwise.
      70                 :      */
      71 UNC           0 :     slotOps = css->slotOps;
      72               0 :     if (!slotOps)
      73               0 :         slotOps = &TTSOpsVirtual;
      74                 : 
      75                 :     /*
      76                 :      * Determine the scan tuple type.  If the custom scan provider provided a
      77                 :      * targetlist describing the scan tuples, use that; else use base
      78                 :      * relation's rowtype.
      79                 :      */
      80 UBC           0 :     if (cscan->custom_scan_tlist != NIL || scan_rel == NULL)
      81               0 :     {
      82 EUB             :         TupleDesc   scan_tupdesc;
      83                 : 
      84 UIC           0 :         scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist);
      85 UNC           0 :         ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc, slotOps);
      86                 :         /* Node's targetlist will contain Vars with varno = INDEX_VAR */
      87 UIC           0 :         tlistvarno = INDEX_VAR;
      88                 :     }
      89 EUB             :     else
      90                 :     {
      91 UIC           0 :         ExecInitScanTupleSlot(estate, &css->ss, RelationGetDescr(scan_rel),
      92                 :                               slotOps);
      93 EUB             :         /* Node's targetlist will contain Vars with varno = scanrelid */
      94 UBC           0 :         tlistvarno = scanrelid;
      95                 :     }
      96 EUB             : 
      97                 :     /*
      98                 :      * Initialize result slot, type and projection.
      99                 :      */
     100 UBC           0 :     ExecInitResultTupleSlotTL(&css->ss.ps, &TTSOpsVirtual);
     101 UIC           0 :     ExecAssignScanProjectionInfoWithVarno(&css->ss, tlistvarno);
     102                 : 
     103 EUB             :     /* initialize child expressions */
     104 UIC           0 :     css->ss.ps.qual =
     105               0 :         ExecInitQual(cscan->scan.plan.qual, (PlanState *) css);
     106                 : 
     107                 :     /*
     108                 :      * The callback of custom-scan provider applies the final initialization
     109 EUB             :      * of the custom-scan-state node according to its logic.
     110                 :      */
     111 UIC           0 :     css->methods->BeginCustomScan(css, estate, eflags);
     112                 : 
     113 UBC           0 :     return css;
     114 EUB             : }
     115                 : 
     116                 : static TupleTableSlot *
     117 UIC           0 : ExecCustomScan(PlanState *pstate)
     118                 : {
     119               0 :     CustomScanState *node = castNode(CustomScanState, pstate);
     120 EUB             : 
     121 UIC           0 :     CHECK_FOR_INTERRUPTS();
     122 EUB             : 
     123 UIC           0 :     Assert(node->methods->ExecCustomScan != NULL);
     124               0 :     return node->methods->ExecCustomScan(node);
     125                 : }
     126 EUB             : 
     127                 : void
     128 UBC           0 : ExecEndCustomScan(CustomScanState *node)
     129                 : {
     130               0 :     Assert(node->methods->EndCustomScan != NULL);
     131 UIC           0 :     node->methods->EndCustomScan(node);
     132 EUB             : 
     133                 :     /* Free the exprcontext */
     134 UIC           0 :     ExecFreeExprContext(&node->ss.ps);
     135                 : 
     136                 :     /* Clean out the tuple table */
     137 UBC           0 :     ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
     138 UIC           0 :     ExecClearTuple(node->ss.ss_ScanTupleSlot);
     139 UBC           0 : }
     140 EUB             : 
     141                 : void
     142 UIC           0 : ExecReScanCustomScan(CustomScanState *node)
     143 EUB             : {
     144 UIC           0 :     Assert(node->methods->ReScanCustomScan != NULL);
     145               0 :     node->methods->ReScanCustomScan(node);
     146 UBC           0 : }
     147 EUB             : 
     148                 : void
     149 UIC           0 : ExecCustomMarkPos(CustomScanState *node)
     150                 : {
     151 UBC           0 :     if (!node->methods->MarkPosCustomScan)
     152 UIC           0 :         ereport(ERROR,
     153 EUB             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     154                 :                  errmsg("custom scan \"%s\" does not support MarkPos",
     155                 :                         node->methods->CustomName)));
     156 UIC           0 :     node->methods->MarkPosCustomScan(node);
     157               0 : }
     158 EUB             : 
     159                 : void
     160 UBC           0 : ExecCustomRestrPos(CustomScanState *node)
     161 EUB             : {
     162 UIC           0 :     if (!node->methods->RestrPosCustomScan)
     163               0 :         ereport(ERROR,
     164                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     165 EUB             :                  errmsg("custom scan \"%s\" does not support MarkPos",
     166                 :                         node->methods->CustomName)));
     167 UIC           0 :     node->methods->RestrPosCustomScan(node);
     168               0 : }
     169 EUB             : 
     170                 : void
     171 UBC           0 : ExecCustomScanEstimate(CustomScanState *node, ParallelContext *pcxt)
     172 EUB             : {
     173 UIC           0 :     const CustomExecMethods *methods = node->methods;
     174                 : 
     175               0 :     if (methods->EstimateDSMCustomScan)
     176 EUB             :     {
     177 UBC           0 :         node->pscan_len = methods->EstimateDSMCustomScan(node, pcxt);
     178 UIC           0 :         shm_toc_estimate_chunk(&pcxt->estimator, node->pscan_len);
     179               0 :         shm_toc_estimate_keys(&pcxt->estimator, 1);
     180 EUB             :     }
     181 UIC           0 : }
     182 EUB             : 
     183                 : void
     184 UBC           0 : ExecCustomScanInitializeDSM(CustomScanState *node, ParallelContext *pcxt)
     185                 : {
     186               0 :     const CustomExecMethods *methods = node->methods;
     187 EUB             : 
     188 UBC           0 :     if (methods->InitializeDSMCustomScan)
     189                 :     {
     190               0 :         int         plan_node_id = node->ss.ps.plan->plan_node_id;
     191                 :         void       *coordinate;
     192                 : 
     193               0 :         coordinate = shm_toc_allocate(pcxt->toc, node->pscan_len);
     194 UIC           0 :         methods->InitializeDSMCustomScan(node, pcxt, coordinate);
     195 UBC           0 :         shm_toc_insert(pcxt->toc, plan_node_id, coordinate);
     196                 :     }
     197               0 : }
     198                 : 
     199 EUB             : void
     200 UIC           0 : ExecCustomScanReInitializeDSM(CustomScanState *node, ParallelContext *pcxt)
     201                 : {
     202 UBC           0 :     const CustomExecMethods *methods = node->methods;
     203 EUB             : 
     204 UBC           0 :     if (methods->ReInitializeDSMCustomScan)
     205                 :     {
     206               0 :         int         plan_node_id = node->ss.ps.plan->plan_node_id;
     207                 :         void       *coordinate;
     208                 : 
     209               0 :         coordinate = shm_toc_lookup(pcxt->toc, plan_node_id, false);
     210 UIC           0 :         methods->ReInitializeDSMCustomScan(node, pcxt, coordinate);
     211 EUB             :     }
     212 UIC           0 : }
     213 EUB             : 
     214                 : void
     215 UBC           0 : ExecCustomScanInitializeWorker(CustomScanState *node,
     216                 :                                ParallelWorkerContext *pwcxt)
     217                 : {
     218               0 :     const CustomExecMethods *methods = node->methods;
     219 EUB             : 
     220 UIC           0 :     if (methods->InitializeWorkerCustomScan)
     221 EUB             :     {
     222 UIC           0 :         int         plan_node_id = node->ss.ps.plan->plan_node_id;
     223                 :         void       *coordinate;
     224 EUB             : 
     225 UIC           0 :         coordinate = shm_toc_lookup(pwcxt->toc, plan_node_id, false);
     226               0 :         methods->InitializeWorkerCustomScan(node, pwcxt->toc, coordinate);
     227 EUB             :     }
     228 UIC           0 : }
     229 EUB             : 
     230                 : void
     231 UBC           0 : ExecShutdownCustomScan(CustomScanState *node)
     232                 : {
     233 UIC           0 :     const CustomExecMethods *methods = node->methods;
     234 EUB             : 
     235 UBC           0 :     if (methods->ShutdownCustomScan)
     236 UIC           0 :         methods->ShutdownCustomScan(node);
     237 UBC           0 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a