LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeBitmapAnd.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 89.1 % 55 49 6 49
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                 :  * nodeBitmapAnd.c
       4                 :  *    routines to handle BitmapAnd 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/nodeBitmapAnd.c
      12                 :  *
      13                 :  *-------------------------------------------------------------------------
      14                 :  */
      15                 : /* INTERFACE ROUTINES
      16                 :  *      ExecInitBitmapAnd   - initialize the BitmapAnd node
      17                 :  *      MultiExecBitmapAnd  - retrieve the result bitmap from the node
      18                 :  *      ExecEndBitmapAnd    - shut down the BitmapAnd node
      19                 :  *      ExecReScanBitmapAnd - rescan the BitmapAnd node
      20                 :  *
      21                 :  *   NOTES
      22                 :  *      BitmapAnd 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/nodeBitmapAnd.h"
      33                 : 
      34                 : 
      35                 : /* ----------------------------------------------------------------
      36                 :  *      ExecBitmapAnd
      37                 :  *
      38                 :  *      stub for pro forma compliance
      39                 :  * ----------------------------------------------------------------
      40                 :  */
      41                 : static TupleTableSlot *
      42 UBC           0 : ExecBitmapAnd(PlanState *pstate)
      43                 : {
      44               0 :     elog(ERROR, "BitmapAnd node does not support ExecProcNode call convention");
      45                 :     return NULL;
      46                 : }
      47                 : 
      48                 : /* ----------------------------------------------------------------
      49                 :  *      ExecInitBitmapAnd
      50                 :  *
      51                 :  *      Begin all of the subscans of the BitmapAnd node.
      52                 :  * ----------------------------------------------------------------
      53                 :  */
      54                 : BitmapAndState *
      55 CBC          38 : ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags)
      56                 : {
      57              38 :     BitmapAndState *bitmapandstate = makeNode(BitmapAndState);
      58                 :     PlanState **bitmapplanstates;
      59                 :     int         nplans;
      60                 :     int         i;
      61                 :     ListCell   *l;
      62                 :     Plan       *initNode;
      63                 : 
      64                 :     /* check for unsupported flags */
      65              38 :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
      66                 : 
      67                 :     /*
      68                 :      * Set up empty vector of subplan states
      69                 :      */
      70              38 :     nplans = list_length(node->bitmapplans);
      71                 : 
      72              38 :     bitmapplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
      73                 : 
      74                 :     /*
      75                 :      * create new BitmapAndState for our BitmapAnd node
      76                 :      */
      77              38 :     bitmapandstate->ps.plan = (Plan *) node;
      78              38 :     bitmapandstate->ps.state = estate;
      79              38 :     bitmapandstate->ps.ExecProcNode = ExecBitmapAnd;
      80              38 :     bitmapandstate->bitmapplans = bitmapplanstates;
      81              38 :     bitmapandstate->nplans = nplans;
      82                 : 
      83                 :     /*
      84                 :      * call ExecInitNode on each of the plans to be executed and save the
      85                 :      * results into the array "bitmapplanstates".
      86                 :      */
      87              38 :     i = 0;
      88             114 :     foreach(l, node->bitmapplans)
      89                 :     {
      90              76 :         initNode = (Plan *) lfirst(l);
      91              76 :         bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags);
      92              76 :         i++;
      93                 :     }
      94                 : 
      95                 :     /*
      96                 :      * Miscellaneous initialization
      97                 :      *
      98                 :      * BitmapAnd plans don't have expression contexts because they never call
      99                 :      * ExecQual or ExecProject.  They don't need any tuple slots either.
     100                 :      */
     101                 : 
     102              38 :     return bitmapandstate;
     103                 : }
     104                 : 
     105                 : /* ----------------------------------------------------------------
     106                 :  *     MultiExecBitmapAnd
     107                 :  * ----------------------------------------------------------------
     108                 :  */
     109                 : Node *
     110              26 : MultiExecBitmapAnd(BitmapAndState *node)
     111                 : {
     112                 :     PlanState **bitmapplans;
     113                 :     int         nplans;
     114                 :     int         i;
     115              26 :     TIDBitmap  *result = NULL;
     116                 : 
     117                 :     /* must provide our own instrumentation support */
     118              26 :     if (node->ps.instrument)
     119 UBC           0 :         InstrStartNode(node->ps.instrument);
     120                 : 
     121                 :     /*
     122                 :      * get information from the node
     123                 :      */
     124 CBC          26 :     bitmapplans = node->bitmapplans;
     125              26 :     nplans = node->nplans;
     126                 : 
     127                 :     /*
     128                 :      * Scan all the subplans and AND their result bitmaps
     129                 :      */
     130              75 :     for (i = 0; i < nplans; i++)
     131                 :     {
     132              52 :         PlanState  *subnode = bitmapplans[i];
     133                 :         TIDBitmap  *subresult;
     134                 : 
     135              52 :         subresult = (TIDBitmap *) MultiExecProcNode(subnode);
     136                 : 
     137              52 :         if (!subresult || !IsA(subresult, TIDBitmap))
     138 UBC           0 :             elog(ERROR, "unrecognized result from subplan");
     139                 : 
     140 CBC          52 :         if (result == NULL)
     141              26 :             result = subresult; /* first subplan */
     142                 :         else
     143                 :         {
     144              26 :             tbm_intersect(result, subresult);
     145              26 :             tbm_free(subresult);
     146                 :         }
     147                 : 
     148                 :         /*
     149                 :          * If at any stage we have a completely empty bitmap, we can fall out
     150                 :          * without evaluating the remaining subplans, since ANDing them can no
     151                 :          * longer change the result.  (Note: the fact that indxpath.c orders
     152                 :          * the subplans by selectivity should make this case more likely to
     153                 :          * occur.)
     154                 :          */
     155              52 :         if (tbm_is_empty(result))
     156               3 :             break;
     157                 :     }
     158                 : 
     159              26 :     if (result == NULL)
     160 UBC           0 :         elog(ERROR, "BitmapAnd doesn't support zero inputs");
     161                 : 
     162                 :     /* must provide our own instrumentation support */
     163 CBC          26 :     if (node->ps.instrument)
     164 UBC           0 :         InstrStopNode(node->ps.instrument, 0 /* XXX */ );
     165                 : 
     166 CBC          26 :     return (Node *) result;
     167                 : }
     168                 : 
     169                 : /* ----------------------------------------------------------------
     170                 :  *      ExecEndBitmapAnd
     171                 :  *
     172                 :  *      Shuts down the subscans of the BitmapAnd node.
     173                 :  *
     174                 :  *      Returns nothing of interest.
     175                 :  * ----------------------------------------------------------------
     176                 :  */
     177                 : void
     178              38 : ExecEndBitmapAnd(BitmapAndState *node)
     179                 : {
     180                 :     PlanState **bitmapplans;
     181                 :     int         nplans;
     182                 :     int         i;
     183                 : 
     184                 :     /*
     185                 :      * get information from the node
     186                 :      */
     187              38 :     bitmapplans = node->bitmapplans;
     188              38 :     nplans = node->nplans;
     189                 : 
     190                 :     /*
     191                 :      * shut down each of the subscans (that we've initialized)
     192                 :      */
     193             114 :     for (i = 0; i < nplans; i++)
     194                 :     {
     195              76 :         if (bitmapplans[i])
     196              76 :             ExecEndNode(bitmapplans[i]);
     197                 :     }
     198              38 : }
     199                 : 
     200                 : void
     201              17 : ExecReScanBitmapAnd(BitmapAndState *node)
     202                 : {
     203                 :     int         i;
     204                 : 
     205              51 :     for (i = 0; i < node->nplans; i++)
     206                 :     {
     207              34 :         PlanState  *subnode = node->bitmapplans[i];
     208                 : 
     209                 :         /*
     210                 :          * ExecReScan doesn't know about my subplans, so I have to do
     211                 :          * changed-parameter signaling myself.
     212                 :          */
     213              34 :         if (node->ps.chgParam != NULL)
     214               6 :             UpdateChangedParamSet(subnode, node->ps.chgParam);
     215                 : 
     216                 :         /*
     217                 :          * If chgParam of subnode is not null then plan will be re-scanned by
     218                 :          * first ExecProcNode.
     219                 :          */
     220              34 :         if (subnode->chgParam == NULL)
     221              31 :             ExecReScan(subnode);
     222                 :     }
     223              17 : }
        

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