LCOV - differential code coverage report
Current view: top level - src/backend/executor - nodeUnique.c (source / functions) Coverage Total Hit UNC UIC UBC CBC EUB
Current: Differential Code Coverage HEAD vs 15 Lines: 86.0 % 43 37 3 1 2 37 4
Current Date: 2023-04-08 17:13:01 Functions: 75.0 % 4 3 1 3
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 86.0 % 43 37 3 1 2 37 2
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 75.0 % 4 3 1 3

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * nodeUnique.c
                                  4                 :  *    Routines to handle unique'ing of queries where appropriate
                                  5                 :  *
                                  6                 :  * Unique is a very simple node type that just filters out duplicate
                                  7                 :  * tuples from a stream of sorted tuples from its subplan.  It's essentially
                                  8                 :  * a dumbed-down form of Group: the duplicate-removal functionality is
                                  9                 :  * identical.  However, Unique doesn't do projection nor qual checking,
                                 10                 :  * so it's marginally more efficient for cases where neither is needed.
                                 11                 :  * (It's debatable whether the savings justifies carrying two plan node
                                 12                 :  * types, though.)
                                 13                 :  *
                                 14                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                 15                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                 16                 :  *
                                 17                 :  *
                                 18                 :  * IDENTIFICATION
                                 19                 :  *    src/backend/executor/nodeUnique.c
                                 20                 :  *
                                 21                 :  *-------------------------------------------------------------------------
                                 22                 :  */
                                 23                 : /*
                                 24                 :  * INTERFACE ROUTINES
                                 25                 :  *      ExecUnique      - generate a unique'd temporary relation
                                 26                 :  *      ExecInitUnique  - initialize node and subnodes
                                 27                 :  *      ExecEndUnique   - shutdown node and subnodes
                                 28                 :  *
                                 29                 :  * NOTES
                                 30                 :  *      Assumes tuples returned from subplan arrive in
                                 31                 :  *      sorted order.
                                 32                 :  */
                                 33                 : 
                                 34                 : #include "postgres.h"
                                 35                 : 
                                 36                 : #include "executor/executor.h"
                                 37                 : #include "executor/nodeUnique.h"
                                 38                 : #include "miscadmin.h"
                                 39                 : #include "utils/memutils.h"
                                 40                 : 
                                 41                 : 
                                 42                 : /* ----------------------------------------------------------------
                                 43                 :  *      ExecUnique
                                 44                 :  * ----------------------------------------------------------------
                                 45                 :  */
                                 46                 : static TupleTableSlot *         /* return: a tuple or NULL */
 2092 andres                     47 CBC       41396 : ExecUnique(PlanState *pstate)
                                 48                 : {
                                 49           41396 :     UniqueState *node = castNode(UniqueState, pstate);
 1879                            50           41396 :     ExprContext *econtext = node->ps.ps_ExprContext;
                                 51                 :     TupleTableSlot *resultTupleSlot;
                                 52                 :     TupleTableSlot *slot;
                                 53                 :     PlanState  *outerPlan;
                                 54                 : 
 2084                            55           41396 :     CHECK_FOR_INTERRUPTS();
                                 56                 : 
                                 57                 :     /*
                                 58                 :      * get information from the node
                                 59                 :      */
 7430 tgl                        60           41396 :     outerPlan = outerPlanState(node);
                                 61           41396 :     resultTupleSlot = node->ps.ps_ResultTupleSlot;
                                 62                 : 
                                 63                 :     /*
                                 64                 :      * now loop, returning only non-duplicate tuples. We assume that the
                                 65                 :      * tuples arrive in sorted order so we can detect duplicates easily. The
                                 66                 :      * first tuple of each group is returned.
                                 67                 :      */
                                 68                 :     for (;;)
                                 69                 :     {
                                 70                 :         /*
                                 71                 :          * fetch a tuple from the outer subplan
                                 72                 :          */
                                 73          198736 :         slot = ExecProcNode(outerPlan);
 9345 bruce                      74          198736 :         if (TupIsNull(slot))
                                 75                 :         {
                                 76                 :             /* end of subplan, so we're done */
 6598 tgl                        77             678 :             ExecClearTuple(resultTupleSlot);
 9345 bruce                      78             678 :             return NULL;
                                 79                 :         }
                                 80                 : 
                                 81                 :         /*
                                 82                 :          * Always return the first tuple from the subplan.
                                 83                 :          */
 6598 tgl                        84          198058 :         if (TupIsNull(resultTupleSlot))
                                 85                 :             break;
                                 86                 : 
                                 87                 :         /*
                                 88                 :          * Else test if the new tuple and the previously returned tuple match.
                                 89                 :          * If so then we loop back and fetch another new tuple from the
                                 90                 :          * subplan.
                                 91                 :          */
 1879 andres                     92          197419 :         econtext->ecxt_innertuple = slot;
                                 93          197419 :         econtext->ecxt_outertuple = resultTupleSlot;
                                 94          197419 :         if (!ExecQualAndReset(node->eqfunction, econtext))
 8473 tgl                        95           40079 :             break;
                                 96                 :     }
                                 97                 : 
                                 98                 :     /*
                                 99                 :      * We have a new tuple different from the previous saved tuple (if any).
                                100                 :      * Save it and return it.  We must copy it because the source subplan
                                101                 :      * won't guarantee that this source tuple is still accessible after
                                102                 :      * fetching the next source tuple.
                                103                 :      */
 6598                           104           40718 :     return ExecCopySlot(resultTupleSlot, slot);
                                105                 : }
                                106                 : 
                                107                 : /* ----------------------------------------------------------------
                                108                 :  *      ExecInitUnique
                                109                 :  *
                                110                 :  *      This initializes the unique node state structures and
                                111                 :  *      the node's subplan.
                                112                 :  * ----------------------------------------------------------------
                                113                 :  */
                                114                 : UniqueState *
 6249                           115             793 : ExecInitUnique(Unique *node, EState *estate, int eflags)
                                116                 : {
                                117                 :     UniqueState *uniquestate;
                                118                 : 
                                119                 :     /* check for unsupported flags */
 5360                           120             793 :     Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
                                121                 : 
                                122                 :     /*
                                123                 :      * create state structure
                                124                 :      */
 9345 bruce                     125             793 :     uniquestate = makeNode(UniqueState);
 7430 tgl                       126             793 :     uniquestate->ps.plan = (Plan *) node;
                                127             793 :     uniquestate->ps.state = estate;
 2092 andres                    128             793 :     uniquestate->ps.ExecProcNode = ExecUnique;
                                129                 : 
                                130                 :     /*
                                131                 :      * create expression context
                                132                 :      */
 1879                           133             793 :     ExecAssignExprContext(estate, &uniquestate->ps);
                                134                 : 
                                135                 :     /*
                                136                 :      * then initialize outer plan
                                137                 :      */
 6249 tgl                       138             793 :     outerPlanState(uniquestate) = ExecInitNode(outerPlan(node), estate, eflags);
                                139                 : 
                                140                 :     /*
                                141                 :      * Initialize result slot and type. Unique nodes do no projections, so
                                142                 :      * initialize projection info for this node appropriately.
                                143                 :      */
 1606 andres                    144             793 :     ExecInitResultTupleSlotTL(&uniquestate->ps, &TTSOpsMinimalTuple);
 7430 tgl                       145             793 :     uniquestate->ps.ps_ProjInfo = NULL;
                                146                 : 
                                147                 :     /*
                                148                 :      * Precompute fmgr lookup data for inner loop
                                149                 :      */
 1879 andres                    150             793 :     uniquestate->eqfunction =
                                151             793 :         execTuplesMatchPrepare(ExecGetResultType(outerPlanState(uniquestate)),
                                152                 :                                node->numCols,
                                153             793 :                                node->uniqColIdx,
                                154             793 :                                node->uniqOperators,
 1479 peter                     155             793 :                                node->uniqCollations,
                                156                 :                                &uniquestate->ps);
                                157                 : 
 7430 tgl                       158             793 :     return uniquestate;
                                159                 : }
                                160                 : 
                                161                 : /* ----------------------------------------------------------------
                                162                 :  *      ExecEndUnique
                                163                 :  *
                                164                 :  *      This shuts down the subplan and frees resources allocated
                                165                 :  *      to this node.
                                166                 :  * ----------------------------------------------------------------
                                167                 :  */
                                168                 : void
                                169             793 : ExecEndUnique(UniqueState *node)
                                170                 : {
                                171                 :     /* clean up tuple table */
                                172             793 :     ExecClearTuple(node->ps.ps_ResultTupleSlot);
                                173                 : 
 1879 andres                    174             793 :     ExecFreeExprContext(&node->ps);
                                175                 : 
 7420 tgl                       176             793 :     ExecEndNode(outerPlanState(node));
 9345 bruce                     177             793 : }
                                178                 : 
                                179                 : 
                                180                 : void
 4654 tgl                       181 UBC           0 : ExecReScanUnique(UniqueState *node)
                                182                 : {
  276 tgl                       183 UNC           0 :     PlanState  *outerPlan = outerPlanState(node);
                                184                 : 
 6598 tgl                       185 EUB             :     /* must clear result tuple so first input tuple is returned */
 7430 tgl                       186 UIC           0 :     ExecClearTuple(node->ps.ps_ResultTupleSlot);
                                187                 : 
 9173 bruce                     188 EUB             :     /*
                                189                 :      * if chgParam of subnode is not null then plan will be re-scanned by
                                190                 :      * first ExecProcNode.
                                191                 :      */
  276 tgl                       192 UNC           0 :     if (outerPlan->chgParam == NULL)
                                193               0 :         ExecReScan(outerPlan);
 9176 vadim4o                   194 UBC           0 : }
        

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