LCOV - differential code coverage report
Current view: top level - src/backend/nodes - equalfuncs.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 76.8 % 69 53 16 53
Current Date: 2024-04-14 14:21:10 Functions: 83.3 % 6 5 1 5
Baseline: 16@8cea358b128 Branches: 33.2 % 391 130 30 10 221 26 6 98
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: 76.8 % 69 53 16 53
Function coverage date bins:
(240..) days: 83.3 % 6 5 1 5
Branch coverage date bins:
(240..) days: 33.2 % 391 130 30 10 221 26 6 98

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * equalfuncs.c
                                  4                 :                :  *    Equality functions to compare node trees.
                                  5                 :                :  *
                                  6                 :                :  * NOTE: it is intentional that parse location fields (in nodes that have
                                  7                 :                :  * one) are not compared.  This is because we want, for example, a variable
                                  8                 :                :  * "x" to be considered equal() to another reference to "x" in the query.
                                  9                 :                :  *
                                 10                 :                :  *
                                 11                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                 12                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 13                 :                :  *
                                 14                 :                :  * IDENTIFICATION
                                 15                 :                :  *    src/backend/nodes/equalfuncs.c
                                 16                 :                :  *
                                 17                 :                :  *-------------------------------------------------------------------------
                                 18                 :                :  */
                                 19                 :                : 
                                 20                 :                : #include "postgres.h"
                                 21                 :                : 
                                 22                 :                : #include "miscadmin.h"
                                 23                 :                : #include "utils/datum.h"
                                 24                 :                : 
                                 25                 :                : 
                                 26                 :                : /*
                                 27                 :                :  * Macros to simplify comparison of different kinds of fields.  Use these
                                 28                 :                :  * wherever possible to reduce the chance for silly typos.  Note that these
                                 29                 :                :  * hard-wire the convention that the local variables in an Equal routine are
                                 30                 :                :  * named 'a' and 'b'.
                                 31                 :                :  */
                                 32                 :                : 
                                 33                 :                : /* Compare a simple scalar field (int, float, bool, enum, etc) */
                                 34                 :                : #define COMPARE_SCALAR_FIELD(fldname) \
                                 35                 :                :     do { \
                                 36                 :                :         if (a->fldname != b->fldname) \
                                 37                 :                :             return false; \
                                 38                 :                :     } while (0)
                                 39                 :                : 
                                 40                 :                : /* Compare a field that is a pointer to some kind of Node or Node tree */
                                 41                 :                : #define COMPARE_NODE_FIELD(fldname) \
                                 42                 :                :     do { \
                                 43                 :                :         if (!equal(a->fldname, b->fldname)) \
                                 44                 :                :             return false; \
                                 45                 :                :     } while (0)
                                 46                 :                : 
                                 47                 :                : /* Compare a field that is a pointer to a Bitmapset */
                                 48                 :                : #define COMPARE_BITMAPSET_FIELD(fldname) \
                                 49                 :                :     do { \
                                 50                 :                :         if (!bms_equal(a->fldname, b->fldname)) \
                                 51                 :                :             return false; \
                                 52                 :                :     } while (0)
                                 53                 :                : 
                                 54                 :                : /* Compare a field that is a pointer to a C string, or perhaps NULL */
                                 55                 :                : #define COMPARE_STRING_FIELD(fldname) \
                                 56                 :                :     do { \
                                 57                 :                :         if (!equalstr(a->fldname, b->fldname)) \
                                 58                 :                :             return false; \
                                 59                 :                :     } while (0)
                                 60                 :                : 
                                 61                 :                : /* Macro for comparing string fields that might be NULL */
                                 62                 :                : #define equalstr(a, b)  \
                                 63                 :                :     (((a) != NULL && (b) != NULL) ? (strcmp(a, b) == 0) : (a) == (b))
                                 64                 :                : 
                                 65                 :                : /* Compare a field that is an inline array */
                                 66                 :                : #define COMPARE_ARRAY_FIELD(fldname) \
                                 67                 :                :     do { \
                                 68                 :                :         if (memcmp(a->fldname, b->fldname, sizeof(a->fldname)) != 0) \
                                 69                 :                :             return false; \
                                 70                 :                :     } while (0)
                                 71                 :                : 
                                 72                 :                : /* Compare a field that is a pointer to a simple palloc'd object of size sz */
                                 73                 :                : #define COMPARE_POINTER_FIELD(fldname, sz) \
                                 74                 :                :     do { \
                                 75                 :                :         if (memcmp(a->fldname, b->fldname, (sz)) != 0) \
                                 76                 :                :             return false; \
                                 77                 :                :     } while (0)
                                 78                 :                : 
                                 79                 :                : /* Compare a parse location field (this is a no-op, per note above) */
                                 80                 :                : #define COMPARE_LOCATION_FIELD(fldname) \
                                 81                 :                :     ((void) 0)
                                 82                 :                : 
                                 83                 :                : /* Compare a CoercionForm field (also a no-op, per comment in primnodes.h) */
                                 84                 :                : #define COMPARE_COERCIONFORM_FIELD(fldname) \
                                 85                 :                :     ((void) 0)
                                 86                 :                : 
                                 87                 :                : 
                                 88                 :                : #include "equalfuncs.funcs.c"
                                 89                 :                : 
                                 90                 :                : 
                                 91                 :                : /*
                                 92                 :                :  * Support functions for nodes with custom_copy_equal attribute
                                 93                 :                :  */
                                 94                 :                : 
                                 95                 :                : static bool
 4512 peter_e@gmx.net            96                 :CBC       78850 : _equalConst(const Const *a, const Const *b)
                                 97                 :                : {
 7811 tgl@sss.pgh.pa.us          98         [ +  + ]:          78850 :     COMPARE_SCALAR_FIELD(consttype);
 6238                            99         [ +  + ]:          64625 :     COMPARE_SCALAR_FIELD(consttypmod);
 4814 peter_e@gmx.net           100         [ +  + ]:          64615 :     COMPARE_SCALAR_FIELD(constcollid);
 7811 tgl@sss.pgh.pa.us         101         [ -  + ]:          61878 :     COMPARE_SCALAR_FIELD(constlen);
                                102         [ +  + ]:          61878 :     COMPARE_SCALAR_FIELD(constisnull);
                                103         [ -  + ]:          61744 :     COMPARE_SCALAR_FIELD(constbyval);
                                104                 :                :     COMPARE_LOCATION_FIELD(location);
                                105                 :                : 
                                106                 :                :     /*
                                107                 :                :      * We treat all NULL constants of the same type as equal. Someday this
                                108                 :                :      * might need to change?  But datumIsEqual doesn't work on nulls, so...
                                109                 :                :      */
 8878                           110         [ +  + ]:          61744 :     if (a->constisnull)
                                111                 :           5956 :         return true;
 8677                           112                 :          55788 :     return datumIsEqual(a->constvalue, b->constvalue,
                                113                 :          55788 :                         a->constbyval, a->constlen);
                                114                 :                : }
                                115                 :                : 
                                116                 :                : static bool
  645 peter@eisentraut.org      117                 :UBC           0 : _equalExtensibleNode(const ExtensibleNode *a, const ExtensibleNode *b)
                                118                 :                : {
                                119                 :                :     const ExtensibleNodeMethods *methods;
                                120                 :                : 
                                121   [ #  #  #  #  :              0 :     COMPARE_STRING_FIELD(extnodename);
                                              #  # ]
                                122                 :                : 
                                123                 :                :     /* At this point, we know extnodename is the same for both nodes. */
                                124                 :              0 :     methods = GetExtensibleNodeMethods(a->extnodename, false);
                                125                 :                : 
                                126                 :                :     /* compare the private fields */
                                127         [ #  # ]:              0 :     if (!methods->nodeEqual(a, b))
                                128                 :              0 :         return false;
                                129                 :                : 
 5302 tgl@sss.pgh.pa.us         130                 :              0 :     return true;
                                131                 :                : }
                                132                 :                : 
                                133                 :                : static bool
  645 peter@eisentraut.org      134                 :CBC          81 : _equalA_Const(const A_Const *a, const A_Const *b)
                                135                 :                : {
  392 tgl@sss.pgh.pa.us         136         [ -  + ]:             81 :     COMPARE_SCALAR_FIELD(isnull);
                                137                 :                :     /* Hack for in-line val field.  Also val is not valid if isnull is true */
                                138         [ +  - ]:             81 :     if (!a->isnull &&
  645 peter@eisentraut.org      139         [ -  + ]:             81 :         !equal(&a->val, &b->val))
 7794 tgl@sss.pgh.pa.us         140                 :UBC           0 :         return false;
                                141                 :                :     COMPARE_LOCATION_FIELD(location);
                                142                 :                : 
 7794 tgl@sss.pgh.pa.us         143                 :CBC          81 :     return true;
                                144                 :                : }
                                145                 :                : 
                                146                 :                : static bool
  518                           147                 :          19916 : _equalBitmapset(const Bitmapset *a, const Bitmapset *b)
                                148                 :                : {
                                149                 :          19916 :     return bms_equal(a, b);
                                150                 :                : }
                                151                 :                : 
                                152                 :                : /*
                                153                 :                :  * Lists are handled specially
                                154                 :                :  */
                                155                 :                : static bool
  645 peter@eisentraut.org      156                 :        2083924 : _equalList(const List *a, const List *b)
                                157                 :                : {
                                158                 :                :     const ListCell *item_a;
                                159                 :                :     const ListCell *item_b;
                                160                 :                : 
                                161                 :                :     /*
                                162                 :                :      * Try to reject by simple scalar checks before grovelling through all the
                                163                 :                :      * list elements...
                                164                 :                :      */
                                165         [ -  + ]:        2083924 :     COMPARE_SCALAR_FIELD(type);
                                166         [ +  + ]:        2083924 :     COMPARE_SCALAR_FIELD(length);
                                167                 :                : 
                                168                 :                :     /*
                                169                 :                :      * We place the switch outside the loop for the sake of efficiency; this
                                170                 :                :      * may not be worth doing...
                                171                 :                :      */
                                172   [ +  +  +  -  :        2025927 :     switch (a->type)
                                                 - ]
                                173                 :                :     {
                                174                 :         194456 :         case T_List:
                                175   [ +  -  +  +  :         484795 :             forboth(item_a, a, item_b, b)
                                     +  -  +  +  +  
                                        +  +  -  +  
                                                 + ]
                                176                 :                :             {
                                177         [ +  + ]:         363831 :                 if (!equal(lfirst(item_a), lfirst(item_b)))
                                178                 :          73492 :                     return false;
                                179                 :                :             }
                                180                 :         120964 :             break;
                                181                 :           2805 :         case T_IntList:
                                182   [ +  -  +  +  :           9458 :             forboth(item_a, a, item_b, b)
                                     +  -  +  +  +  
                                        +  +  -  +  
                                                 + ]
                                183                 :                :             {
                                184         [ +  + ]:           6661 :                 if (lfirst_int(item_a) != lfirst_int(item_b))
                                185                 :              8 :                     return false;
                                186                 :                :             }
                                187                 :           2797 :             break;
                                188                 :        1828666 :         case T_OidList:
                                189   [ +  -  +  +  :        3373911 :             forboth(item_a, a, item_b, b)
                                     +  -  +  +  +  
                                        +  +  -  +  
                                                 + ]
                                190                 :                :             {
                                191         [ +  + ]:        1889976 :                 if (lfirst_oid(item_a) != lfirst_oid(item_b))
                                192                 :         344731 :                     return false;
                                193                 :                :             }
                                194                 :        1483935 :             break;
  642 alvherre@alvh.no-ip.      195                 :UBC           0 :         case T_XidList:
                                196   [ #  #  #  #  :              0 :             forboth(item_a, a, item_b, b)
                                     #  #  #  #  #  
                                        #  #  #  #  
                                                 # ]
                                197                 :                :             {
                                198         [ #  # ]:              0 :                 if (lfirst_xid(item_a) != lfirst_xid(item_b))
                                199                 :              0 :                     return false;
                                200                 :                :             }
                                201                 :              0 :             break;
  645 peter@eisentraut.org      202                 :              0 :         default:
                                203         [ #  # ]:              0 :             elog(ERROR, "unrecognized list node type: %d",
                                204                 :                :                  (int) a->type);
                                205                 :                :             return false;       /* keep compiler quiet */
                                206                 :                :     }
                                207                 :                : 
                                208                 :                :     /*
                                209                 :                :      * If we got here, we should have run out of elements of both lists
                                210                 :                :      */
  645 peter@eisentraut.org      211         [ -  + ]:CBC     1607696 :     Assert(item_a == NULL);
                                212         [ -  + ]:        1607696 :     Assert(item_b == NULL);
                                213                 :                : 
 7902 tgl@sss.pgh.pa.us         214                 :        1607696 :     return true;
                                215                 :                : }
                                216                 :                : 
                                217                 :                : 
                                218                 :                : /*
                                219                 :                :  * equal
                                220                 :                :  *    returns whether two nodes are equal
                                221                 :                :  */
                                222                 :                : bool
  645 peter@eisentraut.org      223                 :        5959804 : equal(const void *a, const void *b)
                                224                 :                : {
                                225                 :                :     bool        retval;
                                226                 :                : 
                                227         [ +  + ]:        5959804 :     if (a == b)
                                228                 :         159544 :         return true;
                                229                 :                : 
                                230                 :                :     /*
                                231                 :                :      * note that a!=b, so only one of them can be NULL
                                232                 :                :      */
                                233   [ +  +  +  + ]:        5800260 :     if (a == NULL || b == NULL)
                                234                 :          99830 :         return false;
                                235                 :                : 
                                236                 :                :     /*
                                237                 :                :      * are they the same type of nodes?
                                238                 :                :      */
                                239         [ +  + ]:        5700430 :     if (nodeTag(a) != nodeTag(b))
                                240                 :         771422 :         return false;
                                241                 :                : 
                                242                 :                :     /* Guard against stack overflow due to overly complex expressions */
                                243                 :        4929008 :     check_stack_depth();
                                244                 :                : 
                                245   [ +  +  -  -  :        4929008 :     switch (nodeTag(a))
                                     +  +  +  +  +  
                                     +  -  +  +  -  
                                     +  -  +  +  +  
                                     +  +  -  +  -  
                                     +  +  -  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     +  +  -  +  -  
                                     -  -  -  -  +  
                                     +  +  +  -  +  
                                     +  +  -  +  +  
                                     +  -  -  -  -  
                                     -  -  -  -  -  
                                     +  -  -  -  -  
                                     -  -  -  -  +  
                                     -  -  -  -  -  
                                     -  -  -  -  +  
                                     +  +  -  +  +  
                                     -  +  -  -  -  
                                     -  -  -  +  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  +  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     +  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  -  -  -  -  
                                     -  +  +  -  -  
                                     -  +  -  +  -  
                                        -  +  -  +  
                                                 - ]
                                246                 :                :     {
                                247                 :                : #include "equalfuncs.switch.c"
                                248                 :                : 
 9715 bruce@momjian.us          249                 :        2083924 :         case T_List:
                                250                 :                :         case T_IntList:
                                251                 :                :         case T_OidList:
                                252                 :                :         case T_XidList:
 7263 neilc@samurai.com         253                 :        2083924 :             retval = _equalList(a, b);
 9715 bruce@momjian.us          254                 :        2083924 :             break;
                                255                 :                : 
 9715 bruce@momjian.us          256                 :UBC           0 :         default:
 7572 tgl@sss.pgh.pa.us         257         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d",
                                258                 :                :                  (int) nodeTag(a));
                                259                 :                :             retval = false;     /* keep compiler quiet */
                                260                 :                :             break;
                                261                 :                :     }
                                262                 :                : 
 9716 bruce@momjian.us          263                 :CBC     4929008 :     return retval;
                                264                 :                : }
        

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