LCOV - differential code coverage report
Current view: top level - src/backend/executor - execJunk.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 91.9 % 74 68 6 68
Current Date: 2024-04-14 14:21:10 Functions: 80.0 % 5 4 1 4
Baseline: 16@8cea358b128 Branches: 85.0 % 40 34 6 34
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 91.9 % 74 68 6 68
Function coverage date bins:
(240..) days: 80.0 % 5 4 1 4
Branch coverage date bins:
(240..) days: 85.0 % 40 34 6 34

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * execJunk.c
                                  4                 :                :  *    Junk attribute support stuff....
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/backend/executor/execJunk.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : #include "postgres.h"
                                 16                 :                : 
                                 17                 :                : #include "executor/executor.h"
                                 18                 :                : 
                                 19                 :                : /*-------------------------------------------------------------------------
                                 20                 :                :  *      XXX this stuff should be rewritten to take advantage
                                 21                 :                :  *          of ExecProject() and the ProjectionInfo node.
                                 22                 :                :  *          -cim 6/3/91
                                 23                 :                :  *
                                 24                 :                :  * An attribute of a tuple living inside the executor, can be
                                 25                 :                :  * either a normal attribute or a "junk" attribute. "junk" attributes
                                 26                 :                :  * never make it out of the executor, i.e. they are never printed,
                                 27                 :                :  * returned or stored on disk. Their only purpose in life is to
                                 28                 :                :  * store some information useful only to the executor, mainly the values
                                 29                 :                :  * of system attributes like "ctid", or sort key columns that are not to
                                 30                 :                :  * be output.
                                 31                 :                :  *
                                 32                 :                :  * The general idea is the following: A target list consists of a list of
                                 33                 :                :  * TargetEntry nodes containing expressions. Each TargetEntry has a field
                                 34                 :                :  * called 'resjunk'. If the value of this field is true then the
                                 35                 :                :  * corresponding attribute is a "junk" attribute.
                                 36                 :                :  *
                                 37                 :                :  * When we initialize a plan we call ExecInitJunkFilter to create a filter.
                                 38                 :                :  *
                                 39                 :                :  * We then execute the plan, treating the resjunk attributes like any others.
                                 40                 :                :  *
                                 41                 :                :  * Finally, when at the top level we get back a tuple, we can call
                                 42                 :                :  * ExecFindJunkAttribute/ExecGetJunkAttribute to retrieve the values of the
                                 43                 :                :  * junk attributes we are interested in, and ExecFilterJunk to remove all the
                                 44                 :                :  * junk attributes from a tuple.  This new "clean" tuple is then printed,
                                 45                 :                :  * inserted, or updated.
                                 46                 :                :  *
                                 47                 :                :  *-------------------------------------------------------------------------
                                 48                 :                :  */
                                 49                 :                : 
                                 50                 :                : /*
                                 51                 :                :  * ExecInitJunkFilter
                                 52                 :                :  *
                                 53                 :                :  * Initialize the Junk filter.
                                 54                 :                :  *
                                 55                 :                :  * The source targetlist is passed in.  The output tuple descriptor is
                                 56                 :                :  * built from the non-junk tlist entries.
                                 57                 :                :  * An optional resultSlot can be passed as well; otherwise, we create one.
                                 58                 :                :  */
                                 59                 :                : JunkFilter *
 1972 andres@anarazel.de         60                 :CBC       28681 : ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
                                 61                 :                : {
                                 62                 :                :     JunkFilter *junkfilter;
                                 63                 :                :     TupleDesc   cleanTupType;
                                 64                 :                :     int         cleanLength;
                                 65                 :                :     AttrNumber *cleanMap;
                                 66                 :                : 
                                 67                 :                :     /*
                                 68                 :                :      * Compute the tuple descriptor for the cleaned tuple.
                                 69                 :                :      */
                                 70                 :          28681 :     cleanTupType = ExecCleanTypeFromTL(targetList);
                                 71                 :                : 
                                 72                 :                :     /*
                                 73                 :                :      * Use the given slot, or make a new slot if we weren't given one.
                                 74                 :                :      */
 6969 tgl@sss.pgh.pa.us          75         [ +  - ]:          28681 :     if (slot)
 6512                            76                 :          28681 :         ExecSetSlotDescriptor(slot, cleanTupType);
                                 77                 :                :     else
 1977 andres@anarazel.de         78                 :UBC           0 :         slot = MakeSingleTupleTableSlot(cleanTupType, &TTSOpsVirtual);
                                 79                 :                : 
                                 80                 :                :     /*
                                 81                 :                :      * Now calculate the mapping between the original tuple's attributes and
                                 82                 :                :      * the "clean" tuple's attributes.
                                 83                 :                :      *
                                 84                 :                :      * The "map" is an array of "cleanLength" attribute numbers, i.e. one
                                 85                 :                :      * entry for every attribute of the "clean" tuple. The value of this entry
                                 86                 :                :      * is the attribute number of the corresponding attribute of the
                                 87                 :                :      * "original" tuple.  (Zero indicates a NULL output attribute, but we do
                                 88                 :                :      * not use that feature in this routine.)
                                 89                 :                :      */
 7129 tgl@sss.pgh.pa.us          90                 :CBC       28681 :     cleanLength = cleanTupType->natts;
                                 91         [ +  + ]:          28681 :     if (cleanLength > 0)
                                 92                 :                :     {
                                 93                 :                :         AttrNumber  cleanResno;
                                 94                 :                :         ListCell   *t;
                                 95                 :                : 
                                 96                 :          28645 :         cleanMap = (AttrNumber *) palloc(cleanLength * sizeof(AttrNumber));
 1266                            97                 :          28645 :         cleanResno = 0;
 7129                            98   [ +  -  +  +  :          96072 :         foreach(t, targetList)
                                              +  + ]
                                 99                 :                :         {
                                100                 :          67427 :             TargetEntry *tle = lfirst(t);
                                101                 :                : 
 6948                           102         [ +  + ]:          67427 :             if (!tle->resjunk)
                                103                 :                :             {
 1266                           104                 :          52859 :                 cleanMap[cleanResno] = tle->resno;
 7129                           105                 :          52859 :                 cleanResno++;
                                106                 :                :             }
                                107                 :                :         }
 1266                           108         [ -  + ]:          28645 :         Assert(cleanResno == cleanLength);
                                109                 :                :     }
                                110                 :                :     else
 7129                           111                 :             36 :         cleanMap = NULL;
                                112                 :                : 
                                113                 :                :     /*
                                114                 :                :      * Finally create and initialize the JunkFilter struct.
                                115                 :                :      */
                                116                 :          28681 :     junkfilter = makeNode(JunkFilter);
                                117                 :                : 
                                118                 :          28681 :     junkfilter->jf_targetList = targetList;
                                119                 :          28681 :     junkfilter->jf_cleanTupType = cleanTupType;
                                120                 :          28681 :     junkfilter->jf_cleanMap = cleanMap;
                                121                 :          28681 :     junkfilter->jf_resultSlot = slot;
                                122                 :                : 
                                123                 :          28681 :     return junkfilter;
                                124                 :                : }
                                125                 :                : 
                                126                 :                : /*
                                127                 :                :  * ExecInitJunkFilterConversion
                                128                 :                :  *
                                129                 :                :  * Initialize a JunkFilter for rowtype conversions.
                                130                 :                :  *
                                131                 :                :  * Here, we are given the target "clean" tuple descriptor rather than
                                132                 :                :  * inferring it from the targetlist.  The target descriptor can contain
                                133                 :                :  * deleted columns.  It is assumed that the caller has checked that the
                                134                 :                :  * non-deleted columns match up with the non-junk columns of the targetlist.
                                135                 :                :  */
                                136                 :                : JunkFilter *
                                137                 :            618 : ExecInitJunkFilterConversion(List *targetList,
                                138                 :                :                              TupleDesc cleanTupType,
                                139                 :                :                              TupleTableSlot *slot)
                                140                 :                : {
                                141                 :                :     JunkFilter *junkfilter;
                                142                 :                :     int         cleanLength;
                                143                 :                :     AttrNumber *cleanMap;
                                144                 :                :     ListCell   *t;
                                145                 :                :     int         i;
                                146                 :                : 
                                147                 :                :     /*
                                148                 :                :      * Use the given slot, or make a new slot if we weren't given one.
                                149                 :                :      */
 6969                           150         [ +  - ]:            618 :     if (slot)
 6512                           151                 :            618 :         ExecSetSlotDescriptor(slot, cleanTupType);
                                152                 :                :     else
 1977 andres@anarazel.de        153                 :UBC           0 :         slot = MakeSingleTupleTableSlot(cleanTupType, &TTSOpsVirtual);
                                154                 :                : 
                                155                 :                :     /*
                                156                 :                :      * Calculate the mapping between the original tuple's attributes and the
                                157                 :                :      * "clean" tuple's attributes.
                                158                 :                :      *
                                159                 :                :      * The "map" is an array of "cleanLength" attribute numbers, i.e. one
                                160                 :                :      * entry for every attribute of the "clean" tuple. The value of this entry
                                161                 :                :      * is the attribute number of the corresponding attribute of the
                                162                 :                :      * "original" tuple.  We store zero for any deleted attributes, marking
                                163                 :                :      * that a NULL is needed in the output tuple.
                                164                 :                :      */
 7129 tgl@sss.pgh.pa.us         165                 :CBC         618 :     cleanLength = cleanTupType->natts;
 9716 bruce@momjian.us          166         [ +  - ]:            618 :     if (cleanLength > 0)
                                167                 :                :     {
 7129 tgl@sss.pgh.pa.us         168                 :            618 :         cleanMap = (AttrNumber *) palloc0(cleanLength * sizeof(AttrNumber));
                                169                 :            618 :         t = list_head(targetList);
                                170         [ +  + ]:           2246 :         for (i = 0; i < cleanLength; i++)
                                171                 :                :         {
 2429 andres@anarazel.de        172         [ +  + ]:           1628 :             if (TupleDescAttr(cleanTupType, i)->attisdropped)
 7129 tgl@sss.pgh.pa.us         173                 :             33 :                 continue;       /* map entry is already zero */
                                174                 :                :             for (;;)
 9716 bruce@momjian.us          175                 :UBC           0 :             {
 7129 tgl@sss.pgh.pa.us         176                 :CBC        1595 :                 TargetEntry *tle = lfirst(t);
                                177                 :                : 
 1735                           178                 :           1595 :                 t = lnext(targetList, t);
 6948                           179         [ +  - ]:           1595 :                 if (!tle->resjunk)
                                180                 :                :                 {
                                181                 :           1595 :                     cleanMap[i] = tle->resno;
 7129                           182                 :           1595 :                     break;
                                183                 :                :                 }
                                184                 :                :             }
                                185                 :                :         }
                                186                 :                :     }
                                187                 :                :     else
 9716 bruce@momjian.us          188                 :UBC           0 :         cleanMap = NULL;
                                189                 :                : 
                                190                 :                :     /*
                                191                 :                :      * Finally create and initialize the JunkFilter struct.
                                192                 :                :      */
 9716 bruce@momjian.us          193                 :CBC         618 :     junkfilter = makeNode(JunkFilter);
                                194                 :                : 
                                195                 :            618 :     junkfilter->jf_targetList = targetList;
                                196                 :            618 :     junkfilter->jf_cleanTupType = cleanTupType;
                                197                 :            618 :     junkfilter->jf_cleanMap = cleanMap;
 8358 tgl@sss.pgh.pa.us         198                 :            618 :     junkfilter->jf_resultSlot = slot;
                                199                 :                : 
 9357 bruce@momjian.us          200                 :            618 :     return junkfilter;
                                201                 :                : }
                                202                 :                : 
                                203                 :                : /*
                                204                 :                :  * ExecFindJunkAttribute
                                205                 :                :  *
                                206                 :                :  * Locate the specified junk attribute in the junk filter's targetlist,
                                207                 :                :  * and return its resno.  Returns InvalidAttrNumber if not found.
                                208                 :                :  */
                                209                 :                : AttrNumber
 6341 tgl@sss.pgh.pa.us         210                 :UBC           0 : ExecFindJunkAttribute(JunkFilter *junkfilter, const char *attrName)
                                211                 :                : {
 4841                           212                 :              0 :     return ExecFindJunkAttributeInTlist(junkfilter->jf_targetList, attrName);
                                213                 :                : }
                                214                 :                : 
                                215                 :                : /*
                                216                 :                :  * ExecFindJunkAttributeInTlist
                                217                 :                :  *
                                218                 :                :  * Find a junk attribute given a subplan's targetlist (not necessarily
                                219                 :                :  * part of a JunkFilter).
                                220                 :                :  */
                                221                 :                : AttrNumber
 4841 tgl@sss.pgh.pa.us         222                 :CBC       77528 : ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
                                223                 :                : {
                                224                 :                :     ListCell   *t;
                                225                 :                : 
                                226   [ +  +  +  +  :         215392 :     foreach(t, targetlist)
                                              +  + ]
                                227                 :                :     {
 9715 bruce@momjian.us          228                 :         159981 :         TargetEntry *tle = lfirst(t);
                                229                 :                : 
 6948 tgl@sss.pgh.pa.us         230   [ +  +  +  + ]:         159981 :         if (tle->resjunk && tle->resname &&
                                231         [ +  + ]:          41462 :             (strcmp(tle->resname, attrName) == 0))
                                232                 :                :         {
                                233                 :                :             /* We found it ! */
 6341                           234                 :          22117 :             return tle->resno;
                                235                 :                :         }
                                236                 :                :     }
                                237                 :                : 
                                238                 :          55411 :     return InvalidAttrNumber;
                                239                 :                : }
                                240                 :                : 
                                241                 :                : /*
                                242                 :                :  * ExecFilterJunk
                                243                 :                :  *
                                244                 :                :  * Construct and return a slot with all the junk attributes removed.
                                245                 :                :  */
                                246                 :                : TupleTableSlot *
 6969                           247                 :         234607 : ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
                                248                 :                : {
                                249                 :                :     TupleTableSlot *resultSlot;
                                250                 :                :     AttrNumber *cleanMap;
                                251                 :                :     TupleDesc   cleanTupType;
                                252                 :                :     int         cleanLength;
                                253                 :                :     int         i;
                                254                 :                :     Datum      *values;
                                255                 :                :     bool       *isnull;
                                256                 :                :     Datum      *old_values;
                                257                 :                :     bool       *old_isnull;
                                258                 :                : 
                                259                 :                :     /*
                                260                 :                :      * Extract all the values of the old tuple.
                                261                 :                :      */
                                262                 :         234607 :     slot_getallattrs(slot);
                                263                 :         234607 :     old_values = slot->tts_values;
                                264                 :         234607 :     old_isnull = slot->tts_isnull;
                                265                 :                : 
                                266                 :                :     /*
                                267                 :                :      * get info from the junk filter
                                268                 :                :      */
 8476                           269                 :         234607 :     cleanTupType = junkfilter->jf_cleanTupType;
 7129                           270                 :         234607 :     cleanLength = cleanTupType->natts;
 9716 bruce@momjian.us          271                 :         234607 :     cleanMap = junkfilter->jf_cleanMap;
 6969 tgl@sss.pgh.pa.us         272                 :         234607 :     resultSlot = junkfilter->jf_resultSlot;
                                273                 :                : 
                                274                 :                :     /*
                                275                 :                :      * Prepare to build a virtual result tuple.
                                276                 :                :      */
                                277                 :         234607 :     ExecClearTuple(resultSlot);
                                278                 :         234607 :     values = resultSlot->tts_values;
                                279                 :         234607 :     isnull = resultSlot->tts_isnull;
                                280                 :                : 
                                281                 :                :     /*
                                282                 :                :      * Transpose data into proper fields of the new tuple.
                                283                 :                :      */
 9716 bruce@momjian.us          284         [ +  + ]:         735840 :     for (i = 0; i < cleanLength; i++)
                                285                 :                :     {
 7129 tgl@sss.pgh.pa.us         286                 :         501233 :         int         j = cleanMap[i];
                                287                 :                : 
 6969                           288         [ +  + ]:         501233 :         if (j == 0)
                                289                 :                :         {
                                290                 :             60 :             values[i] = (Datum) 0;
                                291                 :             60 :             isnull[i] = true;
                                292                 :                :         }
                                293                 :                :         else
                                294                 :                :         {
                                295                 :         501173 :             values[i] = old_values[j - 1];
                                296                 :         501173 :             isnull[i] = old_isnull[j - 1];
                                297                 :                :         }
                                298                 :                :     }
                                299                 :                : 
                                300                 :                :     /*
                                301                 :                :      * And return the virtual tuple.
                                302                 :                :      */
                                303                 :         234607 :     return ExecStoreVirtualTuple(resultSlot);
                                304                 :                : }
        

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