LCOV - differential code coverage report
Current view: top level - src/backend/executor - execAmi.c (source / functions) Coverage Total Hit LBC UBC GBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 79.0 % 290 229 3 58 3 226
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 7 7 7
Baseline: 16@8cea358b128 Branches: 70.0 % 150 105 1 44 1 104
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 79.0 % 290 229 3 58 3 226
Function coverage date bins:
(240..) days: 100.0 % 7 7 7
Branch coverage date bins:
(240..) days: 70.0 % 150 105 1 44 1 104

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * execAmi.c
                                  4                 :                :  *    miscellaneous executor access method routines
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *  src/backend/executor/execAmi.c
                                 10                 :                :  *
                                 11                 :                :  *-------------------------------------------------------------------------
                                 12                 :                :  */
                                 13                 :                : #include "postgres.h"
                                 14                 :                : 
                                 15                 :                : #include "access/amapi.h"
                                 16                 :                : #include "access/htup_details.h"
                                 17                 :                : #include "catalog/pg_class.h"
                                 18                 :                : #include "executor/nodeAgg.h"
                                 19                 :                : #include "executor/nodeAppend.h"
                                 20                 :                : #include "executor/nodeBitmapAnd.h"
                                 21                 :                : #include "executor/nodeBitmapHeapscan.h"
                                 22                 :                : #include "executor/nodeBitmapIndexscan.h"
                                 23                 :                : #include "executor/nodeBitmapOr.h"
                                 24                 :                : #include "executor/nodeCtescan.h"
                                 25                 :                : #include "executor/nodeCustom.h"
                                 26                 :                : #include "executor/nodeForeignscan.h"
                                 27                 :                : #include "executor/nodeFunctionscan.h"
                                 28                 :                : #include "executor/nodeGather.h"
                                 29                 :                : #include "executor/nodeGatherMerge.h"
                                 30                 :                : #include "executor/nodeGroup.h"
                                 31                 :                : #include "executor/nodeHash.h"
                                 32                 :                : #include "executor/nodeHashjoin.h"
                                 33                 :                : #include "executor/nodeIncrementalSort.h"
                                 34                 :                : #include "executor/nodeIndexonlyscan.h"
                                 35                 :                : #include "executor/nodeIndexscan.h"
                                 36                 :                : #include "executor/nodeLimit.h"
                                 37                 :                : #include "executor/nodeLockRows.h"
                                 38                 :                : #include "executor/nodeMaterial.h"
                                 39                 :                : #include "executor/nodeMemoize.h"
                                 40                 :                : #include "executor/nodeMergeAppend.h"
                                 41                 :                : #include "executor/nodeMergejoin.h"
                                 42                 :                : #include "executor/nodeModifyTable.h"
                                 43                 :                : #include "executor/nodeNamedtuplestorescan.h"
                                 44                 :                : #include "executor/nodeNestloop.h"
                                 45                 :                : #include "executor/nodeProjectSet.h"
                                 46                 :                : #include "executor/nodeRecursiveunion.h"
                                 47                 :                : #include "executor/nodeResult.h"
                                 48                 :                : #include "executor/nodeSamplescan.h"
                                 49                 :                : #include "executor/nodeSeqscan.h"
                                 50                 :                : #include "executor/nodeSetOp.h"
                                 51                 :                : #include "executor/nodeSort.h"
                                 52                 :                : #include "executor/nodeSubplan.h"
                                 53                 :                : #include "executor/nodeSubqueryscan.h"
                                 54                 :                : #include "executor/nodeTableFuncscan.h"
                                 55                 :                : #include "executor/nodeTidrangescan.h"
                                 56                 :                : #include "executor/nodeTidscan.h"
                                 57                 :                : #include "executor/nodeUnique.h"
                                 58                 :                : #include "executor/nodeValuesscan.h"
                                 59                 :                : #include "executor/nodeWindowAgg.h"
                                 60                 :                : #include "executor/nodeWorktablescan.h"
                                 61                 :                : #include "nodes/extensible.h"
                                 62                 :                : #include "nodes/pathnodes.h"
                                 63                 :                : #include "utils/syscache.h"
                                 64                 :                : 
                                 65                 :                : static bool IndexSupportsBackwardScan(Oid indexid);
                                 66                 :                : 
                                 67                 :                : 
                                 68                 :                : /*
                                 69                 :                :  * ExecReScan
                                 70                 :                :  *      Reset a plan node so that its output can be re-scanned.
                                 71                 :                :  *
                                 72                 :                :  * Note that if the plan node has parameters that have changed value,
                                 73                 :                :  * the output might be different from last time.
                                 74                 :                :  */
                                 75                 :                : void
 5025 tgl@sss.pgh.pa.us          76                 :CBC     1221028 : ExecReScan(PlanState *node)
                                 77                 :                : {
                                 78                 :                :     /* If collecting timing stats, update them */
 8244                            79         [ +  + ]:        1221028 :     if (node->instrument)
                                 80                 :          15029 :         InstrEndLoop(node->instrument);
                                 81                 :                : 
                                 82                 :                :     /*
                                 83                 :                :      * If we have changed parameters, propagate that info.
                                 84                 :                :      *
                                 85                 :                :      * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
                                 86                 :                :      * corresponding to the output param(s) that the InitPlan will update.
                                 87                 :                :      * Since we make only one pass over the list, that means that an InitPlan
                                 88                 :                :      * can depend on the output param(s) of a sibling InitPlan only if that
                                 89                 :                :      * sibling appears earlier in the list.  This is workable for now given
                                 90                 :                :      * the limited ways in which one InitPlan could depend on another, but
                                 91                 :                :      * eventually we might need to work harder (or else make the planner
                                 92                 :                :      * enlarge the extParam/allParam sets to include the params of depended-on
                                 93                 :                :      * InitPlans).
                                 94                 :                :      */
 7735                            95         [ +  + ]:        1221028 :     if (node->chgParam != NULL)
                                 96                 :                :     {
                                 97                 :                :         ListCell   *l;
                                 98                 :                : 
 7263 neilc@samurai.com          99   [ +  +  +  +  :        1115542 :         foreach(l, node->initPlan)
                                              +  + ]
                                100                 :                :         {
                                101                 :            663 :             SubPlanState *sstate = (SubPlanState *) lfirst(l);
 7793 tgl@sss.pgh.pa.us         102                 :            663 :             PlanState  *splan = sstate->planstate;
                                103                 :                : 
 7735                           104         [ +  + ]:            663 :             if (splan->plan->extParam != NULL)    /* don't care about child
                                105                 :                :                                                  * local Params */
                                106                 :            586 :                 UpdateChangedParamSet(splan, node->chgParam);
                                107         [ +  + ]:            663 :             if (splan->chgParam != NULL)
 7793                           108                 :            466 :                 ExecReScanSetParamPlan(sstate, node);
                                109                 :                :         }
 7263 neilc@samurai.com         110   [ +  +  +  +  :        1115306 :         foreach(l, node->subPlan)
                                              +  + ]
                                111                 :                :         {
                                112                 :            427 :             SubPlanState *sstate = (SubPlanState *) lfirst(l);
 7793 tgl@sss.pgh.pa.us         113                 :            427 :             PlanState  *splan = sstate->planstate;
                                114                 :                : 
 7735                           115         [ +  + ]:            427 :             if (splan->plan->extParam != NULL)
                                116                 :            424 :                 UpdateChangedParamSet(splan, node->chgParam);
                                117                 :                :         }
                                118                 :                :         /* Well. Now set chgParam for child trees. */
  647                           119         [ +  + ]:        1114879 :         if (outerPlanState(node) != NULL)
                                120                 :         296330 :             UpdateChangedParamSet(outerPlanState(node), node->chgParam);
                                121         [ +  + ]:        1114879 :         if (innerPlanState(node) != NULL)
                                122                 :           6775 :             UpdateChangedParamSet(innerPlanState(node), node->chgParam);
                                123                 :                :     }
                                124                 :                : 
                                125                 :                :     /* Call expression callbacks */
 7423                           126         [ +  + ]:        1221028 :     if (node->ps_ExprContext)
                                127                 :        1129928 :         ReScanExprContext(node->ps_ExprContext);
                                128                 :                : 
                                129                 :                :     /* And do node-type-specific processing */
 9716 bruce@momjian.us          130   [ +  +  -  +  :        1221028 :     switch (nodeTag(node))
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  -  
                                     +  +  -  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                        +  +  +  - ]
                                131                 :                :     {
 7801 tgl@sss.pgh.pa.us         132                 :          16651 :         case T_ResultState:
 5025                           133                 :          16651 :             ExecReScanResult((ResultState *) node);
 9557 vadim4o@yahoo.com         134                 :          16651 :             break;
                                135                 :                : 
 2643 andres@anarazel.de        136                 :           6005 :         case T_ProjectSetState:
                                137                 :           6005 :             ExecReScanProjectSet((ProjectSetState *) node);
                                138                 :           6005 :             break;
                                139                 :                : 
 5300 tgl@sss.pgh.pa.us         140                 :UBC           0 :         case T_ModifyTableState:
 5025                           141                 :              0 :             ExecReScanModifyTable((ModifyTableState *) node);
 5300                           142                 :              0 :             break;
                                143                 :                : 
 7801 tgl@sss.pgh.pa.us         144                 :CBC        8310 :         case T_AppendState:
 5025                           145                 :           8310 :             ExecReScanAppend((AppendState *) node);
 9557 vadim4o@yahoo.com         146                 :           8310 :             break;
                                147                 :                : 
 4931 tgl@sss.pgh.pa.us         148                 :              9 :         case T_MergeAppendState:
                                149                 :              9 :             ExecReScanMergeAppend((MergeAppendState *) node);
                                150                 :              9 :             break;
                                151                 :                : 
 5671                           152                 :              6 :         case T_RecursiveUnionState:
 5025                           153                 :              6 :             ExecReScanRecursiveUnion((RecursiveUnionState *) node);
 5671                           154                 :              6 :             break;
                                155                 :                : 
 6935                           156                 :             29 :         case T_BitmapAndState:
 5025                           157                 :             29 :             ExecReScanBitmapAnd((BitmapAndState *) node);
 6935                           158                 :             29 :             break;
                                159                 :                : 
                                160                 :             14 :         case T_BitmapOrState:
 5025                           161                 :             14 :             ExecReScanBitmapOr((BitmapOrState *) node);
 6935                           162                 :             14 :             break;
                                163                 :                : 
 7801                           164                 :         507215 :         case T_SeqScanState:
 5025                           165                 :         507215 :             ExecReScanSeqScan((SeqScanState *) node);
 8598                           166                 :         507215 :             break;
                                167                 :                : 
 3257 simon@2ndQuadrant.co      168                 :             29 :         case T_SampleScanState:
                                169                 :             29 :             ExecReScanSampleScan((SampleScanState *) node);
                                170                 :             29 :             break;
                                171                 :                : 
 3119 rhaas@postgresql.org      172                 :            150 :         case T_GatherState:
                                173                 :            150 :             ExecReScanGather((GatherState *) node);
                                174                 :            150 :             break;
                                175                 :                : 
 2434                           176                 :             24 :         case T_GatherMergeState:
                                177                 :             24 :             ExecReScanGatherMerge((GatherMergeState *) node);
                                178                 :             24 :             break;
                                179                 :                : 
 7801 tgl@sss.pgh.pa.us         180                 :         202154 :         case T_IndexScanState:
 5025                           181                 :         202154 :             ExecReScanIndexScan((IndexScanState *) node);
 8598                           182                 :         202151 :             break;
                                183                 :                : 
 4569                           184                 :          40844 :         case T_IndexOnlyScanState:
                                185                 :          40844 :             ExecReScanIndexOnlyScan((IndexOnlyScanState *) node);
                                186                 :          40844 :             break;
                                187                 :                : 
 6935                           188                 :           2586 :         case T_BitmapIndexScanState:
 5025                           189                 :           2586 :             ExecReScanBitmapIndexScan((BitmapIndexScanState *) node);
 6935                           190                 :           2586 :             break;
                                191                 :                : 
                                192                 :           2259 :         case T_BitmapHeapScanState:
 5025                           193                 :           2259 :             ExecReScanBitmapHeapScan((BitmapHeapScanState *) node);
 6935                           194                 :           2259 :             break;
                                195                 :                : 
 7801                           196                 :              9 :         case T_TidScanState:
 5025                           197                 :              9 :             ExecReScanTidScan((TidScanState *) node);
 8008                           198                 :              9 :             break;
                                199                 :                : 
 1142 drowley@postgresql.o      200                 :             33 :         case T_TidRangeScanState:
                                201                 :             33 :             ExecReScanTidRangeScan((TidRangeScanState *) node);
                                202                 :             33 :             break;
                                203                 :                : 
 7801 tgl@sss.pgh.pa.us         204                 :           1093 :         case T_SubqueryScanState:
 5025                           205                 :           1093 :             ExecReScanSubqueryScan((SubqueryScanState *) node);
 9557 vadim4o@yahoo.com         206                 :           1093 :             break;
                                207                 :                : 
 7801 tgl@sss.pgh.pa.us         208                 :          49865 :         case T_FunctionScanState:
 5025                           209                 :          49865 :             ExecReScanFunctionScan((FunctionScanState *) node);
 9557 vadim4o@yahoo.com         210                 :          49865 :             break;
                                211                 :                : 
 2594 alvherre@alvh.no-ip.      212                 :            219 :         case T_TableFuncScanState:
                                213                 :            219 :             ExecReScanTableFuncScan((TableFuncScanState *) node);
                                214                 :            219 :             break;
                                215                 :                : 
 6465 mail@joeconway.com        216                 :          30199 :         case T_ValuesScanState:
 5025 tgl@sss.pgh.pa.us         217                 :          30199 :             ExecReScanValuesScan((ValuesScanState *) node);
 6465 mail@joeconway.com        218                 :          30199 :             break;
                                219                 :                : 
 5671 tgl@sss.pgh.pa.us         220                 :           2619 :         case T_CteScanState:
 5025                           221                 :           2619 :             ExecReScanCteScan((CteScanState *) node);
 5671                           222                 :           2619 :             break;
                                223                 :                : 
 2571 kgrittn@postgresql.o      224                 :UBC           0 :         case T_NamedTuplestoreScanState:
                                225                 :              0 :             ExecReScanNamedTuplestoreScan((NamedTuplestoreScanState *) node);
                                226                 :              0 :             break;
                                227                 :                : 
 5671 tgl@sss.pgh.pa.us         228                 :CBC        3151 :         case T_WorkTableScanState:
 5025                           229                 :           3151 :             ExecReScanWorkTableScan((WorkTableScanState *) node);
 5671                           230                 :           3151 :             break;
                                231                 :                : 
 4802                           232                 :            402 :         case T_ForeignScanState:
                                233                 :            402 :             ExecReScanForeignScan((ForeignScanState *) node);
                                234                 :            402 :             break;
                                235                 :                : 
 3446 rhaas@postgresql.org      236                 :UBC           0 :         case T_CustomScanState:
                                237                 :              0 :             ExecReScanCustomScan((CustomScanState *) node);
                                238                 :              0 :             break;
                                239                 :                : 
 7801 tgl@sss.pgh.pa.us         240                 :CBC        5865 :         case T_NestLoopState:
 5025                           241                 :           5865 :             ExecReScanNestLoop((NestLoopState *) node);
 9557 vadim4o@yahoo.com         242                 :           5865 :             break;
                                243                 :                : 
 7801 tgl@sss.pgh.pa.us         244                 :            239 :         case T_MergeJoinState:
 5025                           245                 :            239 :             ExecReScanMergeJoin((MergeJoinState *) node);
 9557 vadim4o@yahoo.com         246                 :            239 :             break;
                                247                 :                : 
 7801 tgl@sss.pgh.pa.us         248                 :           1117 :         case T_HashJoinState:
 5025                           249                 :           1117 :             ExecReScanHashJoin((HashJoinState *) node);
 9557 vadim4o@yahoo.com         250                 :           1117 :             break;
                                251                 :                : 
 7801 tgl@sss.pgh.pa.us         252                 :          60884 :         case T_MaterialState:
 5025                           253                 :          60884 :             ExecReScanMaterial((MaterialState *) node);
 9404 bruce@momjian.us          254                 :          60884 :             break;
                                255                 :                : 
 1005 drowley@postgresql.o      256                 :         233521 :         case T_MemoizeState:
                                257                 :         233521 :             ExecReScanMemoize((MemoizeState *) node);
 1108                           258                 :         233521 :             break;
                                259                 :                : 
 7801 tgl@sss.pgh.pa.us         260                 :          20882 :         case T_SortState:
 5025                           261                 :          20882 :             ExecReScanSort((SortState *) node);
 9557 vadim4o@yahoo.com         262                 :          20882 :             break;
                                263                 :                : 
 1469 tomas.vondra@postgre      264                 :              6 :         case T_IncrementalSortState:
                                265                 :              6 :             ExecReScanIncrementalSort((IncrementalSortState *) node);
                                266                 :              6 :             break;
                                267                 :                : 
 7801 tgl@sss.pgh.pa.us         268                 :             12 :         case T_GroupState:
 5025                           269                 :             12 :             ExecReScanGroup((GroupState *) node);
 9547 vadim4o@yahoo.com         270                 :             12 :             break;
                                271                 :                : 
 7801 tgl@sss.pgh.pa.us         272                 :          18481 :         case T_AggState:
 5025                           273                 :          18481 :             ExecReScanAgg((AggState *) node);
 8592                           274                 :          18481 :             break;
                                275                 :                : 
 5586                           276                 :             39 :         case T_WindowAggState:
 5025                           277                 :             39 :             ExecReScanWindowAgg((WindowAggState *) node);
 5586                           278                 :             39 :             break;
                                279                 :                : 
 7801 tgl@sss.pgh.pa.us         280                 :GBC        4736 :         case T_UniqueState:
 5025                           281                 :           4736 :             ExecReScanUnique((UniqueState *) node);
 8571                           282                 :           4736 :             break;
                                283                 :                : 
 7801 tgl@sss.pgh.pa.us         284                 :CBC         613 :         case T_HashState:
 5025                           285                 :            613 :             ExecReScanHash((HashState *) node);
 9547 vadim4o@yahoo.com         286                 :            613 :             break;
                                287                 :                : 
 7801 tgl@sss.pgh.pa.us         288                 :            300 :         case T_SetOpState:
 5025                           289                 :            300 :             ExecReScanSetOp((SetOpState *) node);
 9543 vadim4o@yahoo.com         290                 :            300 :             break;
                                291                 :                : 
 5298 tgl@sss.pgh.pa.us         292                 :              8 :         case T_LockRowsState:
 5025                           293                 :              8 :             ExecReScanLockRows((LockRowsState *) node);
 5298                           294                 :              8 :             break;
                                295                 :                : 
 7801                           296                 :            450 :         case T_LimitState:
 5025                           297                 :            450 :             ExecReScanLimit((LimitState *) node);
 9405 bruce@momjian.us          298                 :            450 :             break;
                                299                 :                : 
 9715 bruce@momjian.us          300                 :UBC           0 :         default:
 7573 tgl@sss.pgh.pa.us         301         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
                                302                 :                :             break;
                                303                 :                :     }
                                304                 :                : 
 7735 tgl@sss.pgh.pa.us         305         [ +  + ]:CBC     1221025 :     if (node->chgParam != NULL)
                                306                 :                :     {
                                307                 :        1114879 :         bms_free(node->chgParam);
                                308                 :        1114879 :         node->chgParam = NULL;
                                309                 :                :     }
10141 scrappy@hub.org           310                 :        1221025 : }
                                311                 :                : 
                                312                 :                : /*
                                313                 :                :  * ExecMarkPos
                                314                 :                :  *
                                315                 :                :  * Marks the current scan position.
                                316                 :                :  *
                                317                 :                :  * NOTE: mark/restore capability is currently needed only for plan nodes
                                318                 :                :  * that are the immediate inner child of a MergeJoin node.  Since MergeJoin
                                319                 :                :  * requires sorted input, there is never any need to support mark/restore in
                                320                 :                :  * node types that cannot produce sorted output.  There are some cases in
                                321                 :                :  * which a node can pass through sorted data from its child; if we don't
                                322                 :                :  * implement mark/restore for such a node type, the planner compensates by
                                323                 :                :  * inserting a Material node above that node.
                                324                 :                :  */
                                325                 :                : void
 7555 bruce@momjian.us          326                 :         358163 : ExecMarkPos(PlanState *node)
                                327                 :                : {
 9716                           328   [ +  +  -  +  :         358163 :     switch (nodeTag(node))
                                           +  -  - ]
                                329                 :                :     {
 7801 tgl@sss.pgh.pa.us         330                 :           3038 :         case T_IndexScanState:
                                331                 :           3038 :             ExecIndexMarkPos((IndexScanState *) node);
 9715 bruce@momjian.us          332                 :           3038 :             break;
                                333                 :                : 
 4569 tgl@sss.pgh.pa.us         334                 :          62002 :         case T_IndexOnlyScanState:
                                335                 :          62002 :             ExecIndexOnlyMarkPos((IndexOnlyScanState *) node);
                                336                 :          62002 :             break;
                                337                 :                : 
 3446 rhaas@postgresql.org      338                 :UBC           0 :         case T_CustomScanState:
                                339                 :              0 :             ExecCustomMarkPos((CustomScanState *) node);
                                340                 :              0 :             break;
                                341                 :                : 
 7801 tgl@sss.pgh.pa.us         342                 :CBC        3318 :         case T_MaterialState:
                                343                 :           3318 :             ExecMaterialMarkPos((MaterialState *) node);
 8701                           344                 :           3318 :             break;
                                345                 :                : 
 7801                           346                 :         289805 :         case T_SortState:
                                347                 :         289805 :             ExecSortMarkPos((SortState *) node);
 9715 bruce@momjian.us          348                 :         289805 :             break;
                                349                 :                : 
 6268 tgl@sss.pgh.pa.us         350                 :UBC           0 :         case T_ResultState:
                                351                 :              0 :             ExecResultMarkPos((ResultState *) node);
                                352                 :              0 :             break;
                                353                 :                : 
 9715 bruce@momjian.us          354                 :              0 :         default:
                                355                 :                :             /* don't make hard error unless caller asks to restore... */
 7573 tgl@sss.pgh.pa.us         356         [ #  # ]:              0 :             elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
 9715 bruce@momjian.us          357                 :              0 :             break;
                                358                 :                :     }
10141 scrappy@hub.org           359                 :CBC      358163 : }
                                360                 :                : 
                                361                 :                : /*
                                362                 :                :  * ExecRestrPos
                                363                 :                :  *
                                364                 :                :  * restores the scan position previously saved with ExecMarkPos()
                                365                 :                :  *
                                366                 :                :  * NOTE: the semantics of this are that the first ExecProcNode following
                                367                 :                :  * the restore operation will yield the same tuple as the first one following
                                368                 :                :  * the mark operation.  It is unspecified what happens to the plan node's
                                369                 :                :  * result TupleTableSlot.  (In most cases the result slot is unchanged by
                                370                 :                :  * a restore, but the node may choose to clear it or to load it with the
                                371                 :                :  * restored-to tuple.)  Hence the caller should discard any previously
                                372                 :                :  * returned TupleTableSlot after doing a restore.
                                373                 :                :  */
                                374                 :                : void
 7555 bruce@momjian.us          375                 :          70141 : ExecRestrPos(PlanState *node)
                                376                 :                : {
 9716                           377   [ +  -  -  +  :          70141 :     switch (nodeTag(node))
                                           +  -  - ]
                                378                 :                :     {
 7801 tgl@sss.pgh.pa.us         379                 :          27015 :         case T_IndexScanState:
                                380                 :          27015 :             ExecIndexRestrPos((IndexScanState *) node);
 8664                           381                 :          27015 :             break;
                                382                 :                : 
 4569 tgl@sss.pgh.pa.us         383                 :LBC         (3) :         case T_IndexOnlyScanState:
                                384                 :            (3) :             ExecIndexOnlyRestrPos((IndexOnlyScanState *) node);
                                385                 :            (3) :             break;
                                386                 :                : 
 3446 rhaas@postgresql.org      387                 :UBC           0 :         case T_CustomScanState:
                                388                 :              0 :             ExecCustomRestrPos((CustomScanState *) node);
                                389                 :              0 :             break;
                                390                 :                : 
 7801 tgl@sss.pgh.pa.us         391                 :CBC       27151 :         case T_MaterialState:
                                392                 :          27151 :             ExecMaterialRestrPos((MaterialState *) node);
 8664                           393                 :          27151 :             break;
                                394                 :                : 
 7801                           395                 :          15975 :         case T_SortState:
                                396                 :          15975 :             ExecSortRestrPos((SortState *) node);
 8664                           397                 :          15975 :             break;
                                398                 :                : 
 6268 tgl@sss.pgh.pa.us         399                 :UBC           0 :         case T_ResultState:
                                400                 :              0 :             ExecResultRestrPos((ResultState *) node);
                                401                 :              0 :             break;
                                402                 :                : 
 9715 bruce@momjian.us          403                 :              0 :         default:
 7573 tgl@sss.pgh.pa.us         404         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
                                405                 :                :             break;
                                406                 :                :     }
10141 scrappy@hub.org           407                 :CBC       70141 : }
                                408                 :                : 
                                409                 :                : /*
                                410                 :                :  * ExecSupportsMarkRestore - does a Path support mark/restore?
                                411                 :                :  *
                                412                 :                :  * This is used during planning and so must accept a Path, not a Plan.
                                413                 :                :  * We keep it here to be adjacent to the routines above, which also must
                                414                 :                :  * know which plan types support mark/restore.
                                415                 :                :  */
                                416                 :                : bool
 3446 rhaas@postgresql.org      417                 :           3064 : ExecSupportsMarkRestore(Path *pathnode)
                                418                 :                : {
                                419                 :                :     /*
                                420                 :                :      * For consistency with the routines above, we do not examine the nodeTag
                                421                 :                :      * but rather the pathtype, which is the Plan node type the Path would
                                422                 :                :      * produce.
                                423                 :                :      */
                                424   [ +  -  -  -  :           3064 :     switch (pathnode->pathtype)
                                           +  +  + ]
                                425                 :                :     {
 7806 tgl@sss.pgh.pa.us         426                 :           2565 :         case T_IndexScan:
                                427                 :                :         case T_IndexOnlyScan:
                                428                 :                : 
                                429                 :                :             /*
                                430                 :                :              * Not all index types support mark/restore.
                                431                 :                :              */
 1237 rhodiumtoad@postgres      432                 :           2565 :             return castNode(IndexPath, pathnode)->indexinfo->amcanmarkpos;
                                433                 :                : 
 7806 tgl@sss.pgh.pa.us         434                 :UBC           0 :         case T_Material:
                                435                 :                :         case T_Sort:
                                436                 :              0 :             return true;
                                437                 :                : 
 3433                           438                 :              0 :         case T_CustomScan:
 1013                           439         [ #  # ]:              0 :             if (castNode(CustomPath, pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
                                440                 :              0 :                 return true;
                                441                 :              0 :             return false;
                                442                 :                : 
 6268                           443                 :              0 :         case T_Result:
                                444                 :                : 
                                445                 :                :             /*
                                446                 :                :              * Result supports mark/restore iff it has a child plan that does.
                                447                 :                :              *
                                448                 :                :              * We have to be careful here because there is more than one Path
                                449                 :                :              * type that can produce a Result plan node.
                                450                 :                :              */
 2960                           451         [ #  # ]:              0 :             if (IsA(pathnode, ProjectionPath))
                                452                 :              0 :                 return ExecSupportsMarkRestore(((ProjectionPath *) pathnode)->subpath);
                                453         [ #  # ]:              0 :             else if (IsA(pathnode, MinMaxAggPath))
                                454                 :              0 :                 return false;   /* childless Result */
 1903                           455         [ #  # ]:              0 :             else if (IsA(pathnode, GroupResultPath))
                                456                 :              0 :                 return false;   /* childless Result */
                                457                 :                :             else
                                458                 :                :             {
                                459                 :                :                 /* Simple RTE_RESULT base relation */
                                460         [ #  # ]:              0 :                 Assert(IsA(pathnode, Path));
 2960                           461                 :              0 :                 return false;   /* childless Result */
                                462                 :                :             }
                                463                 :                : 
 1847 tgl@sss.pgh.pa.us         464                 :CBC          42 :         case T_Append:
                                465                 :                :             {
                                466                 :             42 :                 AppendPath *appendPath = castNode(AppendPath, pathnode);
                                467                 :                : 
                                468                 :                :                 /*
                                469                 :                :                  * If there's exactly one child, then there will be no Append
                                470                 :                :                  * in the final plan, so we can handle mark/restore if the
                                471                 :                :                  * child plan node can.
                                472                 :                :                  */
                                473         [ -  + ]:             42 :                 if (list_length(appendPath->subpaths) == 1)
 1847 tgl@sss.pgh.pa.us         474                 :UBC           0 :                     return ExecSupportsMarkRestore((Path *) linitial(appendPath->subpaths));
                                475                 :                :                 /* Otherwise, Append can't handle it */
 1847 tgl@sss.pgh.pa.us         476                 :CBC          42 :                 return false;
                                477                 :                :             }
                                478                 :                : 
                                479                 :             22 :         case T_MergeAppend:
                                480                 :                :             {
                                481                 :             22 :                 MergeAppendPath *mapath = castNode(MergeAppendPath, pathnode);
                                482                 :                : 
                                483                 :                :                 /*
                                484                 :                :                  * Like the Append case above, single-subpath MergeAppends
                                485                 :                :                  * won't be in the final plan, so just return the child's
                                486                 :                :                  * mark/restore ability.
                                487                 :                :                  */
                                488         [ -  + ]:             22 :                 if (list_length(mapath->subpaths) == 1)
 1847 tgl@sss.pgh.pa.us         489                 :UBC           0 :                     return ExecSupportsMarkRestore((Path *) linitial(mapath->subpaths));
                                490                 :                :                 /* Otherwise, MergeAppend can't handle it */
 1847 tgl@sss.pgh.pa.us         491                 :CBC          22 :                 return false;
                                492                 :                :             }
                                493                 :                : 
 7806                           494                 :            435 :         default:
                                495                 :            435 :             break;
                                496                 :                :     }
                                497                 :                : 
                                498                 :            435 :     return false;
                                499                 :                : }
                                500                 :                : 
                                501                 :                : /*
                                502                 :                :  * ExecSupportsBackwardScan - does a plan type support backwards scanning?
                                503                 :                :  *
                                504                 :                :  * Ideally, all plan types would support backwards scan, but that seems
                                505                 :                :  * unlikely to happen soon.  In some cases, a plan node passes the backwards
                                506                 :                :  * scan down to its children, and so supports backwards scan only if its
                                507                 :                :  * children do.  Therefore, this routine must be passed a complete plan tree.
                                508                 :                :  */
                                509                 :                : bool
 7706                           510                 :           1540 : ExecSupportsBackwardScan(Plan *node)
                                511                 :                : {
                                512         [ -  + ]:           1540 :     if (node == NULL)
 7706 tgl@sss.pgh.pa.us         513                 :UBC           0 :         return false;
                                514                 :                : 
                                515                 :                :     /*
                                516                 :                :      * Parallel-aware nodes return a subset of the tuples in each worker, and
                                517                 :                :      * in general we can't expect to have enough bookkeeping state to know
                                518                 :                :      * which ones we returned in this worker as opposed to some other worker.
                                519                 :                :      */
 3077 rhaas@postgresql.org      520         [ -  + ]:CBC        1540 :     if (node->parallel_aware)
 3077 rhaas@postgresql.org      521                 :UBC           0 :         return false;
                                522                 :                : 
 7706 tgl@sss.pgh.pa.us         523   [ +  +  +  -  :CBC        1540 :     switch (nodeTag(node))
                                     +  +  -  -  +  
                                           +  +  + ]
                                524                 :                :     {
                                525                 :             34 :         case T_Result:
                                526         [ -  + ]:             34 :             if (outerPlan(node) != NULL)
 2642 andres@anarazel.de        527                 :UBC           0 :                 return ExecSupportsBackwardScan(outerPlan(node));
                                528                 :                :             else
 7706 tgl@sss.pgh.pa.us         529                 :CBC          34 :                 return false;
                                530                 :                : 
                                531                 :             20 :         case T_Append:
                                532                 :                :             {
                                533                 :                :                 ListCell   *l;
                                534                 :                : 
                                535                 :                :                 /* With async, tuples may be interleaved, so can't back up. */
 1110 efujita@postgresql.o      536         [ -  + ]:             20 :                 if (((Append *) node)->nasyncplans > 0)
 1110 efujita@postgresql.o      537                 :UBC           0 :                     return false;
                                538                 :                : 
 7559 bruce@momjian.us          539   [ +  -  +  +  :CBC          68 :                 foreach(l, ((Append *) node)->appendplans)
                                              +  + ]
                                540                 :                :                 {
                                541         [ +  + ]:             49 :                     if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
                                542                 :              1 :                         return false;
                                543                 :                :                 }
                                544                 :                :                 /* need not check tlist because Append doesn't evaluate it */
                                545                 :             19 :                 return true;
                                546                 :                :             }
                                547                 :                : 
 3186 tgl@sss.pgh.pa.us         548                 :              3 :         case T_SampleScan:
                                549                 :                :             /* Simplify life for tablesample methods by disallowing this */
                                550                 :              3 :             return false;
                                551                 :                : 
 3119 rhaas@postgresql.org      552                 :UBC           0 :         case T_Gather:
                                553                 :              0 :             return false;
                                554                 :                : 
 5658 tgl@sss.pgh.pa.us         555                 :CBC         205 :         case T_IndexScan:
 2642 andres@anarazel.de        556                 :            205 :             return IndexSupportsBackwardScan(((IndexScan *) node)->indexid);
                                557                 :                : 
 4569 tgl@sss.pgh.pa.us         558                 :             25 :         case T_IndexOnlyScan:
 2642 andres@anarazel.de        559                 :             25 :             return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid);
                                560                 :                : 
 7706 tgl@sss.pgh.pa.us         561                 :UBC           0 :         case T_SubqueryScan:
 2642 andres@anarazel.de        562                 :              0 :             return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
                                563                 :                : 
 3446 rhaas@postgresql.org      564                 :              0 :         case T_CustomScan:
 1013 tgl@sss.pgh.pa.us         565         [ #  # ]:              0 :             if (((CustomScan *) node)->flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN)
                                566                 :              0 :                 return true;
 3446 rhaas@postgresql.org      567                 :              0 :             return false;
                                568                 :                : 
 2642 andres@anarazel.de        569                 :CBC         828 :         case T_SeqScan:
                                570                 :                :         case T_TidScan:
                                571                 :                :         case T_TidRangeScan:
                                572                 :                :         case T_FunctionScan:
                                573                 :                :         case T_ValuesScan:
                                574                 :                :         case T_CteScan:
                                575                 :                :         case T_Material:
                                576                 :                :         case T_Sort:
                                577                 :                :             /* these don't evaluate tlist */
 7706 tgl@sss.pgh.pa.us         578                 :            828 :             return true;
                                579                 :                : 
 1469 tomas.vondra@postgre      580                 :              2 :         case T_IncrementalSort:
                                581                 :                : 
                                582                 :                :             /*
                                583                 :                :              * Unlike full sort, incremental sort keeps only a single group of
                                584                 :                :              * tuples in memory, so it can't scan backwards.
                                585                 :                :              */
                                586                 :              2 :             return false;
                                587                 :                : 
 5298 tgl@sss.pgh.pa.us         588                 :             72 :         case T_LockRows:
                                589                 :                :         case T_Limit:
 7706                           590                 :             72 :             return ExecSupportsBackwardScan(outerPlan(node));
                                591                 :                : 
                                592                 :            351 :         default:
                                593                 :            351 :             return false;
                                594                 :                :     }
                                595                 :                : }
                                596                 :                : 
                                597                 :                : /*
                                598                 :                :  * An IndexScan or IndexOnlyScan node supports backward scan only if the
                                599                 :                :  * index's AM does.
                                600                 :                :  */
                                601                 :                : static bool
 5658                           602                 :            230 : IndexSupportsBackwardScan(Oid indexid)
                                603                 :                : {
                                604                 :                :     bool        result;
                                605                 :                :     HeapTuple   ht_idxrel;
                                606                 :                :     Form_pg_class idxrelrec;
                                607                 :                :     IndexAmRoutine *amroutine;
                                608                 :                : 
                                609                 :                :     /* Fetch the pg_class tuple of the index relation */
 5173 rhaas@postgresql.org      610                 :            230 :     ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
 5658 tgl@sss.pgh.pa.us         611         [ -  + ]:            230 :     if (!HeapTupleIsValid(ht_idxrel))
 5658 tgl@sss.pgh.pa.us         612         [ #  # ]:UBC           0 :         elog(ERROR, "cache lookup failed for relation %u", indexid);
 5658 tgl@sss.pgh.pa.us         613                 :CBC         230 :     idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
                                614                 :                : 
                                615                 :                :     /* Fetch the index AM's API struct */
 2801                           616                 :            230 :     amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
                                617                 :                : 
 3010                           618                 :            230 :     result = amroutine->amcanbackward;
                                619                 :                : 
                                620                 :            230 :     pfree(amroutine);
 5658                           621                 :            230 :     ReleaseSysCache(ht_idxrel);
                                622                 :                : 
                                623                 :            230 :     return result;
                                624                 :                : }
                                625                 :                : 
                                626                 :                : /*
                                627                 :                :  * ExecMaterializesOutput - does a plan type materialize its output?
                                628                 :                :  *
                                629                 :                :  * Returns true if the plan node type is one that automatically materializes
                                630                 :                :  * its output (typically by keeping it in a tuplestore).  For such plans,
                                631                 :                :  * a rescan without any parameter change will have zero startup cost and
                                632                 :                :  * very low per-tuple cost.
                                633                 :                :  */
                                634                 :                : bool
 5328                           635                 :         227971 : ExecMaterializesOutput(NodeTag plantype)
                                636                 :                : {
                                637         [ +  + ]:         227971 :     switch (plantype)
                                638                 :                :     {
                                639                 :          11529 :         case T_Material:
                                640                 :                :         case T_FunctionScan:
                                641                 :                :         case T_TableFuncScan:
                                642                 :                :         case T_CteScan:
                                643                 :                :         case T_NamedTuplestoreScan:
                                644                 :                :         case T_WorkTableScan:
                                645                 :                :         case T_Sort:
                                646                 :          11529 :             return true;
                                647                 :                : 
                                648                 :         216442 :         default:
                                649                 :         216442 :             break;
                                650                 :                :     }
                                651                 :                : 
                                652                 :         216442 :     return false;
                                653                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622