LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeBitmapHeapscan.c (source / functions) Coverage Total Hit UNC UBC GNC CBC EUB ECB DUB DCB
Current: bed3ffbf9d952be6c7d739d068cdce44c046dfb7 vs 574581b50ac9c63dd9e4abebb731a3b67e5b50f6 Lines: 78.1 % 187 146 21 20 18 128 1 9 16
Current Date: 2026-05-05 10:23:31 +0900 Functions: 88.2 % 17 15 2 8 7
Baseline: lcov-20260505-025707-baseline Branches: 60.2 % 88 53 12 23 6 47 4 2 11 5
Baseline Date: 2026-05-05 10:27:06 +0900 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 46.2 % 39 18 21 18
(30,360] days: 0.0 % 1 0 1
(360..) days: 87.1 % 147 128 19 128 1
Function coverage date bins:
(7,30] days: 100.0 % 3 3 3
(360..) days: 85.7 % 14 12 2 5 7
Branch coverage date bins:
(7,30] days: 33.3 % 18 6 12 6
(30,360] days: 0.0 % 2 0 2
(360..) days: 63.5 % 74 47 21 47 4 2

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * nodeBitmapHeapscan.c
                                  4                 :                :  *    Routines to support bitmapped scans of relations
                                  5                 :                :  *
                                  6                 :                :  * NOTE: it is critical that this plan type only be used with MVCC-compliant
                                  7                 :                :  * snapshots (ie, regular snapshots, not SnapshotAny or one of the other
                                  8                 :                :  * special snapshots).  The reason is that since index and heap scans are
                                  9                 :                :  * decoupled, there can be no assurance that the index tuple prompting a
                                 10                 :                :  * visit to a particular heap TID still exists when the visit is made.
                                 11                 :                :  * Therefore the tuple might not exist anymore either (which is OK because
                                 12                 :                :  * heap_fetch will cope) --- but worse, the tuple slot could have been
                                 13                 :                :  * re-used for a newer tuple.  With an MVCC snapshot the newer tuple is
                                 14                 :                :  * certain to fail the time qual and so it will not be mistakenly returned,
                                 15                 :                :  * but with anything else we might return a tuple that doesn't meet the
                                 16                 :                :  * required index qual conditions.
                                 17                 :                :  *
                                 18                 :                :  *
                                 19                 :                :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
                                 20                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 21                 :                :  *
                                 22                 :                :  *
                                 23                 :                :  * IDENTIFICATION
                                 24                 :                :  *    src/backend/executor/nodeBitmapHeapscan.c
                                 25                 :                :  *
                                 26                 :                :  *-------------------------------------------------------------------------
                                 27                 :                :  */
                                 28                 :                : /*
                                 29                 :                :  * INTERFACE ROUTINES
                                 30                 :                :  *      ExecBitmapHeapScan          scans a relation using bitmap info
                                 31                 :                :  *      ExecBitmapHeapNext          workhorse for above
                                 32                 :                :  *      ExecInitBitmapHeapScan      creates and initializes state info.
                                 33                 :                :  *      ExecReScanBitmapHeapScan    prepares to rescan the plan.
                                 34                 :                :  *      ExecEndBitmapHeapScan       releases all storage.
                                 35                 :                :  */
                                 36                 :                : #include "postgres.h"
                                 37                 :                : 
                                 38                 :                : #include "access/relscan.h"
                                 39                 :                : #include "access/tableam.h"
                                 40                 :                : #include "access/visibilitymap.h"
                                 41                 :                : #include "executor/executor.h"
                                 42                 :                : #include "executor/instrument.h"
                                 43                 :                : #include "executor/nodeBitmapHeapscan.h"
                                 44                 :                : #include "miscadmin.h"
                                 45                 :                : #include "pgstat.h"
                                 46                 :                : #include "storage/bufmgr.h"
                                 47                 :                : #include "storage/condition_variable.h"
                                 48                 :                : #include "utils/dsa.h"
                                 49                 :                : #include "utils/rel.h"
                                 50                 :                : #include "utils/spccache.h"
                                 51                 :                : #include "utils/wait_event.h"
                                 52                 :                : 
                                 53                 :                : static void BitmapTableScanSetup(BitmapHeapScanState *node);
                                 54                 :                : static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
                                 55                 :                : static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
                                 56                 :                : static bool BitmapShouldInitializeSharedState(ParallelBitmapHeapState *pstate);
                                 57                 :                : 
                                 58                 :                : 
                                 59                 :                : /* ----------------
                                 60                 :                :  *   SharedBitmapState information
                                 61                 :                :  *
                                 62                 :                :  *      BM_INITIAL      TIDBitmap creation is not yet started, so first worker
                                 63                 :                :  *                      to see this state will set the state to BM_INPROGRESS
                                 64                 :                :  *                      and that process will be responsible for creating
                                 65                 :                :  *                      TIDBitmap.
                                 66                 :                :  *      BM_INPROGRESS   TIDBitmap creation is in progress; workers need to
                                 67                 :                :  *                      sleep until it's finished.
                                 68                 :                :  *      BM_FINISHED     TIDBitmap creation is done, so now all workers can
                                 69                 :                :  *                      proceed to iterate over TIDBitmap.
                                 70                 :                :  * ----------------
                                 71                 :                :  */
                                 72                 :                : typedef enum
                                 73                 :                : {
                                 74                 :                :     BM_INITIAL,
                                 75                 :                :     BM_INPROGRESS,
                                 76                 :                :     BM_FINISHED,
                                 77                 :                : } SharedBitmapState;
                                 78                 :                : 
                                 79                 :                : /* ----------------
                                 80                 :                :  *   ParallelBitmapHeapState information
                                 81                 :                :  *      tbmiterator             iterator for scanning current pages
                                 82                 :                :  *      mutex                   mutual exclusion for state
                                 83                 :                :  *      state                   current state of the TIDBitmap
                                 84                 :                :  *      cv                      conditional wait variable
                                 85                 :                :  * ----------------
                                 86                 :                :  */
                                 87                 :                : typedef struct ParallelBitmapHeapState
                                 88                 :                : {
                                 89                 :                :     dsa_pointer tbmiterator;
                                 90                 :                :     slock_t     mutex;
                                 91                 :                :     SharedBitmapState state;
                                 92                 :                :     ConditionVariable cv;
                                 93                 :                : } ParallelBitmapHeapState;
                                 94                 :                : 
                                 95                 :                : 
                                 96                 :                : /*
                                 97                 :                :  * Do the underlying index scan, build the bitmap, set up the parallel state
                                 98                 :                :  * needed for parallel workers to iterate through the bitmap, and set up the
                                 99                 :                :  * underlying table scan descriptor.
                                100                 :                :  */
                                101                 :                : static void
  460 melanieplageman@gmai      102                 :CBC       15063 : BitmapTableScanSetup(BitmapHeapScanState *node)
                                103                 :                : {
                                104                 :          15063 :     TBMIterator tbmiterator = {0};
                                105                 :          15063 :     ParallelBitmapHeapState *pstate = node->pstate;
                                106                 :          15063 :     dsa_area   *dsa = node->ss.ps.state->es_query_dsa;
                                107                 :                : 
                                108         [ +  + ]:          15063 :     if (!pstate)
                                109                 :                :     {
                                110                 :          14835 :         node->tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
                                111                 :                : 
                                112   [ +  -  -  + ]:          14835 :         if (!node->tbm || !IsA(node->tbm, TIDBitmap))
  460 melanieplageman@gmai      113         [ #  # ]:UBC           0 :             elog(ERROR, "unrecognized result from subplan");
                                114                 :                :     }
  460 melanieplageman@gmai      115         [ +  + ]:CBC         228 :     else if (BitmapShouldInitializeSharedState(pstate))
                                116                 :                :     {
                                117                 :                :         /*
                                118                 :                :          * The leader will immediately come out of the function, but others
                                119                 :                :          * will be blocked until leader populates the TBM and wakes them up.
                                120                 :                :          */
                                121                 :             48 :         node->tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
                                122   [ +  -  -  + ]:             48 :         if (!node->tbm || !IsA(node->tbm, TIDBitmap))
  460 melanieplageman@gmai      123         [ #  # ]:UBC           0 :             elog(ERROR, "unrecognized result from subplan");
                                124                 :                : 
                                125                 :                :         /*
                                126                 :                :          * Prepare to iterate over the TBM. This will return the dsa_pointer
                                127                 :                :          * of the iterator state which will be used by multiple processes to
                                128                 :                :          * iterate jointly.
                                129                 :                :          */
  460 melanieplageman@gmai      130                 :CBC          48 :         pstate->tbmiterator = tbm_prepare_shared_iterate(node->tbm);
                                131                 :                : 
                                132                 :                :         /* We have initialized the shared state so wake up others. */
                                133                 :             48 :         BitmapDoneInitializingSharedState(pstate);
                                134                 :                :     }
                                135                 :                : 
                                136         [ +  + ]:          15063 :     tbmiterator = tbm_begin_iterate(node->tbm, dsa,
                                137                 :                :                                     pstate ?
                                138                 :                :                                     pstate->tbmiterator :
                                139                 :                :                                     InvalidDsaPointer);
                                140                 :                : 
                                141                 :                :     /*
                                142                 :                :      * If this is the first scan of the underlying table, create the table
                                143                 :                :      * scan descriptor and begin the scan.
                                144                 :                :      */
                                145         [ +  + ]:          15063 :     if (!node->ss.ss_currentScanDesc)
                                146                 :                :     {
   28 tomas.vondra@postgre      147                 :GNC       12763 :         uint32      flags = SO_NONE;
                                148                 :                : 
                                149         [ +  + ]:          12763 :         if (ScanRelIsReadOnly(&node->ss))
                                150                 :           9209 :             flags |= SO_HINT_REL_READ_ONLY;
                                151                 :                : 
                                152         [ -  + ]:          12763 :         if (node->ss.ps.state->es_instrument & INSTRUMENT_IO)
   28 tomas.vondra@postgre      153                 :UNC           0 :             flags |= SO_SCAN_INSTRUMENT;
                                154                 :                : 
  460 melanieplageman@gmai      155                 :CBC       12763 :         node->ss.ss_currentScanDesc =
                                156                 :          12763 :             table_beginscan_bm(node->ss.ss_currentRelation,
                                157                 :          12763 :                                node->ss.ps.state->es_snapshot,
                                158                 :                :                                0,
                                159                 :                :                                NULL,
                                160                 :                :                                flags);
                                161                 :                :     }
                                162                 :                : 
                                163                 :          15063 :     node->ss.ss_currentScanDesc->st.rs_tbmiterator = tbmiterator;
                                164                 :          15063 :     node->initialized = true;
                                165                 :          15063 : }
                                166                 :                : 
                                167                 :                : /* ----------------------------------------------------------------
                                168                 :                :  *      BitmapHeapNext
                                169                 :                :  *
                                170                 :                :  *      Retrieve next tuple from the BitmapHeapScan node's currentRelation
                                171                 :                :  * ----------------------------------------------------------------
                                172                 :                :  */
                                173                 :                : static TupleTableSlot *
 7686 tgl@sss.pgh.pa.us         174                 :        3630824 : BitmapHeapNext(BitmapHeapScanState *node)
                                175                 :                : {
  416 melanieplageman@gmai      176                 :        3630824 :     ExprContext *econtext = node->ss.ps.ps_ExprContext;
                                177                 :        3630824 :     TupleTableSlot *slot = node->ss.ss_ScanTupleSlot;
                                178                 :                : 
                                179                 :                :     /*
                                180                 :                :      * If we haven't yet performed the underlying index scan, do it, and begin
                                181                 :                :      * the iteration over the bitmap.
                                182                 :                :      */
 3345 rhaas@postgresql.org      183         [ +  + ]:        3630824 :     if (!node->initialized)
  460 melanieplageman@gmai      184                 :          15063 :         BitmapTableScanSetup(node);
                                185                 :                : 
  416                           186         [ +  + ]:        4131449 :     while (table_scan_bitmap_next_tuple(node->ss.ss_currentScanDesc,
                                187                 :                :                                         slot, &node->recheck,
                                188                 :                :                                         &node->stats.lossy_pages,
                                189                 :                :                                         &node->stats.exact_pages))
                                190                 :                :     {
                                191                 :                :         /*
                                192                 :                :          * Continuing in previously obtained page.
                                193                 :                :          */
                                194         [ +  + ]:        4116715 :         CHECK_FOR_INTERRUPTS();
                                195                 :                : 
                                196                 :                :         /*
                                197                 :                :          * If we are using lossy info, we have to recheck the qual conditions
                                198                 :                :          * at every tuple.
                                199                 :                :          */
                                200         [ +  + ]:        4116715 :         if (node->recheck)
                                201                 :                :         {
                                202                 :        1889241 :             econtext->ecxt_scantuple = slot;
                                203         [ +  + ]:        1889241 :             if (!ExecQualAndReset(node->bitmapqualorig, econtext))
                                204                 :                :             {
                                205                 :                :                 /* Fails recheck, so drop it and loop back for another */
                                206         [ -  + ]:         500625 :                 InstrCountFiltered2(node, 1);
                                207                 :         500625 :                 ExecClearTuple(slot);
                                208                 :         500625 :                 continue;
                                209                 :                :             }
                                210                 :                :         }
                                211                 :                : 
                                212                 :                :         /* OK to return this tuple */
                                213                 :        3616090 :         return slot;
                                214                 :                :     }
                                215                 :                : 
                                216                 :                :     /*
                                217                 :                :      * if we get here it means we are at the end of the scan..
                                218                 :                :      */
 7465 tgl@sss.pgh.pa.us         219                 :          14731 :     return ExecClearTuple(slot);
                                220                 :                : }
                                221                 :                : 
                                222                 :                : /*
                                223                 :                :  *  BitmapDoneInitializingSharedState - Shared state is initialized
                                224                 :                :  *
                                225                 :                :  *  By this time the leader has already populated the TBM and initialized the
                                226                 :                :  *  shared state so wake up other processes.
                                227                 :                :  */
                                228                 :                : static inline void
 3345 rhaas@postgresql.org      229                 :             48 : BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
                                230                 :                : {
                                231         [ -  + ]:             48 :     SpinLockAcquire(&pstate->mutex);
                                232                 :             48 :     pstate->state = BM_FINISHED;
                                233                 :             48 :     SpinLockRelease(&pstate->mutex);
                                234                 :             48 :     ConditionVariableBroadcast(&pstate->cv);
                                235                 :             48 : }
                                236                 :                : 
                                237                 :                : /*
                                238                 :                :  * BitmapHeapRecheck -- access method routine to recheck a tuple in EvalPlanQual
                                239                 :                :  */
                                240                 :                : static bool
 6035 tgl@sss.pgh.pa.us         241                 :UBC           0 : BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot)
                                242                 :                : {
                                243                 :                :     ExprContext *econtext;
                                244                 :                : 
                                245                 :                :     /*
                                246                 :                :      * extract necessary information from index scan node
                                247                 :                :      */
                                248                 :              0 :     econtext = node->ss.ps.ps_ExprContext;
                                249                 :                : 
                                250                 :                :     /* Does the tuple meet the original qual conditions? */
                                251                 :              0 :     econtext->ecxt_scantuple = slot;
 3018 andres@anarazel.de        252                 :              0 :     return ExecQualAndReset(node->bitmapqualorig, econtext);
                                253                 :                : }
                                254                 :                : 
                                255                 :                : /* ----------------------------------------------------------------
                                256                 :                :  *      ExecBitmapHeapScan(node)
                                257                 :                :  * ----------------------------------------------------------------
                                258                 :                :  */
                                259                 :                : static TupleTableSlot *
 3214 andres@anarazel.de        260                 :CBC     3401437 : ExecBitmapHeapScan(PlanState *pstate)
                                261                 :                : {
                                262                 :        3401437 :     BitmapHeapScanState *node = castNode(BitmapHeapScanState, pstate);
                                263                 :                : 
 6035 tgl@sss.pgh.pa.us         264                 :        3401437 :     return ExecScan(&node->ss,
                                265                 :                :                     (ExecScanAccessMtd) BitmapHeapNext,
                                266                 :                :                     (ExecScanRecheckMtd) BitmapHeapRecheck);
                                267                 :                : }
                                268                 :                : 
                                269                 :                : /* ----------------------------------------------------------------
                                270                 :                :  *      ExecReScanBitmapHeapScan(node)
                                271                 :                :  * ----------------------------------------------------------------
                                272                 :                :  */
                                273                 :                : void
 5776                           274                 :           2828 : ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
                                275                 :                : {
 4000 bruce@momjian.us          276                 :           2828 :     PlanState  *outerPlan = outerPlanState(node);
                                277                 :                : 
  557 melanieplageman@gmai      278                 :           2828 :     TableScanDesc scan = node->ss.ss_currentScanDesc;
                                279                 :                : 
                                280         [ +  + ]:           2828 :     if (scan)
                                281                 :                :     {
                                282                 :                :         /*
                                283                 :                :          * End iteration on iterators saved in scan descriptor if they have
                                284                 :                :          * not already been cleaned up.
                                285                 :                :          */
  502                           286         [ +  + ]:           2304 :         if (!tbm_exhausted(&scan->st.rs_tbmiterator))
                                287                 :           2300 :             tbm_end_iterate(&scan->st.rs_tbmiterator);
                                288                 :                : 
                                289                 :                :         /* rescan to release any page pin */
  759 tomas.vondra@postgre      290                 :           2304 :         table_rescan(node->ss.ss_currentScanDesc, NULL);
                                291                 :                :     }
                                292                 :                : 
                                293                 :                :     /* release bitmaps and buffers if any */
 7686 tgl@sss.pgh.pa.us         294         [ +  + ]:           2828 :     if (node->tbm)
                                295                 :           2300 :         tbm_free(node->tbm);
                                296                 :           2828 :     node->tbm = NULL;
 3345 rhaas@postgresql.org      297                 :           2828 :     node->initialized = false;
  557 melanieplageman@gmai      298                 :           2828 :     node->recheck = true;
                                299                 :                : 
 6035 tgl@sss.pgh.pa.us         300                 :           2828 :     ExecScanReScan(&node->ss);
                                301                 :                : 
                                302                 :                :     /*
                                303                 :                :      * if chgParam of subnode is not null then plan will be re-scanned by
                                304                 :                :      * first ExecProcNode.
                                305                 :                :      */
 4019 rhaas@postgresql.org      306         [ +  + ]:           2828 :     if (outerPlan->chgParam == NULL)
                                307                 :            199 :         ExecReScan(outerPlan);
 7686 tgl@sss.pgh.pa.us         308                 :           2828 : }
                                309                 :                : 
                                310                 :                : /* ----------------------------------------------------------------
                                311                 :                :  *      ExecEndBitmapHeapScan
                                312                 :                :  * ----------------------------------------------------------------
                                313                 :                :  */
                                314                 :                : void
                                315                 :          15696 : ExecEndBitmapHeapScan(BitmapHeapScanState *node)
                                316                 :                : {
                                317                 :                :     TableScanDesc scanDesc;
                                318                 :                : 
                                319                 :                :     /*
                                320                 :                :      * When ending a parallel worker, copy the statistics gathered by the
                                321                 :                :      * worker back into shared memory so that it can be picked up by the main
                                322                 :                :      * process to report in EXPLAIN ANALYZE.
                                323                 :                :      */
  665 drowley@postgresql.o      324   [ -  +  -  - ]:          15696 :     if (node->sinstrument != NULL && IsParallelWorker())
                                325                 :                :     {
                                326                 :                :         BitmapHeapScanInstrumentation *si;
                                327                 :                : 
   52 tomas.vondra@postgre      328         [ #  # ]:UBC           0 :         Assert(ParallelWorkerNumber < node->sinstrument->num_workers);
  665 drowley@postgresql.o      329                 :              0 :         si = &node->sinstrument->sinstrument[ParallelWorkerNumber];
                                330                 :                : 
                                331                 :                :         /*
                                332                 :                :          * Here we accumulate the stats rather than performing memcpy on
                                333                 :                :          * node->stats into si.  When a Gather/GatherMerge node finishes it
                                334                 :                :          * will perform planner shutdown on the workers.  On rescan it will
                                335                 :                :          * spin up new workers which will have a new BitmapHeapScanState and
                                336                 :                :          * zeroed stats.
                                337                 :                :          */
                                338                 :              0 :         si->exact_pages += node->stats.exact_pages;
                                339                 :              0 :         si->lossy_pages += node->stats.lossy_pages;
                                340                 :                : 
                                341                 :                :         /* collect I/O instrumentation for this process */
   28 tomas.vondra@postgre      342         [ #  # ]:UNC           0 :         if (node->ss.ss_currentScanDesc &&
                                343         [ #  # ]:              0 :             node->ss.ss_currentScanDesc->rs_instrument)
                                344                 :                :         {
                                345                 :              0 :             AccumulateIOStats(&si->stats.io,
                                346                 :              0 :                               &node->ss.ss_currentScanDesc->rs_instrument->io);
                                347                 :                :         }
                                348                 :                :     }
                                349                 :                : 
                                350                 :                :     /*
                                351                 :                :      * extract information from the node
                                352                 :                :      */
 7686 tgl@sss.pgh.pa.us         353                 :CBC       15696 :     scanDesc = node->ss.ss_currentScanDesc;
                                354                 :                : 
                                355                 :                :     /*
                                356                 :                :      * close down subplans
                                357                 :                :      */
                                358                 :          15696 :     ExecEndNode(outerPlanState(node));
                                359                 :                : 
  557 melanieplageman@gmai      360         [ +  + ]:          15696 :     if (scanDesc)
                                361                 :                :     {
                                362                 :                :         /*
                                363                 :                :          * End iteration on iterators saved in scan descriptor if they have
                                364                 :                :          * not already been cleaned up.
                                365                 :                :          */
  502                           366         [ +  - ]:          12682 :         if (!tbm_exhausted(&scanDesc->st.rs_tbmiterator))
                                367                 :          12682 :             tbm_end_iterate(&scanDesc->st.rs_tbmiterator);
                                368                 :                : 
                                369                 :                :         /*
                                370                 :                :          * close table scan
                                371                 :                :          */
  557                           372                 :          12682 :         table_endscan(scanDesc);
                                373                 :                :     }
                                374                 :                : 
                                375                 :                :     /*
                                376                 :                :      * release bitmaps and buffers if any
                                377                 :                :      */
 7686 tgl@sss.pgh.pa.us         378         [ +  + ]:          15696 :     if (node->tbm)
                                379                 :          12502 :         tbm_free(node->tbm);
                                380                 :          15696 : }
                                381                 :                : 
                                382                 :                : /* ----------------------------------------------------------------
                                383                 :                :  *      ExecInitBitmapHeapScan
                                384                 :                :  *
                                385                 :                :  *      Initializes the scan's state information.
                                386                 :                :  * ----------------------------------------------------------------
                                387                 :                :  */
                                388                 :                : BitmapHeapScanState *
 7371                           389                 :          15777 : ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
                                390                 :                : {
                                391                 :                :     BitmapHeapScanState *scanstate;
                                392                 :                :     Relation    currentRelation;
                                393                 :                : 
                                394                 :                :     /* check for unsupported flags */
                                395         [ -  + ]:          15777 :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
                                396                 :                : 
                                397                 :                :     /*
                                398                 :                :      * Assert caller didn't ask for an unsafe snapshot --- see comments at
                                399                 :                :      * head of file.
                                400                 :                :      */
 7465                           401   [ -  +  -  - ]:          15777 :     Assert(IsMVCCSnapshot(estate->es_snapshot));
                                402                 :                : 
                                403                 :                :     /*
                                404                 :                :      * create state structure
                                405                 :                :      */
 7686                           406                 :          15777 :     scanstate = makeNode(BitmapHeapScanState);
                                407                 :          15777 :     scanstate->ss.ps.plan = (Plan *) node;
                                408                 :          15777 :     scanstate->ss.ps.state = estate;
 3214 andres@anarazel.de        409                 :          15777 :     scanstate->ss.ps.ExecProcNode = ExecBitmapHeapScan;
                                410                 :                : 
 7686 tgl@sss.pgh.pa.us         411                 :          15777 :     scanstate->tbm = NULL;
                                412                 :                : 
                                413                 :                :     /* Zero the statistics counters */
  665 drowley@postgresql.o      414                 :          15777 :     memset(&scanstate->stats, 0, sizeof(BitmapHeapScanInstrumentation));
                                415                 :                : 
 3345 rhaas@postgresql.org      416                 :          15777 :     scanstate->initialized = false;
                                417                 :          15777 :     scanstate->pstate = NULL;
  557 melanieplageman@gmai      418                 :          15777 :     scanstate->recheck = true;
                                419                 :                : 
                                420                 :                :     /*
                                421                 :                :      * Miscellaneous initialization
                                422                 :                :      *
                                423                 :                :      * create expression context for node
                                424                 :                :      */
 7686 tgl@sss.pgh.pa.us         425                 :          15777 :     ExecAssignExprContext(estate, &scanstate->ss.ps);
                                426                 :                : 
                                427                 :                :     /*
                                428                 :                :      * open the scan relation
                                429                 :                :      */
 3000 andres@anarazel.de        430                 :          15777 :     currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
                                431                 :                : 
                                432                 :                :     /*
                                433                 :                :      * initialize child nodes
                                434                 :                :      */
                                435                 :          15777 :     outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags);
                                436                 :                : 
                                437                 :                :     /*
                                438                 :                :      * get the scan type from the relation descriptor.
                                439                 :                :      */
                                440                 :          15777 :     ExecInitScanTupleSlot(estate, &scanstate->ss,
                                441                 :                :                           RelationGetDescr(currentRelation),
                                442                 :                :                           table_slot_callbacks(currentRelation),
                                443                 :                :                           TTS_FLAG_OBEYS_NOT_NULL_CONSTRAINTS);
                                444                 :                : 
                                445                 :                :     /*
                                446                 :                :      * Initialize result type and projection.
                                447                 :                :      */
 2734                           448                 :          15777 :     ExecInitResultTypeTL(&scanstate->ss.ps);
 3000                           449                 :          15777 :     ExecAssignScanProjectionInfo(&scanstate->ss);
                                450                 :                : 
                                451                 :                :     /*
                                452                 :                :      * initialize child expressions
                                453                 :                :      */
                                454                 :          15777 :     scanstate->ss.ps.qual =
                                455                 :          15777 :         ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
                                456                 :          15777 :     scanstate->bitmapqualorig =
                                457                 :          15777 :         ExecInitQual(node->bitmapqualorig, (PlanState *) scanstate);
                                458                 :                : 
 7686 tgl@sss.pgh.pa.us         459                 :          15777 :     scanstate->ss.ss_currentRelation = currentRelation;
                                460                 :                : 
                                461                 :                :     /*
                                462                 :                :      * all done.
                                463                 :                :      */
                                464                 :          15777 :     return scanstate;
                                465                 :                : }
                                466                 :                : 
                                467                 :                : /*----------------
                                468                 :                :  *      BitmapShouldInitializeSharedState
                                469                 :                :  *
                                470                 :                :  *      The first process to come here and see the state to the BM_INITIAL
                                471                 :                :  *      will become the leader for the parallel bitmap scan and will be
                                472                 :                :  *      responsible for populating the TIDBitmap.  The other processes will
                                473                 :                :  *      be blocked by the condition variable until the leader wakes them up.
                                474                 :                :  * ---------------
                                475                 :                :  */
                                476                 :                : static bool
 3345 rhaas@postgresql.org      477                 :            228 : BitmapShouldInitializeSharedState(ParallelBitmapHeapState *pstate)
                                478                 :                : {
                                479                 :                :     SharedBitmapState state;
                                480                 :                : 
                                481                 :                :     while (1)
                                482                 :                :     {
                                483         [ -  + ]:            260 :         SpinLockAcquire(&pstate->mutex);
                                484                 :            260 :         state = pstate->state;
                                485         [ +  + ]:            260 :         if (pstate->state == BM_INITIAL)
                                486                 :             48 :             pstate->state = BM_INPROGRESS;
                                487                 :            260 :         SpinLockRelease(&pstate->mutex);
                                488                 :                : 
                                489                 :                :         /* Exit if bitmap is done, or if we're the leader. */
                                490         [ +  + ]:            260 :         if (state != BM_INPROGRESS)
                                491                 :            228 :             break;
                                492                 :                : 
                                493                 :                :         /* Wait for the leader to wake us up. */
                                494                 :             32 :         ConditionVariableSleep(&pstate->cv, WAIT_EVENT_PARALLEL_BITMAP_SCAN);
                                495                 :                :     }
                                496                 :                : 
                                497                 :            228 :     ConditionVariableCancelSleep();
                                498                 :                : 
                                499                 :            228 :     return (state == BM_INITIAL);
                                500                 :                : }
                                501                 :                : 
                                502                 :                : /* ----------------------------------------------------------------
                                503                 :                :  *      ExecBitmapHeapEstimate
                                504                 :                :  *
                                505                 :                :  *      Compute the amount of space we'll need in the parallel
                                506                 :                :  *      query DSM, and inform pcxt->estimator about our needs.
                                507                 :                :  * ----------------------------------------------------------------
                                508                 :                :  */
                                509                 :                : void
                                510                 :             12 : ExecBitmapHeapEstimate(BitmapHeapScanState *node,
                                511                 :                :                        ParallelContext *pcxt)
                                512                 :                : {
   28 tomas.vondra@postgre      513                 :GNC          12 :     shm_toc_estimate_chunk(&pcxt->estimator,
                                514                 :                :                            MAXALIGN(sizeof(ParallelBitmapHeapState)));
 3345 rhaas@postgresql.org      515                 :CBC          12 :     shm_toc_estimate_keys(&pcxt->estimator, 1);
                                516                 :             12 : }
                                517                 :                : 
                                518                 :                : /* ----------------------------------------------------------------
                                519                 :                :  *      ExecBitmapHeapInitializeDSM
                                520                 :                :  *
                                521                 :                :  *      Set up a parallel bitmap heap scan descriptor.
                                522                 :                :  * ----------------------------------------------------------------
                                523                 :                :  */
                                524                 :                : void
                                525                 :             12 : ExecBitmapHeapInitializeDSM(BitmapHeapScanState *node,
                                526                 :                :                             ParallelContext *pcxt)
                                527                 :                : {
                                528                 :                :     ParallelBitmapHeapState *pstate;
 3080                           529                 :             12 :     dsa_area   *dsa = node->ss.ps.state->es_query_dsa;
                                530                 :                : 
                                531                 :                :     /* If there's no DSA, there are no workers; initialize nothing. */
                                532         [ -  + ]:             12 :     if (dsa == NULL)
 3080 rhaas@postgresql.org      533                 :UBC           0 :         return;
                                534                 :                : 
                                535                 :                :     pstate = (ParallelBitmapHeapState *)
   28 tomas.vondra@postgre      536                 :GNC          12 :         shm_toc_allocate(pcxt->toc,
                                537                 :                :                          MAXALIGN(sizeof(ParallelBitmapHeapState)));
                                538                 :                : 
 3345 rhaas@postgresql.org      539                 :CBC          12 :     pstate->tbmiterator = 0;
                                540                 :                : 
                                541                 :                :     /* Initialize the mutex */
                                542                 :             12 :     SpinLockInit(&pstate->mutex);
                                543                 :             12 :     pstate->state = BM_INITIAL;
                                544                 :                : 
                                545                 :             12 :     ConditionVariableInit(&pstate->cv);
                                546                 :                : 
                                547                 :             12 :     shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pstate);
                                548                 :             12 :     node->pstate = pstate;
                                549                 :                : }
                                550                 :                : 
                                551                 :                : /* ----------------------------------------------------------------
                                552                 :                :  *      ExecBitmapHeapReInitializeDSM
                                553                 :                :  *
                                554                 :                :  *      Reset shared state before beginning a fresh scan.
                                555                 :                :  * ----------------------------------------------------------------
                                556                 :                :  */
                                557                 :                : void
 3170 tgl@sss.pgh.pa.us         558                 :             36 : ExecBitmapHeapReInitializeDSM(BitmapHeapScanState *node,
                                559                 :                :                               ParallelContext *pcxt)
                                560                 :                : {
                                561                 :             36 :     ParallelBitmapHeapState *pstate = node->pstate;
                                562                 :             36 :     dsa_area   *dsa = node->ss.ps.state->es_query_dsa;
                                563                 :                : 
                                564                 :                :     /* If there's no DSA, there are no workers; do nothing. */
 3080 rhaas@postgresql.org      565         [ -  + ]:             36 :     if (dsa == NULL)
 3080 rhaas@postgresql.org      566                 :UBC           0 :         return;
                                567                 :                : 
 3170 tgl@sss.pgh.pa.us         568                 :CBC          36 :     pstate->state = BM_INITIAL;
                                569                 :                : 
                                570         [ +  - ]:             36 :     if (DsaPointerIsValid(pstate->tbmiterator))
                                571                 :             36 :         tbm_free_shared_area(dsa, pstate->tbmiterator);
                                572                 :                : 
                                573                 :             36 :     pstate->tbmiterator = InvalidDsaPointer;
                                574                 :                : }
                                575                 :                : 
                                576                 :                : /* ----------------------------------------------------------------
                                577                 :                :  *      ExecBitmapHeapInitializeWorker
                                578                 :                :  *
                                579                 :                :  *      Copy relevant information from TOC into planstate.
                                580                 :                :  * ----------------------------------------------------------------
                                581                 :                :  */
                                582                 :                : void
 3092 andres@anarazel.de        583                 :            180 : ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node,
                                584                 :                :                                ParallelWorkerContext *pwcxt)
                                585                 :                : {
 3080 rhaas@postgresql.org      586         [ -  + ]:            180 :     Assert(node->ss.ps.state->es_query_dsa != NULL);
                                587                 :                : 
   28 tomas.vondra@postgre      588                 :GNC         180 :     node->pstate = (ParallelBitmapHeapState *)
                                589                 :            180 :         shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
                                590                 :            180 : }
                                591                 :                : 
                                592                 :                : /*
                                593                 :                :  * Compute the amount of space we'll need for the shared instrumentation and
                                594                 :                :  * inform pcxt->estimator.
                                595                 :                :  */
                                596                 :                : void
                                597                 :             13 : ExecBitmapHeapInstrumentEstimate(BitmapHeapScanState *node,
                                598                 :                :                                  ParallelContext *pcxt)
                                599                 :                : {
                                600                 :                :     Size        size;
                                601                 :                : 
                                602   [ -  +  -  - ]:             13 :     if (!node->ss.ps.instrument || pcxt->nworkers == 0)
                                603                 :             13 :         return;
                                604                 :                : 
   28 tomas.vondra@postgre      605                 :UNC           0 :     size = add_size(offsetof(SharedBitmapHeapInstrumentation, sinstrument),
                                606                 :              0 :                     mul_size(pcxt->nworkers, sizeof(BitmapHeapScanInstrumentation)));
                                607                 :              0 :     shm_toc_estimate_chunk(&pcxt->estimator, size);
                                608                 :              0 :     shm_toc_estimate_keys(&pcxt->estimator, 1);
                                609                 :                : }
                                610                 :                : 
                                611                 :                : /*
                                612                 :                :  * Set up parallel bitmap heap scan instrumentation.
                                613                 :                :  */
                                614                 :                : void
   28 tomas.vondra@postgre      615                 :GNC          13 : ExecBitmapHeapInstrumentInitDSM(BitmapHeapScanState *node,
                                616                 :                :                                 ParallelContext *pcxt)
                                617                 :                : {
                                618                 :                :     Size        size;
                                619                 :                : 
                                620   [ -  +  -  - ]:             13 :     if (!node->ss.ps.instrument || pcxt->nworkers == 0)
                                621                 :             13 :         return;
                                622                 :                : 
   28 tomas.vondra@postgre      623                 :UNC           0 :     size = add_size(offsetof(SharedBitmapHeapInstrumentation, sinstrument),
                                624                 :              0 :                     mul_size(pcxt->nworkers, sizeof(BitmapHeapScanInstrumentation)));
                                625                 :              0 :     node->sinstrument =
                                626                 :              0 :         (SharedBitmapHeapInstrumentation *) shm_toc_allocate(pcxt->toc, size);
                                627                 :                : 
                                628                 :                :     /* Each per-worker area must start out as zeroes */
                                629                 :              0 :     memset(node->sinstrument, 0, size);
                                630                 :              0 :     node->sinstrument->num_workers = pcxt->nworkers;
                                631                 :              0 :     shm_toc_insert(pcxt->toc,
                                632                 :              0 :                    node->ss.ps.plan->plan_node_id +
                                633                 :                :                    PARALLEL_KEY_SCAN_INSTRUMENT_OFFSET,
                                634                 :              0 :                    node->sinstrument);
                                635                 :                : }
                                636                 :                : 
                                637                 :                : /*
                                638                 :                :  * Look up and save the location of the shared instrumentation.
                                639                 :                :  */
                                640                 :                : void
   28 tomas.vondra@postgre      641                 :GNC         181 : ExecBitmapHeapInstrumentInitWorker(BitmapHeapScanState *node,
                                642                 :                :                                    ParallelWorkerContext *pwcxt)
                                643                 :                : {
                                644         [ +  - ]:            181 :     if (!node->ss.ps.instrument)
                                645                 :            181 :         return;
                                646                 :                : 
   28 tomas.vondra@postgre      647                 :UNC           0 :     node->sinstrument = (SharedBitmapHeapInstrumentation *)
                                648                 :              0 :         shm_toc_lookup(pwcxt->toc,
                                649                 :              0 :                        node->ss.ps.plan->plan_node_id +
                                650                 :                :                        PARALLEL_KEY_SCAN_INSTRUMENT_OFFSET,
                                651                 :                :                        false);
  665 drowley@postgresql.o      652                 :ECB       (135) : }
                                653                 :                : 
                                654                 :                : /* ----------------------------------------------------------------
                                655                 :                :  *      ExecBitmapHeapRetrieveInstrumentation
                                656                 :                :  *
                                657                 :                :  *      Transfer bitmap heap scan statistics from DSM to private memory.
                                658                 :                :  * ----------------------------------------------------------------
                                659                 :                :  */
                                660                 :                : void
  665 drowley@postgresql.o      661                 :UBC           0 : ExecBitmapHeapRetrieveInstrumentation(BitmapHeapScanState *node)
                                662                 :                : {
                                663                 :              0 :     SharedBitmapHeapInstrumentation *sinstrument = node->sinstrument;
                                664                 :                :     Size        size;
                                665                 :                : 
                                666         [ #  # ]:              0 :     if (sinstrument == NULL)
                                667                 :              0 :         return;
                                668                 :                : 
                                669                 :              0 :     size = offsetof(SharedBitmapHeapInstrumentation, sinstrument)
                                670                 :              0 :         + sinstrument->num_workers * sizeof(BitmapHeapScanInstrumentation);
                                671                 :                : 
                                672                 :              0 :     node->sinstrument = palloc(size);
                                673                 :              0 :     memcpy(node->sinstrument, sinstrument, size);
                                674                 :                : }
        

Generated by: LCOV version 2.5.0-beta