LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeTidscan.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 90.6 % 171 155 16 155 4
Current Date: 2024-04-14 14:21:10 Functions: 88.9 % 9 8 1 1 7
Baseline: 16@8cea358b128 Branches: 71.2 % 118 84 34 84
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: 90.6 % 171 155 16 155
Function coverage date bins:
(240..) days: 88.9 % 9 8 1 1 7
Branch coverage date bins:
(240..) days: 71.2 % 118 84 34 84

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * nodeTidscan.c
                                  4                 :                :  *    Routines to support direct tid scans of relations
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/backend/executor/nodeTidscan.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : /*
                                 16                 :                :  * INTERFACE ROUTINES
                                 17                 :                :  *
                                 18                 :                :  *      ExecTidScan         scans a relation using tids
                                 19                 :                :  *      ExecInitTidScan     creates and initializes state info.
                                 20                 :                :  *      ExecReScanTidScan   rescans the tid relation.
                                 21                 :                :  *      ExecEndTidScan      releases all storage.
                                 22                 :                :  */
                                 23                 :                : #include "postgres.h"
                                 24                 :                : 
                                 25                 :                : #include "access/sysattr.h"
                                 26                 :                : #include "access/tableam.h"
                                 27                 :                : #include "catalog/pg_type.h"
                                 28                 :                : #include "executor/executor.h"
                                 29                 :                : #include "executor/nodeTidscan.h"
                                 30                 :                : #include "lib/qunique.h"
                                 31                 :                : #include "miscadmin.h"
                                 32                 :                : #include "nodes/nodeFuncs.h"
                                 33                 :                : #include "utils/array.h"
                                 34                 :                : #include "utils/rel.h"
                                 35                 :                : 
                                 36                 :                : 
                                 37                 :                : /*
                                 38                 :                :  * It's sufficient to check varattno to identify the CTID variable, as any
                                 39                 :                :  * Var in the relation scan qual must be for our table.  (Even if it's a
                                 40                 :                :  * parameterized scan referencing some other table's CTID, the other table's
                                 41                 :                :  * Var would have become a Param by the time it gets here.)
                                 42                 :                :  */
                                 43                 :                : #define IsCTIDVar(node)  \
                                 44                 :                :     ((node) != NULL && \
                                 45                 :                :      IsA((node), Var) && \
                                 46                 :                :      ((Var *) (node))->varattno == SelfItemPointerAttributeNumber)
                                 47                 :                : 
                                 48                 :                : /* one element in tss_tidexprs */
                                 49                 :                : typedef struct TidExpr
                                 50                 :                : {
                                 51                 :                :     ExprState  *exprstate;      /* ExprState for a TID-yielding subexpr */
                                 52                 :                :     bool        isarray;        /* if true, it yields tid[] not just tid */
                                 53                 :                :     CurrentOfExpr *cexpr;       /* alternatively, we can have CURRENT OF */
                                 54                 :                : } TidExpr;
                                 55                 :                : 
                                 56                 :                : static void TidExprListCreate(TidScanState *tidstate);
                                 57                 :                : static void TidListEval(TidScanState *tidstate);
                                 58                 :                : static int  itemptr_comparator(const void *a, const void *b);
                                 59                 :                : static TupleTableSlot *TidNext(TidScanState *node);
                                 60                 :                : 
                                 61                 :                : 
                                 62                 :                : /*
                                 63                 :                :  * Extract the qual subexpressions that yield TIDs to search for,
                                 64                 :                :  * and compile them into ExprStates if they're ordinary expressions.
                                 65                 :                :  *
                                 66                 :                :  * CURRENT OF is a special case that we can't compile usefully;
                                 67                 :                :  * just drop it into the TidExpr list as-is.
                                 68                 :                :  */
                                 69                 :                : static void
 2588 andres@anarazel.de         70                 :CBC         359 : TidExprListCreate(TidScanState *tidstate)
                                 71                 :                : {
                                 72                 :            359 :     TidScan    *node = (TidScan *) tidstate->ss.ps.plan;
                                 73                 :                :     ListCell   *l;
                                 74                 :                : 
                                 75                 :            359 :     tidstate->tss_tidexprs = NIL;
                                 76                 :            359 :     tidstate->tss_isCurrentOf = false;
                                 77                 :                : 
                                 78   [ +  -  +  +  :            730 :     foreach(l, node->tidquals)
                                              +  + ]
                                 79                 :                :     {
                                 80                 :            371 :         Expr       *expr = (Expr *) lfirst(l);
                                 81                 :            371 :         TidExpr    *tidexpr = (TidExpr *) palloc0(sizeof(TidExpr));
                                 82                 :                : 
                                 83         [ +  + ]:            371 :         if (is_opclause(expr))
                                 84                 :                :         {
                                 85                 :                :             Node       *arg1;
                                 86                 :                :             Node       *arg2;
                                 87                 :                : 
                                 88                 :            136 :             arg1 = get_leftop(expr);
                                 89                 :            136 :             arg2 = get_rightop(expr);
                                 90   [ +  -  +  +  :            136 :             if (IsCTIDVar(arg1))
                                              +  - ]
                                 91                 :            112 :                 tidexpr->exprstate = ExecInitExpr((Expr *) arg2,
                                 92                 :                :                                                   &tidstate->ss.ps);
                                 93   [ +  -  +  -  :             24 :             else if (IsCTIDVar(arg2))
                                              +  - ]
                                 94                 :             24 :                 tidexpr->exprstate = ExecInitExpr((Expr *) arg1,
                                 95                 :                :                                                   &tidstate->ss.ps);
                                 96                 :                :             else
 2588 andres@anarazel.de         97         [ #  # ]:UBC           0 :                 elog(ERROR, "could not identify CTID variable");
 2588 andres@anarazel.de         98                 :CBC         136 :             tidexpr->isarray = false;
                                 99                 :                :         }
                                100   [ +  -  +  + ]:            235 :         else if (expr && IsA(expr, ScalarArrayOpExpr))
                                101                 :             15 :         {
                                102                 :             15 :             ScalarArrayOpExpr *saex = (ScalarArrayOpExpr *) expr;
                                103                 :                : 
                                104   [ +  -  +  -  :             15 :             Assert(IsCTIDVar(linitial(saex->args)));
                                              -  + ]
                                105                 :             15 :             tidexpr->exprstate = ExecInitExpr(lsecond(saex->args),
                                106                 :                :                                               &tidstate->ss.ps);
                                107                 :             15 :             tidexpr->isarray = true;
                                108                 :                :         }
                                109   [ +  -  +  - ]:            220 :         else if (expr && IsA(expr, CurrentOfExpr))
                                110                 :            220 :         {
                                111                 :            220 :             CurrentOfExpr *cexpr = (CurrentOfExpr *) expr;
                                112                 :                : 
                                113                 :            220 :             tidexpr->cexpr = cexpr;
                                114                 :            220 :             tidstate->tss_isCurrentOf = true;
                                115                 :                :         }
                                116                 :                :         else
 2588 andres@anarazel.de        117         [ #  # ]:UBC           0 :             elog(ERROR, "could not identify CTID expression");
                                118                 :                : 
 2588 andres@anarazel.de        119                 :CBC         371 :         tidstate->tss_tidexprs = lappend(tidstate->tss_tidexprs, tidexpr);
                                120                 :                :     }
                                121                 :                : 
                                122                 :                :     /* CurrentOfExpr could never appear OR'd with something else */
                                123   [ +  +  -  + ]:            359 :     Assert(list_length(tidstate->tss_tidexprs) == 1 ||
                                124                 :                :            !tidstate->tss_isCurrentOf);
                                125                 :            359 : }
                                126                 :                : 
                                127                 :                : /*
                                128                 :                :  * Compute the list of TIDs to be visited, by evaluating the expressions
                                129                 :                :  * for them.
                                130                 :                :  *
                                131                 :                :  * (The result is actually an array, not a list.)
                                132                 :                :  */
                                133                 :                : static void
                                134                 :            314 : TidListEval(TidScanState *tidstate)
                                135                 :                : {
 7506 tgl@sss.pgh.pa.us         136                 :            314 :     ExprContext *econtext = tidstate->ss.ps.ps_ExprContext;
                                137                 :                :     TableScanDesc scan;
                                138                 :                :     ItemPointerData *tidList;
                                139                 :                :     int         numAllocTids;
                                140                 :                :     int         numTids;
                                141                 :                :     ListCell   *l;
                                142                 :                : 
                                143                 :                :     /*
                                144                 :                :      * Start scan on-demand - initializing a scan isn't free (e.g. heap stats
                                145                 :                :      * the size of the table), so it makes sense to delay that until needed -
                                146                 :                :      * the node might never get executed.
                                147                 :                :      */
 1794 andres@anarazel.de        148         [ +  + ]:            314 :     if (tidstate->ss.ss_currentScanDesc == NULL)
                                149                 :            311 :         tidstate->ss.ss_currentScanDesc =
 1528 fujii@postgresql.org      150                 :            311 :             table_beginscan_tid(tidstate->ss.ss_currentRelation,
 1431 tgl@sss.pgh.pa.us         151                 :            311 :                                 tidstate->ss.ps.state->es_snapshot);
 1794 andres@anarazel.de        152                 :            314 :     scan = tidstate->ss.ss_currentScanDesc;
                                153                 :                : 
                                154                 :                :     /*
                                155                 :                :      * We initialize the array with enough slots for the case that all quals
                                156                 :                :      * are simple OpExprs or CurrentOfExprs.  If there are any
                                157                 :                :      * ScalarArrayOpExprs, we may have to enlarge the array.
                                158                 :                :      */
 2588                           159                 :            314 :     numAllocTids = list_length(tidstate->tss_tidexprs);
                                160                 :                :     tidList = (ItemPointerData *)
 6714 tgl@sss.pgh.pa.us         161                 :            314 :         palloc(numAllocTids * sizeof(ItemPointerData));
                                162                 :            314 :     numTids = 0;
                                163                 :                : 
 2588 andres@anarazel.de        164   [ +  -  +  +  :            604 :     foreach(l, tidstate->tss_tidexprs)
                                              +  + ]
                                165                 :                :     {
                                166                 :            320 :         TidExpr    *tidexpr = (TidExpr *) lfirst(l);
                                167                 :                :         ItemPointer itemptr;
                                168                 :                :         bool        isNull;
                                169                 :                : 
                                170   [ +  +  +  + ]:            320 :         if (tidexpr->exprstate && !tidexpr->isarray)
                                171                 :                :         {
                                172                 :                :             itemptr = (ItemPointer)
                                173                 :            115 :                 DatumGetPointer(ExecEvalExprSwitchContext(tidexpr->exprstate,
                                174                 :                :                                                           econtext,
                                175                 :                :                                                           &isNull));
 1794                           176         [ -  + ]:            115 :             if (isNull)
 1794 andres@anarazel.de        177                 :UBC           0 :                 continue;
                                178                 :                : 
                                179                 :                :             /*
                                180                 :                :              * We silently discard any TIDs that the AM considers invalid
                                181                 :                :              * (E.g. for heap, they could be out of range at the time of scan
                                182                 :                :              * start.  Since we hold at least AccessShareLock on the table, it
                                183                 :                :              * won't be possible for someone to truncate away the blocks we
                                184                 :                :              * intend to visit.).
                                185                 :                :              */
 1794 andres@anarazel.de        186         [ -  + ]:CBC         115 :             if (!table_tuple_tid_valid(scan, itemptr))
 1794 andres@anarazel.de        187                 :UBC           0 :                 continue;
                                188                 :                : 
 1794 andres@anarazel.de        189         [ +  + ]:CBC         115 :             if (numTids >= numAllocTids)
                                190                 :                :             {
                                191                 :              3 :                 numAllocTids *= 2;
                                192                 :                :                 tidList = (ItemPointerData *)
                                193                 :              3 :                     repalloc(tidList,
                                194                 :                :                              numAllocTids * sizeof(ItemPointerData));
                                195                 :                :             }
                                196                 :            115 :             tidList[numTids++] = *itemptr;
                                197                 :                :         }
 2588                           198   [ +  +  +  - ]:            205 :         else if (tidexpr->exprstate && tidexpr->isarray)
 6714 tgl@sss.pgh.pa.us         199                 :             12 :         {
                                200                 :                :             Datum       arraydatum;
                                201                 :                :             ArrayType  *itemarray;
                                202                 :                :             Datum      *ipdatums;
                                203                 :                :             bool       *ipnulls;
                                204                 :                :             int         ndatums;
                                205                 :                :             int         i;
                                206                 :                : 
 2588 andres@anarazel.de        207                 :             12 :             arraydatum = ExecEvalExprSwitchContext(tidexpr->exprstate,
                                208                 :                :                                                    econtext,
                                209                 :                :                                                    &isNull);
 6714 tgl@sss.pgh.pa.us         210         [ -  + ]:             12 :             if (isNull)
 6714 tgl@sss.pgh.pa.us         211                 :UBC           0 :                 continue;
 6714 tgl@sss.pgh.pa.us         212                 :CBC          12 :             itemarray = DatumGetArrayTypeP(arraydatum);
  653 peter@eisentraut.org      213                 :             12 :             deconstruct_array_builtin(itemarray, TIDOID, &ipdatums, &ipnulls, &ndatums);
 6714 tgl@sss.pgh.pa.us         214         [ +  + ]:             12 :             if (numTids + ndatums > numAllocTids)
                                215                 :                :             {
                                216                 :              9 :                 numAllocTids = numTids + ndatums;
                                217                 :                :                 tidList = (ItemPointerData *)
                                218                 :              9 :                     repalloc(tidList,
                                219                 :                :                              numAllocTids * sizeof(ItemPointerData));
                                220                 :                :             }
                                221         [ +  + ]:             36 :             for (i = 0; i < ndatums; i++)
                                222                 :                :             {
 1794 andres@anarazel.de        223         [ -  + ]:             24 :                 if (ipnulls[i])
 1794 andres@anarazel.de        224                 :UBC           0 :                     continue;
                                225                 :                : 
 1794 andres@anarazel.de        226                 :CBC          24 :                 itemptr = (ItemPointer) DatumGetPointer(ipdatums[i]);
                                227                 :                : 
                                228         [ -  + ]:             24 :                 if (!table_tuple_tid_valid(scan, itemptr))
 1794 andres@anarazel.de        229                 :UBC           0 :                     continue;
                                230                 :                : 
 1794 andres@anarazel.de        231                 :CBC          24 :                 tidList[numTids++] = *itemptr;
                                232                 :                :             }
 6714 tgl@sss.pgh.pa.us         233                 :             12 :             pfree(ipdatums);
                                234                 :             12 :             pfree(ipnulls);
                                235                 :                :         }
                                236                 :                :         else
                                237                 :                :         {
                                238                 :                :             ItemPointerData cursor_tid;
                                239                 :                : 
 2588 andres@anarazel.de        240         [ -  + ]:            193 :             Assert(tidexpr->cexpr);
                                241         [ +  + ]:            163 :             if (execCurrentOf(tidexpr->cexpr, econtext,
 2489 tgl@sss.pgh.pa.us         242                 :            193 :                               RelationGetRelid(tidstate->ss.ss_currentRelation),
                                243                 :                :                               &cursor_tid))
                                244                 :                :             {
 6152                           245         [ -  + ]:            138 :                 if (numTids >= numAllocTids)
                                246                 :                :                 {
 6152 tgl@sss.pgh.pa.us         247                 :UBC           0 :                     numAllocTids *= 2;
                                248                 :                :                     tidList = (ItemPointerData *)
                                249                 :              0 :                         repalloc(tidList,
                                250                 :                :                                  numAllocTids * sizeof(ItemPointerData));
                                251                 :                :                 }
 6152 tgl@sss.pgh.pa.us         252                 :CBC         138 :                 tidList[numTids++] = cursor_tid;
                                253                 :                :             }
                                254                 :                :         }
                                255                 :                :     }
                                256                 :                : 
                                257                 :                :     /*
                                258                 :                :      * Sort the array of TIDs into order, and eliminate duplicates.
                                259                 :                :      * Eliminating duplicates is necessary since we want OR semantics across
                                260                 :                :      * the list.  Sorting makes it easier to detect duplicates, and as a bonus
                                261                 :                :      * ensures that we will visit the heap in the most efficient way.
                                262                 :                :      */
 6714                           263         [ +  + ]:            284 :     if (numTids > 1)
                                264                 :                :     {
                                265                 :                :         /* CurrentOfExpr could never appear OR'd with something else */
 6017                           266         [ -  + ]:             15 :         Assert(!tidstate->tss_isCurrentOf);
                                267                 :                : 
  432 peter@eisentraut.org      268                 :             15 :         qsort(tidList, numTids, sizeof(ItemPointerData),
                                269                 :                :               itemptr_comparator);
 1620 tmunro@postgresql.or      270                 :             15 :         numTids = qunique(tidList, numTids, sizeof(ItemPointerData),
                                271                 :                :                           itemptr_comparator);
                                272                 :                :     }
                                273                 :                : 
 7506 tgl@sss.pgh.pa.us         274                 :            284 :     tidstate->tss_TidList = tidList;
                                275                 :            284 :     tidstate->tss_NumTids = numTids;
                                276                 :            284 :     tidstate->tss_TidPtr = -1;
 8909 bruce@momjian.us          277                 :            284 : }
                                278                 :                : 
                                279                 :                : /*
                                280                 :                :  * qsort comparator for ItemPointerData items
                                281                 :                :  */
                                282                 :                : static int
 6714 tgl@sss.pgh.pa.us         283                 :             39 : itemptr_comparator(const void *a, const void *b)
                                284                 :                : {
                                285                 :             39 :     const ItemPointerData *ipa = (const ItemPointerData *) a;
                                286                 :             39 :     const ItemPointerData *ipb = (const ItemPointerData *) b;
 6402 bruce@momjian.us          287                 :             39 :     BlockNumber ba = ItemPointerGetBlockNumber(ipa);
                                288                 :             39 :     BlockNumber bb = ItemPointerGetBlockNumber(ipb);
 6714 tgl@sss.pgh.pa.us         289                 :             39 :     OffsetNumber oa = ItemPointerGetOffsetNumber(ipa);
                                290                 :             39 :     OffsetNumber ob = ItemPointerGetOffsetNumber(ipb);
                                291                 :                : 
                                292         [ -  + ]:             39 :     if (ba < bb)
 6714 tgl@sss.pgh.pa.us         293                 :UBC           0 :         return -1;
 6714 tgl@sss.pgh.pa.us         294         [ -  + ]:CBC          39 :     if (ba > bb)
 6714 tgl@sss.pgh.pa.us         295                 :UBC           0 :         return 1;
 6714 tgl@sss.pgh.pa.us         296         [ +  + ]:CBC          39 :     if (oa < ob)
                                297                 :             12 :         return -1;
                                298         [ +  - ]:             27 :     if (oa > ob)
                                299                 :             27 :         return 1;
 6714 tgl@sss.pgh.pa.us         300                 :UBC           0 :     return 0;
                                301                 :                : }
                                302                 :                : 
                                303                 :                : /* ----------------------------------------------------------------
                                304                 :                :  *      TidNext
                                305                 :                :  *
                                306                 :                :  *      Retrieve a tuple from the TidScan node's currentRelation
                                307                 :                :  *      using the tids in the TidScanState information.
                                308                 :                :  *
                                309                 :                :  * ----------------------------------------------------------------
                                310                 :                :  */
                                311                 :                : static TupleTableSlot *
 7801 tgl@sss.pgh.pa.us         312                 :CBC         573 : TidNext(TidScanState *node)
                                313                 :                : {
                                314                 :                :     EState     *estate;
                                315                 :                :     ScanDirection direction;
                                316                 :                :     Snapshot    snapshot;
                                317                 :                :     TableScanDesc scan;
                                318                 :                :     Relation    heapRelation;
                                319                 :                :     TupleTableSlot *slot;
                                320                 :                :     ItemPointerData *tidList;
                                321                 :                :     int         numTids;
                                322                 :                :     bool        bBackward;
                                323                 :                : 
                                324                 :                :     /*
                                325                 :                :      * extract necessary information from tid scan node
                                326                 :                :      */
                                327                 :            573 :     estate = node->ss.ps.state;
 8909 bruce@momjian.us          328                 :            573 :     direction = estate->es_direction;
                                329                 :            573 :     snapshot = estate->es_snapshot;
 7801 tgl@sss.pgh.pa.us         330                 :            573 :     heapRelation = node->ss.ss_currentRelation;
                                331                 :            573 :     slot = node->ss.ss_ScanTupleSlot;
                                332                 :                : 
                                333                 :                :     /*
                                334                 :                :      * First time through, compute the list of TIDs to be visited
                                335                 :                :      */
 7506                           336         [ +  + ]:            573 :     if (node->tss_TidList == NULL)
 2588 andres@anarazel.de        337                 :            314 :         TidListEval(node);
                                338                 :                : 
 1794                           339                 :            543 :     scan = node->ss.ss_currentScanDesc;
 7506 tgl@sss.pgh.pa.us         340                 :            543 :     tidList = node->tss_TidList;
                                341                 :            543 :     numTids = node->tss_NumTids;
                                342                 :                : 
                                343                 :                :     /*
                                344                 :                :      * Initialize or advance scan position, depending on direction.
                                345                 :                :      */
 8909 bruce@momjian.us          346                 :            543 :     bBackward = ScanDirectionIsBackward(direction);
                                347         [ +  + ]:            543 :     if (bBackward)
                                348                 :                :     {
 6714 tgl@sss.pgh.pa.us         349         [ -  + ]:              3 :         if (node->tss_TidPtr < 0)
                                350                 :                :         {
                                351                 :                :             /* initialize for backward scan */
 7801 tgl@sss.pgh.pa.us         352                 :UBC           0 :             node->tss_TidPtr = numTids - 1;
                                353                 :                :         }
                                354                 :                :         else
 6714 tgl@sss.pgh.pa.us         355                 :CBC           3 :             node->tss_TidPtr--;
                                356                 :                :     }
                                357                 :                :     else
                                358                 :                :     {
                                359         [ +  + ]:            540 :         if (node->tss_TidPtr < 0)
                                360                 :                :         {
                                361                 :                :             /* initialize for forward scan */
 7801                           362                 :            284 :             node->tss_TidPtr = 0;
                                363                 :                :         }
                                364                 :                :         else
 6714                           365                 :            256 :             node->tss_TidPtr++;
                                366                 :                :     }
                                367                 :                : 
                                368   [ +  -  +  + ]:            558 :     while (node->tss_TidPtr >= 0 && node->tss_TidPtr < numTids)
                                369                 :                :     {
 1847 andres@anarazel.de        370                 :            277 :         ItemPointerData tid = tidList[node->tss_TidPtr];
                                371                 :                : 
                                372                 :                :         /*
                                373                 :                :          * For WHERE CURRENT OF, the tuple retrieved from the cursor might
                                374                 :                :          * since have been updated; if so, we should fetch the version that is
                                375                 :                :          * current according to our snapshot.
                                376                 :                :          */
 6017 tgl@sss.pgh.pa.us         377         [ +  + ]:            277 :         if (node->tss_isCurrentOf)
 1788 andres@anarazel.de        378                 :            138 :             table_tuple_get_latest_tid(scan, &tid);
                                379                 :                : 
                                380         [ +  + ]:            277 :         if (table_tuple_fetch_row_version(heapRelation, &tid, snapshot, slot))
 6714 tgl@sss.pgh.pa.us         381                 :            262 :             return slot;
                                382                 :                : 
                                383                 :                :         /* Bad TID or failed snapshot qual; try next */
 8909 bruce@momjian.us          384         [ -  + ]:             15 :         if (bBackward)
 7801 tgl@sss.pgh.pa.us         385                 :UBC           0 :             node->tss_TidPtr--;
                                386                 :                :         else
 7801 tgl@sss.pgh.pa.us         387                 :CBC          15 :             node->tss_TidPtr++;
                                388                 :                : 
 2455 andres@anarazel.de        389         [ -  + ]:             15 :         CHECK_FOR_INTERRUPTS();
                                390                 :                :     }
                                391                 :                : 
                                392                 :                :     /*
                                393                 :                :      * if we get here it means the tid scan failed so we are at the end of the
                                394                 :                :      * scan..
                                395                 :                :      */
 8909 bruce@momjian.us          396                 :            281 :     return ExecClearTuple(slot);
                                397                 :                : }
                                398                 :                : 
                                399                 :                : /*
                                400                 :                :  * TidRecheck -- access method routine to recheck a tuple in EvalPlanQual
                                401                 :                :  */
                                402                 :                : static bool
 5284 tgl@sss.pgh.pa.us         403                 :UBC           0 : TidRecheck(TidScanState *node, TupleTableSlot *slot)
                                404                 :                : {
                                405                 :                :     /*
                                406                 :                :      * XXX shouldn't we check here to make sure tuple matches TID list? In
                                407                 :                :      * runtime-key case this is not certain, is it?  However, in the WHERE
                                408                 :                :      * CURRENT OF case it might not match anyway ...
                                409                 :                :      */
                                410                 :              0 :     return true;
                                411                 :                : }
                                412                 :                : 
                                413                 :                : 
                                414                 :                : /* ----------------------------------------------------------------
                                415                 :                :  *      ExecTidScan(node)
                                416                 :                :  *
                                417                 :                :  *      Scans the relation using tids and returns
                                418                 :                :  *         the next qualifying tuple in the direction specified.
                                419                 :                :  *      We call the ExecScan() routine and pass it the appropriate
                                420                 :                :  *      access method functions.
                                421                 :                :  *
                                422                 :                :  *      Conditions:
                                423                 :                :  *        -- the "cursor" maintained by the AMI is positioned at the tuple
                                424                 :                :  *           returned previously.
                                425                 :                :  *
                                426                 :                :  *      Initial States:
                                427                 :                :  *        -- the relation indicated is opened for scanning so that the
                                428                 :                :  *           "cursor" is positioned before the first qualifying tuple.
                                429                 :                :  *        -- tss_TidPtr is -1.
                                430                 :                :  * ----------------------------------------------------------------
                                431                 :                :  */
                                432                 :                : static TupleTableSlot *
 2463 andres@anarazel.de        433                 :CBC         564 : ExecTidScan(PlanState *pstate)
                                434                 :                : {
                                435                 :            564 :     TidScanState *node = castNode(TidScanState, pstate);
                                436                 :                : 
 5284 tgl@sss.pgh.pa.us         437                 :            564 :     return ExecScan(&node->ss,
                                438                 :                :                     (ExecScanAccessMtd) TidNext,
                                439                 :                :                     (ExecScanRecheckMtd) TidRecheck);
                                440                 :                : }
                                441                 :                : 
                                442                 :                : /* ----------------------------------------------------------------
                                443                 :                :  *      ExecReScanTidScan(node)
                                444                 :                :  * ----------------------------------------------------------------
                                445                 :                :  */
                                446                 :                : void
 5025                           447                 :              9 : ExecReScanTidScan(TidScanState *node)
                                448                 :                : {
 7506                           449         [ +  + ]:              9 :     if (node->tss_TidList)
                                450                 :              3 :         pfree(node->tss_TidList);
                                451                 :              9 :     node->tss_TidList = NULL;
                                452                 :              9 :     node->tss_NumTids = 0;
 7801                           453                 :              9 :     node->tss_TidPtr = -1;
                                454                 :                : 
                                455                 :                :     /* not really necessary, but seems good form */
 1794 andres@anarazel.de        456         [ +  + ]:              9 :     if (node->ss.ss_currentScanDesc)
                                457                 :              3 :         table_rescan(node->ss.ss_currentScanDesc, NULL);
                                458                 :                : 
 5284 tgl@sss.pgh.pa.us         459                 :              9 :     ExecScanReScan(&node->ss);
 8909 bruce@momjian.us          460                 :              9 : }
                                461                 :                : 
                                462                 :                : /* ----------------------------------------------------------------
                                463                 :                :  *      ExecEndTidScan
                                464                 :                :  *
                                465                 :                :  *      Releases any storage allocated through C routines.
                                466                 :                :  *      Returns nothing.
                                467                 :                :  * ----------------------------------------------------------------
                                468                 :                :  */
                                469                 :                : void
 7801 tgl@sss.pgh.pa.us         470                 :            299 : ExecEndTidScan(TidScanState *node)
                                471                 :                : {
 1794 andres@anarazel.de        472         [ +  + ]:            299 :     if (node->ss.ss_currentScanDesc)
                                473                 :            275 :         table_endscan(node->ss.ss_currentScanDesc);
 8909 bruce@momjian.us          474                 :            299 : }
                                475                 :                : 
                                476                 :                : /* ----------------------------------------------------------------
                                477                 :                :  *      ExecInitTidScan
                                478                 :                :  *
                                479                 :                :  *      Initializes the tid scan's state information, creates
                                480                 :                :  *      scan keys, and opens the base and tid relations.
                                481                 :                :  *
                                482                 :                :  *      Parameters:
                                483                 :                :  *        node: TidScan node produced by the planner.
                                484                 :                :  *        estate: the execution state initialized in InitPlan.
                                485                 :                :  * ----------------------------------------------------------------
                                486                 :                :  */
                                487                 :                : TidScanState *
 6620 tgl@sss.pgh.pa.us         488                 :            359 : ExecInitTidScan(TidScan *node, EState *estate, int eflags)
                                489                 :                : {
                                490                 :                :     TidScanState *tidstate;
                                491                 :                :     Relation    currentRelation;
                                492                 :                : 
                                493                 :                :     /*
                                494                 :                :      * create state structure
                                495                 :                :      */
 7801                           496                 :            359 :     tidstate = makeNode(TidScanState);
                                497                 :            359 :     tidstate->ss.ps.plan = (Plan *) node;
                                498                 :            359 :     tidstate->ss.ps.state = estate;
 2463 andres@anarazel.de        499                 :            359 :     tidstate->ss.ps.ExecProcNode = ExecTidScan;
                                500                 :                : 
                                501                 :                :     /*
                                502                 :                :      * Miscellaneous initialization
                                503                 :                :      *
                                504                 :                :      * create expression context for node
                                505                 :                :      */
 7801 tgl@sss.pgh.pa.us         506                 :            359 :     ExecAssignExprContext(estate, &tidstate->ss.ps);
                                507                 :                : 
                                508                 :                :     /*
                                509                 :                :      * mark tid list as not computed yet
                                510                 :                :      */
 7506                           511                 :            359 :     tidstate->tss_TidList = NULL;
                                512                 :            359 :     tidstate->tss_NumTids = 0;
                                513                 :            359 :     tidstate->tss_TidPtr = -1;
                                514                 :                : 
                                515                 :                :     /*
                                516                 :                :      * open the scan relation
                                517                 :                :      */
 4005                           518                 :            359 :     currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
                                519                 :                : 
 7801                           520                 :            359 :     tidstate->ss.ss_currentRelation = currentRelation;
 2489                           521                 :            359 :     tidstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
                                522                 :                : 
                                523                 :                :     /*
                                524                 :                :      * get the scan type from the relation descriptor.
                                525                 :                :      */
 2249 andres@anarazel.de        526                 :            359 :     ExecInitScanTupleSlot(estate, &tidstate->ss,
                                527                 :                :                           RelationGetDescr(currentRelation),
                                528                 :                :                           table_slot_callbacks(currentRelation));
                                529                 :                : 
                                530                 :                :     /*
                                531                 :                :      * Initialize result type and projection.
                                532                 :                :      */
 1983                           533                 :            359 :     ExecInitResultTypeTL(&tidstate->ss.ps);
 7741 tgl@sss.pgh.pa.us         534                 :            359 :     ExecAssignScanProjectionInfo(&tidstate->ss);
                                535                 :                : 
                                536                 :                :     /*
                                537                 :                :      * initialize child expressions
                                538                 :                :      */
 2249 andres@anarazel.de        539                 :            359 :     tidstate->ss.ps.qual =
                                540                 :            359 :         ExecInitQual(node->scan.plan.qual, (PlanState *) tidstate);
                                541                 :                : 
                                542                 :            359 :     TidExprListCreate(tidstate);
                                543                 :                : 
                                544                 :                :     /*
                                545                 :                :      * all done.
                                546                 :                :      */
 7801 tgl@sss.pgh.pa.us         547                 :            359 :     return tidstate;
                                548                 :                : }
        

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