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 HEAD vs 15 Lines: 91.9 % 74 68 6 68
Current Date: 2023-04-08 17:13:01 Functions: 80.0 % 5 4 1 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 91.9 % 74 68 6 68
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 80.0 % 5 4 1 4

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * execJunk.c
                                  4                 :  *    Junk attribute support stuff....
                                  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/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 *
 1601 andres                     60 CBC       18174 : 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           18174 :     cleanTupType = ExecCleanTypeFromTL(targetList);
                                 71                 : 
                                 72                 :     /*
                                 73                 :      * Use the given slot, or make a new slot if we weren't given one.
                                 74                 :      */
 6598 tgl                        75           18174 :     if (slot)
 6141                            76           18174 :         ExecSetSlotDescriptor(slot, cleanTupType);
                                 77                 :     else
 1606 andres                     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                 :      */
 6758 tgl                        90 CBC       18174 :     cleanLength = cleanTupType->natts;
                                 91           18174 :     if (cleanLength > 0)
                                 92                 :     {
                                 93                 :         AttrNumber  cleanResno;
                                 94                 :         ListCell   *t;
                                 95                 : 
                                 96           18138 :         cleanMap = (AttrNumber *) palloc(cleanLength * sizeof(AttrNumber));
  895                            97           18138 :         cleanResno = 0;
 6758                            98           67899 :         foreach(t, targetList)
                                 99                 :         {
                                100           49761 :             TargetEntry *tle = lfirst(t);
                                101                 : 
 6577                           102           49761 :             if (!tle->resjunk)
                                103                 :             {
  895                           104           37229 :                 cleanMap[cleanResno] = tle->resno;
 6758                           105           37229 :                 cleanResno++;
                                106                 :             }
                                107                 :         }
  895                           108           18138 :         Assert(cleanResno == cleanLength);
                                109                 :     }
                                110                 :     else
 6758                           111              36 :         cleanMap = NULL;
                                112                 : 
                                113                 :     /*
                                114                 :      * Finally create and initialize the JunkFilter struct.
                                115                 :      */
                                116           18174 :     junkfilter = makeNode(JunkFilter);
                                117                 : 
                                118           18174 :     junkfilter->jf_targetList = targetList;
                                119           18174 :     junkfilter->jf_cleanTupType = cleanTupType;
                                120           18174 :     junkfilter->jf_cleanMap = cleanMap;
                                121           18174 :     junkfilter->jf_resultSlot = slot;
                                122                 : 
                                123           18174 :     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             609 : 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                 :      */
 6598                           150             609 :     if (slot)
 6141                           151             609 :         ExecSetSlotDescriptor(slot, cleanTupType);
                                152                 :     else
 1606 andres                    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                 :      */
 6758 tgl                       165 CBC         609 :     cleanLength = cleanTupType->natts;
 9345 bruce                     166             609 :     if (cleanLength > 0)
                                167                 :     {
 6758 tgl                       168             609 :         cleanMap = (AttrNumber *) palloc0(cleanLength * sizeof(AttrNumber));
                                169             609 :         t = list_head(targetList);
                                170            2216 :         for (i = 0; i < cleanLength; i++)
                                171                 :         {
 2058 andres                    172            1607 :             if (TupleDescAttr(cleanTupType, i)->attisdropped)
 6758 tgl                       173              33 :                 continue;       /* map entry is already zero */
                                174                 :             for (;;)
 9345 bruce                     175 UBC           0 :             {
 6758 tgl                       176 CBC        1574 :                 TargetEntry *tle = lfirst(t);
                                177                 : 
 1364                           178            1574 :                 t = lnext(targetList, t);
 6577                           179            1574 :                 if (!tle->resjunk)
                                180                 :                 {
                                181            1574 :                     cleanMap[i] = tle->resno;
 6758                           182            1574 :                     break;
                                183                 :                 }
                                184                 :             }
                                185                 :         }
                                186                 :     }
                                187                 :     else
 9345 bruce                     188 UBC           0 :         cleanMap = NULL;
                                189                 : 
                                190                 :     /*
                                191                 :      * Finally create and initialize the JunkFilter struct.
                                192                 :      */
 9345 bruce                     193 CBC         609 :     junkfilter = makeNode(JunkFilter);
                                194                 : 
                                195             609 :     junkfilter->jf_targetList = targetList;
                                196             609 :     junkfilter->jf_cleanTupType = cleanTupType;
                                197             609 :     junkfilter->jf_cleanMap = cleanMap;
 7987 tgl                       198             609 :     junkfilter->jf_resultSlot = slot;
                                199                 : 
 8986 bruce                     200             609 :     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
 5970 tgl                       210 UBC           0 : ExecFindJunkAttribute(JunkFilter *junkfilter, const char *attrName)
                                211                 : {
 4470                           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
 4470 tgl                       222 CBC       85750 : ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
                                223                 : {
                                224                 :     ListCell   *t;
                                225                 : 
                                226          288426 :     foreach(t, targetlist)
                                227                 :     {
 9344 bruce                     228          223970 :         TargetEntry *tle = lfirst(t);
                                229                 : 
 6577 tgl                       230          223970 :         if (tle->resjunk && tle->resname &&
                                231           39759 :             (strcmp(tle->resname, attrName) == 0))
                                232                 :         {
                                233                 :             /* We found it ! */
 5970                           234           21294 :             return tle->resno;
                                235                 :         }
                                236                 :     }
                                237                 : 
                                238           64456 :     return InvalidAttrNumber;
                                239                 : }
                                240                 : 
                                241                 : /*
                                242                 :  * ExecFilterJunk
                                243                 :  *
                                244                 :  * Construct and return a slot with all the junk attributes removed.
                                245                 :  */
                                246                 : TupleTableSlot *
 6598                           247          205727 : 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          205727 :     slot_getallattrs(slot);
                                263          205727 :     old_values = slot->tts_values;
                                264          205727 :     old_isnull = slot->tts_isnull;
                                265                 : 
                                266                 :     /*
                                267                 :      * get info from the junk filter
                                268                 :      */
 8105                           269          205727 :     cleanTupType = junkfilter->jf_cleanTupType;
 6758                           270          205727 :     cleanLength = cleanTupType->natts;
 9345 bruce                     271          205727 :     cleanMap = junkfilter->jf_cleanMap;
 6598 tgl                       272          205727 :     resultSlot = junkfilter->jf_resultSlot;
                                273                 : 
                                274                 :     /*
                                275                 :      * Prepare to build a virtual result tuple.
                                276                 :      */
                                277          205727 :     ExecClearTuple(resultSlot);
                                278          205727 :     values = resultSlot->tts_values;
                                279          205727 :     isnull = resultSlot->tts_isnull;
                                280                 : 
                                281                 :     /*
                                282                 :      * Transpose data into proper fields of the new tuple.
                                283                 :      */
 9345 bruce                     284          668158 :     for (i = 0; i < cleanLength; i++)
                                285                 :     {
 6758 tgl                       286          462431 :         int         j = cleanMap[i];
                                287                 : 
 6598                           288          462431 :         if (j == 0)
                                289                 :         {
                                290              60 :             values[i] = (Datum) 0;
                                291              60 :             isnull[i] = true;
                                292                 :         }
                                293                 :         else
                                294                 :         {
                                295          462371 :             values[i] = old_values[j - 1];
                                296          462371 :             isnull[i] = old_isnull[j - 1];
                                297                 :         }
                                298                 :     }
                                299                 : 
                                300                 :     /*
                                301                 :      * And return the virtual tuple.
                                302                 :      */
                                303          205727 :     return ExecStoreVirtualTuple(resultSlot);
                                304                 : }
        

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