LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeBitmapOr.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 80.6 % 62 50 12 50
Current Date: 2023-04-08 15:15:32 Functions: 80.0 % 5 4 1 4
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * nodeBitmapOr.c
       4                 :  *    routines to handle BitmapOr nodes.
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       7                 :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :  *
       9                 :  *
      10                 :  * IDENTIFICATION
      11                 :  *    src/backend/executor/nodeBitmapOr.c
      12                 :  *
      13                 :  *-------------------------------------------------------------------------
      14                 :  */
      15                 : /* INTERFACE ROUTINES
      16                 :  *      ExecInitBitmapOr    - initialize the BitmapOr node
      17                 :  *      MultiExecBitmapOr   - retrieve the result bitmap from the node
      18                 :  *      ExecEndBitmapOr     - shut down the BitmapOr node
      19                 :  *      ExecReScanBitmapOr  - rescan the BitmapOr node
      20                 :  *
      21                 :  *   NOTES
      22                 :  *      BitmapOr nodes don't make use of their left and right
      23                 :  *      subtrees, rather they maintain a list of subplans,
      24                 :  *      much like Append nodes.  The logic is much simpler than
      25                 :  *      Append, however, since we needn't cope with forward/backward
      26                 :  *      execution.
      27                 :  */
      28                 : 
      29                 : #include "postgres.h"
      30                 : 
      31                 : #include "executor/execdebug.h"
      32                 : #include "executor/nodeBitmapOr.h"
      33                 : #include "miscadmin.h"
      34                 : 
      35                 : 
      36                 : /* ----------------------------------------------------------------
      37                 :  *      ExecBitmapOr
      38                 :  *
      39                 :  *      stub for pro forma compliance
      40                 :  * ----------------------------------------------------------------
      41                 :  */
      42                 : static TupleTableSlot *
      43 UBC           0 : ExecBitmapOr(PlanState *pstate)
      44                 : {
      45               0 :     elog(ERROR, "BitmapOr node does not support ExecProcNode call convention");
      46                 :     return NULL;
      47                 : }
      48                 : 
      49                 : /* ----------------------------------------------------------------
      50                 :  *      ExecInitBitmapOr
      51                 :  *
      52                 :  *      Begin all of the subscans of the BitmapOr node.
      53                 :  * ----------------------------------------------------------------
      54                 :  */
      55                 : BitmapOrState *
      56 CBC         111 : ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags)
      57                 : {
      58             111 :     BitmapOrState *bitmaporstate = makeNode(BitmapOrState);
      59                 :     PlanState **bitmapplanstates;
      60                 :     int         nplans;
      61                 :     int         i;
      62                 :     ListCell   *l;
      63                 :     Plan       *initNode;
      64                 : 
      65                 :     /* check for unsupported flags */
      66             111 :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
      67                 : 
      68                 :     /*
      69                 :      * Set up empty vector of subplan states
      70                 :      */
      71             111 :     nplans = list_length(node->bitmapplans);
      72                 : 
      73             111 :     bitmapplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
      74                 : 
      75                 :     /*
      76                 :      * create new BitmapOrState for our BitmapOr node
      77                 :      */
      78             111 :     bitmaporstate->ps.plan = (Plan *) node;
      79             111 :     bitmaporstate->ps.state = estate;
      80             111 :     bitmaporstate->ps.ExecProcNode = ExecBitmapOr;
      81             111 :     bitmaporstate->bitmapplans = bitmapplanstates;
      82             111 :     bitmaporstate->nplans = nplans;
      83                 : 
      84                 :     /*
      85                 :      * call ExecInitNode on each of the plans to be executed and save the
      86                 :      * results into the array "bitmapplanstates".
      87                 :      */
      88             111 :     i = 0;
      89             360 :     foreach(l, node->bitmapplans)
      90                 :     {
      91             249 :         initNode = (Plan *) lfirst(l);
      92             249 :         bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags);
      93             249 :         i++;
      94                 :     }
      95                 : 
      96                 :     /*
      97                 :      * Miscellaneous initialization
      98                 :      *
      99                 :      * BitmapOr plans don't have expression contexts because they never call
     100                 :      * ExecQual or ExecProject.  They don't need any tuple slots either.
     101                 :      */
     102                 : 
     103             111 :     return bitmaporstate;
     104                 : }
     105                 : 
     106                 : /* ----------------------------------------------------------------
     107                 :  *     MultiExecBitmapOr
     108                 :  * ----------------------------------------------------------------
     109                 :  */
     110                 : Node *
     111              82 : MultiExecBitmapOr(BitmapOrState *node)
     112                 : {
     113                 :     PlanState **bitmapplans;
     114                 :     int         nplans;
     115                 :     int         i;
     116              82 :     TIDBitmap  *result = NULL;
     117                 : 
     118                 :     /* must provide our own instrumentation support */
     119              82 :     if (node->ps.instrument)
     120              21 :         InstrStartNode(node->ps.instrument);
     121                 : 
     122                 :     /*
     123                 :      * get information from the node
     124                 :      */
     125              82 :     bitmapplans = node->bitmapplans;
     126              82 :     nplans = node->nplans;
     127                 : 
     128                 :     /*
     129                 :      * Scan all the subplans and OR their result bitmaps
     130                 :      */
     131             267 :     for (i = 0; i < nplans; i++)
     132                 :     {
     133             185 :         PlanState  *subnode = bitmapplans[i];
     134                 :         TIDBitmap  *subresult;
     135                 : 
     136                 :         /*
     137                 :          * We can special-case BitmapIndexScan children to avoid an explicit
     138                 :          * tbm_union step for each child: just pass down the current result
     139                 :          * bitmap and let the child OR directly into it.
     140                 :          */
     141             185 :         if (IsA(subnode, BitmapIndexScanState))
     142                 :         {
     143             185 :             if (result == NULL) /* first subplan */
     144                 :             {
     145                 :                 /* XXX should we use less than work_mem for this? */
     146              82 :                 result = tbm_create(work_mem * 1024L,
     147              82 :                                     ((BitmapOr *) node->ps.plan)->isshared ?
     148 UBC           0 :                                     node->ps.state->es_query_dsa : NULL);
     149                 :             }
     150                 : 
     151 CBC         185 :             ((BitmapIndexScanState *) subnode)->biss_result = result;
     152                 : 
     153             185 :             subresult = (TIDBitmap *) MultiExecProcNode(subnode);
     154                 : 
     155             185 :             if (subresult != result)
     156 UBC           0 :                 elog(ERROR, "unrecognized result from subplan");
     157                 :         }
     158                 :         else
     159                 :         {
     160                 :             /* standard implementation */
     161               0 :             subresult = (TIDBitmap *) MultiExecProcNode(subnode);
     162                 : 
     163               0 :             if (!subresult || !IsA(subresult, TIDBitmap))
     164               0 :                 elog(ERROR, "unrecognized result from subplan");
     165                 : 
     166               0 :             if (result == NULL)
     167               0 :                 result = subresult; /* first subplan */
     168                 :             else
     169                 :             {
     170               0 :                 tbm_union(result, subresult);
     171               0 :                 tbm_free(subresult);
     172                 :             }
     173                 :         }
     174                 :     }
     175                 : 
     176                 :     /* We could return an empty result set here? */
     177 CBC          82 :     if (result == NULL)
     178 UBC           0 :         elog(ERROR, "BitmapOr doesn't support zero inputs");
     179                 : 
     180                 :     /* must provide our own instrumentation support */
     181 CBC          82 :     if (node->ps.instrument)
     182              21 :         InstrStopNode(node->ps.instrument, 0 /* XXX */ );
     183                 : 
     184              82 :     return (Node *) result;
     185                 : }
     186                 : 
     187                 : /* ----------------------------------------------------------------
     188                 :  *      ExecEndBitmapOr
     189                 :  *
     190                 :  *      Shuts down the subscans of the BitmapOr node.
     191                 :  *
     192                 :  *      Returns nothing of interest.
     193                 :  * ----------------------------------------------------------------
     194                 :  */
     195                 : void
     196             111 : ExecEndBitmapOr(BitmapOrState *node)
     197                 : {
     198                 :     PlanState **bitmapplans;
     199                 :     int         nplans;
     200                 :     int         i;
     201                 : 
     202                 :     /*
     203                 :      * get information from the node
     204                 :      */
     205             111 :     bitmapplans = node->bitmapplans;
     206             111 :     nplans = node->nplans;
     207                 : 
     208                 :     /*
     209                 :      * shut down each of the subscans (that we've initialized)
     210                 :      */
     211             360 :     for (i = 0; i < nplans; i++)
     212                 :     {
     213             249 :         if (bitmapplans[i])
     214             249 :             ExecEndNode(bitmapplans[i]);
     215                 :     }
     216             111 : }
     217                 : 
     218                 : void
     219              14 : ExecReScanBitmapOr(BitmapOrState *node)
     220                 : {
     221                 :     int         i;
     222                 : 
     223              42 :     for (i = 0; i < node->nplans; i++)
     224                 :     {
     225              28 :         PlanState  *subnode = node->bitmapplans[i];
     226                 : 
     227                 :         /*
     228                 :          * ExecReScan doesn't know about my subplans, so I have to do
     229                 :          * changed-parameter signaling myself.
     230                 :          */
     231              28 :         if (node->ps.chgParam != NULL)
     232               6 :             UpdateChangedParamSet(subnode, node->ps.chgParam);
     233                 : 
     234                 :         /*
     235                 :          * If chgParam of subnode is not null then plan will be re-scanned by
     236                 :          * first ExecProcNode.
     237                 :          */
     238              28 :         if (subnode->chgParam == NULL)
     239              25 :             ExecReScan(subnode);
     240                 :     }
     241              14 : }
        

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