LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - jsonb_op.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 80.3 % 147 118 3 17 9 3 58 2 55 17 58 2
Current Date: 2023-04-08 17:13:01 Functions: 78.6 % 14 11 3 9 1 1 3 9
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 100.0 % 4 4 2 2 2
Legend: Lines: hit not hit (240..) days: 79.7 % 143 114 3 17 9 3 56 2 53 17 56
Function coverage date bins:
(240..) days: 42.3 % 26 11 3 9 1 1 3 9

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * jsonb_op.c
                                  4                 :  *   Special operators for jsonb only, used by various index access methods
                                  5                 :  *
                                  6                 :  * Copyright (c) 2014-2023, PostgreSQL Global Development Group
                                  7                 :  *
                                  8                 :  *
                                  9                 :  * IDENTIFICATION
                                 10                 :  *    src/backend/utils/adt/jsonb_op.c
                                 11                 :  *
                                 12                 :  *-------------------------------------------------------------------------
                                 13                 :  */
                                 14                 : #include "postgres.h"
                                 15                 : 
                                 16                 : #include "catalog/pg_type.h"
                                 17                 : #include "miscadmin.h"
                                 18                 : #include "utils/builtins.h"
                                 19                 : #include "utils/jsonb.h"
                                 20                 : 
                                 21                 : Datum
 3304 andrew                     22 CBC        6859 : jsonb_exists(PG_FUNCTION_ARGS)
                                 23                 : {
 2029 tgl                        24            6859 :     Jsonb      *jb = PG_GETARG_JSONB_P(0);
 3304 andrew                     25            6859 :     text       *key = PG_GETARG_TEXT_PP(1);
                                 26                 :     JsonbValue  kval;
                                 27            6859 :     JsonbValue *v = NULL;
                                 28                 : 
                                 29                 :     /*
                                 30                 :      * We only match Object keys (which are naturally always Strings), or
                                 31                 :      * string elements in arrays.  In particular, we do not match non-string
                                 32                 :      * scalar elements.  Existence of a key/element is only considered at the
                                 33                 :      * top level.  No recursion occurs.
                                 34                 :      */
                                 35            6859 :     kval.type = jbvString;
 3294 tgl                        36            6859 :     kval.val.string.val = VARDATA_ANY(key);
                                 37            6859 :     kval.val.string.len = VARSIZE_ANY_EXHDR(key);
                                 38                 : 
 3259 heikki.linnakangas         39            6859 :     v = findJsonbValueFromContainer(&jb->root,
                                 40                 :                                     JB_FOBJECT | JB_FARRAY,
                                 41                 :                                     &kval);
                                 42                 : 
 3304 andrew                     43            6859 :     PG_RETURN_BOOL(v != NULL);
                                 44                 : }
                                 45                 : 
                                 46                 : Datum
                                 47            4077 : jsonb_exists_any(PG_FUNCTION_ARGS)
                                 48                 : {
 2029 tgl                        49            4077 :     Jsonb      *jb = PG_GETARG_JSONB_P(0);
 3304 andrew                     50            4077 :     ArrayType  *keys = PG_GETARG_ARRAYTYPE_P(1);
                                 51                 :     int         i;
                                 52                 :     Datum      *key_datums;
                                 53                 :     bool       *key_nulls;
                                 54                 :     int         elem_count;
                                 55                 : 
  282 peter                      56 GNC        4077 :     deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, &elem_count);
 3304 andrew                     57 ECB             : 
 3259 heikki.linnakangas         58 GIC        9003 :     for (i = 0; i < elem_count; i++)
                                 59                 :     {
                                 60                 :         JsonbValue  strVal;
 3259 heikki.linnakangas         61 ECB             : 
 3259 heikki.linnakangas         62 GBC        6966 :         if (key_nulls[i])
 3259 heikki.linnakangas         63 UIC           0 :             continue;
 3259 heikki.linnakangas         64 ECB             : 
 3259 heikki.linnakangas         65 GIC        6966 :         strVal.type = jbvString;
  118 tgl                        66 ECB             :         /* We rely on the array elements not being toasted */
  118 tgl                        67 CBC        6966 :         strVal.val.string.val = VARDATA_ANY(key_datums[i]);
  118 tgl                        68 GIC        6966 :         strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]);
 3259 heikki.linnakangas         69 ECB             : 
 3259 heikki.linnakangas         70 GIC        6966 :         if (findJsonbValueFromContainer(&jb->root,
                                 71                 :                                         JB_FOBJECT | JB_FARRAY,
 3259 heikki.linnakangas         72 ECB             :                                         &strVal) != NULL)
 3304 andrew                     73 GIC        2040 :             PG_RETURN_BOOL(true);
                                 74                 :     }
 3304 andrew                     75 ECB             : 
 3304 andrew                     76 GIC        2037 :     PG_RETURN_BOOL(false);
                                 77                 : }
                                 78                 : 
 3304 andrew                     79 ECB             : Datum
 3304 andrew                     80 GIC        3195 : jsonb_exists_all(PG_FUNCTION_ARGS)
 3304 andrew                     81 ECB             : {
 2029 tgl                        82 CBC        3195 :     Jsonb      *jb = PG_GETARG_JSONB_P(0);
 3304 andrew                     83 GIC        3195 :     ArrayType  *keys = PG_GETARG_ARRAYTYPE_P(1);
                                 84                 :     int         i;
                                 85                 :     Datum      *key_datums;
                                 86                 :     bool       *key_nulls;
                                 87                 :     int         elem_count;
 3304 andrew                     88 ECB             : 
  282 peter                      89 GNC        3195 :     deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, &elem_count);
                                 90                 : 
 3259 heikki.linnakangas         91 GIC        4194 :     for (i = 0; i < elem_count; i++)
                                 92                 :     {
 3102 tgl                        93 ECB             :         JsonbValue  strVal;
 3259 heikki.linnakangas         94 EUB             : 
 3259 heikki.linnakangas         95 GIC        3921 :         if (key_nulls[i])
 3259 heikki.linnakangas         96 LBC           0 :             continue;
                                 97                 : 
 3259 heikki.linnakangas         98 CBC        3921 :         strVal.type = jbvString;
  118 tgl                        99 ECB             :         /* We rely on the array elements not being toasted */
  118 tgl                       100 GIC        3921 :         strVal.val.string.val = VARDATA_ANY(key_datums[i]);
  118 tgl                       101 CBC        3921 :         strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]);
                                102                 : 
 3259 heikki.linnakangas        103 GIC        3921 :         if (findJsonbValueFromContainer(&jb->root,
 3259 heikki.linnakangas        104 ECB             :                                         JB_FOBJECT | JB_FARRAY,
                                105                 :                                         &strVal) == NULL)
 3304 andrew                    106 GIC        2922 :             PG_RETURN_BOOL(false);
 3304 andrew                    107 ECB             :     }
                                108                 : 
 3304 andrew                    109 GIC         273 :     PG_RETURN_BOOL(true);
                                110                 : }
 3304 andrew                    111 ECB             : 
                                112                 : Datum
 3304 andrew                    113 CBC       21636 : jsonb_contains(PG_FUNCTION_ARGS)
 3304 andrew                    114 ECB             : {
 2029 tgl                       115 GIC       21636 :     Jsonb      *val = PG_GETARG_JSONB_P(0);
                                116           21636 :     Jsonb      *tmpl = PG_GETARG_JSONB_P(1);
                                117                 : 
                                118                 :     JsonbIterator *it1,
 3260 bruce                     119 ECB             :                *it2;
 3304 andrew                    120                 : 
 3102 tgl                       121 GIC       21636 :     if (JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl))
 3304 andrew                    122 CBC          15 :         PG_RETURN_BOOL(false);
 3304 andrew                    123 ECB             : 
 3259 heikki.linnakangas        124 GIC       21621 :     it1 = JsonbIteratorInit(&val->root);
 3259 heikki.linnakangas        125 CBC       21621 :     it2 = JsonbIteratorInit(&tmpl->root);
                                126                 : 
 3304 andrew                    127 GIC       21621 :     PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
                                128                 : }
 3304 andrew                    129 ECB             : 
                                130                 : Datum
 3304 andrew                    131 GIC          51 : jsonb_contained(PG_FUNCTION_ARGS)
 3304 andrew                    132 ECB             : {
                                133                 :     /* Commutator of "contains" */
 2029 tgl                       134 GIC          51 :     Jsonb      *tmpl = PG_GETARG_JSONB_P(0);
                                135              51 :     Jsonb      *val = PG_GETARG_JSONB_P(1);
                                136                 : 
                                137                 :     JsonbIterator *it1,
 3260 bruce                     138 ECB             :                *it2;
 3304 andrew                    139 EUB             : 
 3102 tgl                       140 GIC          51 :     if (JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl))
 3304 andrew                    141 LBC           0 :         PG_RETURN_BOOL(false);
 3304 andrew                    142 ECB             : 
 3259 heikki.linnakangas        143 GIC          51 :     it1 = JsonbIteratorInit(&val->root);
 3259 heikki.linnakangas        144 CBC          51 :     it2 = JsonbIteratorInit(&tmpl->root);
                                145                 : 
 3304 andrew                    146 GIC          51 :     PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
                                147                 : }
 3304 andrew                    148 ECB             : 
                                149                 : Datum
 3304 andrew                    150 CBC           6 : jsonb_ne(PG_FUNCTION_ARGS)
 3304 andrew                    151 ECB             : {
 2029 tgl                       152 GIC           6 :     Jsonb      *jba = PG_GETARG_JSONB_P(0);
                                153               6 :     Jsonb      *jbb = PG_GETARG_JSONB_P(1);
 3304 andrew                    154 ECB             :     bool        res;
                                155                 : 
 3259 heikki.linnakangas        156 CBC           6 :     res = (compareJsonbContainers(&jba->root, &jbb->root) != 0);
 3304 andrew                    157 ECB             : 
 3304 andrew                    158 CBC           6 :     PG_FREE_IF_COPY(jba, 0);
 3304 andrew                    159 GIC           6 :     PG_FREE_IF_COPY(jbb, 1);
                                160               6 :     PG_RETURN_BOOL(res);
                                161                 : }
                                162                 : 
                                163                 : /*
                                164                 :  * B-Tree operator class operators, support function
 3304 andrew                    165 EUB             :  */
                                166                 : Datum
 3304 andrew                    167 UBC           0 : jsonb_lt(PG_FUNCTION_ARGS)
 3304 andrew                    168 EUB             : {
 2029 tgl                       169 UIC           0 :     Jsonb      *jba = PG_GETARG_JSONB_P(0);
                                170               0 :     Jsonb      *jbb = PG_GETARG_JSONB_P(1);
 3304 andrew                    171 EUB             :     bool        res;
                                172                 : 
 3259 heikki.linnakangas        173 UBC           0 :     res = (compareJsonbContainers(&jba->root, &jbb->root) < 0);
 3304 andrew                    174 EUB             : 
 3304 andrew                    175 UBC           0 :     PG_FREE_IF_COPY(jba, 0);
 3304 andrew                    176 UIC           0 :     PG_FREE_IF_COPY(jbb, 1);
                                177               0 :     PG_RETURN_BOOL(res);
                                178                 : }
 3304 andrew                    179 ECB             : 
                                180                 : Datum
 3304 andrew                    181 CBC        2694 : jsonb_gt(PG_FUNCTION_ARGS)
 3304 andrew                    182 ECB             : {
 2029 tgl                       183 GIC        2694 :     Jsonb      *jba = PG_GETARG_JSONB_P(0);
                                184            2694 :     Jsonb      *jbb = PG_GETARG_JSONB_P(1);
 3304 andrew                    185 ECB             :     bool        res;
                                186                 : 
 3259 heikki.linnakangas        187 CBC        2694 :     res = (compareJsonbContainers(&jba->root, &jbb->root) > 0);
 3304 andrew                    188 ECB             : 
 3304 andrew                    189 CBC        2694 :     PG_FREE_IF_COPY(jba, 0);
 3304 andrew                    190 GIC        2694 :     PG_FREE_IF_COPY(jbb, 1);
                                191            2694 :     PG_RETURN_BOOL(res);
                                192                 : }
 3304 andrew                    193 EUB             : 
                                194                 : Datum
 3304 andrew                    195 UBC           0 : jsonb_le(PG_FUNCTION_ARGS)
 3304 andrew                    196 EUB             : {
 2029 tgl                       197 UIC           0 :     Jsonb      *jba = PG_GETARG_JSONB_P(0);
                                198               0 :     Jsonb      *jbb = PG_GETARG_JSONB_P(1);
 3304 andrew                    199 EUB             :     bool        res;
                                200                 : 
 3259 heikki.linnakangas        201 UBC           0 :     res = (compareJsonbContainers(&jba->root, &jbb->root) <= 0);
 3304 andrew                    202 EUB             : 
 3304 andrew                    203 UBC           0 :     PG_FREE_IF_COPY(jba, 0);
 3304 andrew                    204 UIC           0 :     PG_FREE_IF_COPY(jbb, 1);
                                205               0 :     PG_RETURN_BOOL(res);
                                206                 : }
 3304 andrew                    207 EUB             : 
                                208                 : Datum
 3304 andrew                    209 UBC           0 : jsonb_ge(PG_FUNCTION_ARGS)
 3304 andrew                    210 EUB             : {
 2029 tgl                       211 UIC           0 :     Jsonb      *jba = PG_GETARG_JSONB_P(0);
                                212               0 :     Jsonb      *jbb = PG_GETARG_JSONB_P(1);
 3304 andrew                    213 EUB             :     bool        res;
                                214                 : 
 3259 heikki.linnakangas        215 UBC           0 :     res = (compareJsonbContainers(&jba->root, &jbb->root) >= 0);
 3304 andrew                    216 EUB             : 
 3304 andrew                    217 UBC           0 :     PG_FREE_IF_COPY(jba, 0);
 3304 andrew                    218 UIC           0 :     PG_FREE_IF_COPY(jbb, 1);
                                219               0 :     PG_RETURN_BOOL(res);
                                220                 : }
 3304 andrew                    221 ECB             : 
                                222                 : Datum
 3304 andrew                    223 CBC       12512 : jsonb_eq(PG_FUNCTION_ARGS)
 3304 andrew                    224 ECB             : {
 2029 tgl                       225 GIC       12512 :     Jsonb      *jba = PG_GETARG_JSONB_P(0);
                                226           12512 :     Jsonb      *jbb = PG_GETARG_JSONB_P(1);
 3304 andrew                    227 ECB             :     bool        res;
                                228                 : 
 3259 heikki.linnakangas        229 CBC       12512 :     res = (compareJsonbContainers(&jba->root, &jbb->root) == 0);
 3304 andrew                    230 ECB             : 
 3304 andrew                    231 CBC       12512 :     PG_FREE_IF_COPY(jba, 0);
 3304 andrew                    232 GIC       12512 :     PG_FREE_IF_COPY(jbb, 1);
                                233           12512 :     PG_RETURN_BOOL(res);
                                234                 : }
 3304 andrew                    235 ECB             : 
                                236                 : Datum
 3304 andrew                    237 CBC      121360 : jsonb_cmp(PG_FUNCTION_ARGS)
 3304 andrew                    238 ECB             : {
 2029 tgl                       239 GIC      121360 :     Jsonb      *jba = PG_GETARG_JSONB_P(0);
                                240          121360 :     Jsonb      *jbb = PG_GETARG_JSONB_P(1);
 3304 andrew                    241 ECB             :     int         res;
                                242                 : 
 3259 heikki.linnakangas        243 CBC      121360 :     res = compareJsonbContainers(&jba->root, &jbb->root);
 3304 andrew                    244 ECB             : 
 3304 andrew                    245 CBC      121360 :     PG_FREE_IF_COPY(jba, 0);
 3304 andrew                    246 GIC      121360 :     PG_FREE_IF_COPY(jbb, 1);
                                247          121360 :     PG_RETURN_INT32(res);
                                248                 : }
                                249                 : 
                                250                 : /*
                                251                 :  * Hash operator class jsonb hashing function
 3304 andrew                    252 ECB             :  */
                                253                 : Datum
 3304 andrew                    254 CBC        6090 : jsonb_hash(PG_FUNCTION_ARGS)
                                255                 : {
 2029 tgl                       256 GIC        6090 :     Jsonb      *jb = PG_GETARG_JSONB_P(0);
                                257                 :     JsonbIterator *it;
 3304 andrew                    258 ECB             :     JsonbValue  v;
                                259                 :     JsonbIteratorToken r;
 3304 andrew                    260 CBC        6090 :     uint32      hash = 0;
 3304 andrew                    261 ECB             : 
 3304 andrew                    262 GIC        6090 :     if (JB_ROOT_COUNT(jb) == 0)
 3304 andrew                    263 CBC         708 :         PG_RETURN_INT32(0);
                                264                 : 
 3259 heikki.linnakangas        265            5382 :     it = JsonbIteratorInit(&jb->root);
                                266                 : 
 3304 andrew                    267           73956 :     while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
                                268                 :     {
 3304 andrew                    269 GIC       68574 :         switch (r)
 3304 andrew                    270 ECB             :         {
 3260 bruce                     271                 :                 /* Rotation is left to JsonbHashScalarValue() */
 3304 andrew                    272 CBC          42 :             case WJB_BEGIN_ARRAY:
                                273              42 :                 hash ^= JB_FARRAY;
                                274              42 :                 break;
                                275            5418 :             case WJB_BEGIN_OBJECT:
                                276            5418 :                 hash ^= JB_FOBJECT;
 3304 andrew                    277 GIC        5418 :                 break;
                                278           57654 :             case WJB_KEY:
 3304 andrew                    279 ECB             :             case WJB_VALUE:
                                280                 :             case WJB_ELEM:
 3304 andrew                    281 CBC       57654 :                 JsonbHashScalarValue(&v, &hash);
 3304 andrew                    282 GIC       57654 :                 break;
 3304 andrew                    283 CBC        5460 :             case WJB_END_ARRAY:
 3304 andrew                    284 EUB             :             case WJB_END_OBJECT:
 3304 andrew                    285 GBC        5460 :                 break;
 3304 andrew                    286 UIC           0 :             default:
 2737 noah                      287               0 :                 elog(ERROR, "invalid JsonbIteratorNext rc: %d", (int) r);
                                288                 :         }
 3304 andrew                    289 ECB             :     }
                                290                 : 
 3304 andrew                    291 GIC        5382 :     PG_FREE_IF_COPY(jb, 0);
                                292            5382 :     PG_RETURN_INT32(hash);
                                293                 : }
 2047 rhaas                     294 ECB             : 
                                295                 : Datum
 2047 rhaas                     296 CBC          18 : jsonb_hash_extended(PG_FUNCTION_ARGS)
 2047 rhaas                     297 ECB             : {
 2029 tgl                       298 GIC          18 :     Jsonb      *jb = PG_GETARG_JSONB_P(0);
 2047 rhaas                     299              18 :     uint64      seed = PG_GETARG_INT64(1);
                                300                 :     JsonbIterator *it;
 2047 rhaas                     301 ECB             :     JsonbValue  v;
                                302                 :     JsonbIteratorToken r;
 2047 rhaas                     303 CBC          18 :     uint64      hash = 0;
 2047 rhaas                     304 EUB             : 
 2047 rhaas                     305 GIC          18 :     if (JB_ROOT_COUNT(jb) == 0)
 2047 rhaas                     306 LBC           0 :         PG_RETURN_UINT64(seed);
                                307                 : 
 2047 rhaas                     308 CBC          18 :     it = JsonbIteratorInit(&jb->root);
                                309                 : 
                                310             222 :     while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
                                311                 :     {
 2047 rhaas                     312 GIC         204 :         switch (r)
 2047 rhaas                     313 ECB             :         {
 2029 tgl                       314                 :                 /* Rotation is left to JsonbHashScalarValueExtended() */
 2047 rhaas                     315 CBC          12 :             case WJB_BEGIN_ARRAY:
                                316              12 :                 hash ^= ((uint64) JB_FARRAY) << 32 | JB_FARRAY;
                                317              12 :                 break;
                                318              36 :             case WJB_BEGIN_OBJECT:
                                319              36 :                 hash ^= ((uint64) JB_FOBJECT) << 32 | JB_FOBJECT;
 2047 rhaas                     320 GIC          36 :                 break;
                                321             108 :             case WJB_KEY:
 2047 rhaas                     322 ECB             :             case WJB_VALUE:
                                323                 :             case WJB_ELEM:
 2047 rhaas                     324 CBC         108 :                 JsonbHashScalarValueExtended(&v, &hash, seed);
 2047 rhaas                     325 GIC         108 :                 break;
 2047 rhaas                     326 CBC          48 :             case WJB_END_ARRAY:
 2047 rhaas                     327 EUB             :             case WJB_END_OBJECT:
 2047 rhaas                     328 GBC          48 :                 break;
 2047 rhaas                     329 UIC           0 :             default:
                                330               0 :                 elog(ERROR, "invalid JsonbIteratorNext rc: %d", (int) r);
                                331                 :         }
 2047 rhaas                     332 ECB             :     }
                                333                 : 
 2047 rhaas                     334 GIC          18 :     PG_FREE_IF_COPY(jb, 0);
                                335              18 :     PG_RETURN_UINT64(hash);
                                336                 : }
        

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