Remove JB_ISEMPTY(). Better "raw scalar" handling.
authorPeter Geoghegan <[email protected]>
Tue, 18 Mar 2014 00:33:23 +0000 (17:33 -0700)
committerPeter Geoghegan <[email protected]>
Tue, 18 Mar 2014 00:33:23 +0000 (17:33 -0700)
JB_ISEMPTY() defensive checks seem quite unnecessary, except in exactly
one place where an equivalent check now performed instead.

Have "raw scalar" handling occur within worker function called by bt
support function 1.  This seems like a way better level to handle the
issue at, not least since it's an implementation detail already referred
to at numerous other points within jsonb_util.c (and not jsonb_op.c).

src/backend/utils/adt/jsonb.c
src/backend/utils/adt/jsonb_op.c
src/backend/utils/adt/jsonb_util.c
src/backend/utils/adt/jsonfuncs.c
src/include/utils/jsonb.h

index b818b2f8ae7dabb25a959bccd0fa5296a4eef6da..d6827ce5506384665de29d0725bda77335ccb8b1 100644 (file)
@@ -78,7 +78,7 @@ jsonb_out(PG_FUNCTION_ARGS)
    Jsonb      *jb = PG_GETARG_JSONB(0);
    char       *out;
 
-   out = JsonbToCString(NULL, (JB_ISEMPTY(jb)) ? NULL : VARDATA(jb), VARSIZE(jb));
+   out = JsonbToCString(NULL, VARDATA(jb), VARSIZE(jb));
 
    PG_RETURN_CSTRING(out);
 }
@@ -96,8 +96,7 @@ jsonb_send(PG_FUNCTION_ARGS)
    StringInfo  jtext = makeStringInfo();
    int         version = 1;
 
-   (void) JsonbToCString(jtext, (JB_ISEMPTY(jb)) ? NULL : VARDATA(jb),
-                         VARSIZE(jb));
+   (void) JsonbToCString(jtext, VARDATA(jb), VARSIZE(jb));
 
    pq_begintypsend(&buf);
    pq_sendint(&buf, version, 1);
index 1eca7ad1b7c3510fbeb9db74f45f3e07858d99f6..99d2690e520b8ee155cd74123d944c90551ec31b 100644 (file)
@@ -29,11 +29,10 @@ jsonb_exists(PG_FUNCTION_ARGS)
    kval.string.val = VARDATA_ANY(key);
    kval.string.len = VARSIZE_ANY_EXHDR(key);
 
-   if (!JB_ISEMPTY(jb))
-       v = findJsonbValueFromSuperHeader(VARDATA(jb),
-                                         JB_FOBJECT | JB_FARRAY,
-                                         NULL,
-                                         &kval);
+   v = findJsonbValueFromSuperHeader(VARDATA(jb),
+                                     JB_FOBJECT | JB_FARRAY,
+                                     NULL,
+                                     &kval);
 
    PG_RETURN_BOOL(v != NULL);
 }
@@ -48,7 +47,7 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
    uint32     *plowbound = NULL,
                lowbound = 0;
 
-   if (JB_ISEMPTY(jb) || v == NULL || v->object.nPairs == 0)
+   if (v == NULL || v->object.nPairs == 0)
        PG_RETURN_BOOL(false);
 
    if (JB_ROOT_IS_OBJECT(jb))
@@ -204,32 +203,7 @@ jsonb_cmp(PG_FUNCTION_ARGS)
 
    int         res;
 
-   if (JB_ISEMPTY(jb1) || JB_ISEMPTY(jb2))
-   {
-       if (JB_ISEMPTY(jb1))
-       {
-           if (JB_ISEMPTY(jb2))
-               res = 0;
-           else
-               res = -1;
-       }
-       else
-       {
-           res = 1;
-       }
-   }
-   else if (JB_ROOT_IS_SCALAR(jb1) && !JB_ROOT_IS_SCALAR(jb2))
-   {
-       res = -1;
-   }
-   else if (JB_ROOT_IS_SCALAR(jb2) && !JB_ROOT_IS_SCALAR(jb1))
-   {
-       res = 1;
-   }
-   else
-   {
-       res = compareJsonbSuperHeaderValue(VARDATA(jb1), VARDATA(jb2));
-   }
+   res = compareJsonbSuperHeaderValue(VARDATA(jb1), VARDATA(jb2));
 
    /*
     * This is a btree support function; this is one of the few places where
index 52bd744305f4e5a1ce462b945009b89a40da929e..71174f54e66a0124ddb2b8f3392be2cdb139ecf2 100644 (file)
@@ -186,6 +186,14 @@ compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
                            res = (v1.boolean > v2.boolean) ? 1 : -1;
                        break;
                    case jbvArray:
+                       /*
+                        * This could be a "raw scalar" pseudo array.  That's a
+                        * special case here though, since we still want the
+                        * general type-based comparisons to apply, and as far
+                        * as we're concerned a pseudo array is just a scalar.
+                        */
+                       if (v1.array.scalar != v2.array.scalar)
+                           res = (v1.array.scalar) ? -1 : 1;
                        if (v1.array.nElems != v2.array.nElems)
                            res = (v1.array.nElems > v2.array.nElems) ? 1 : -1;
                        break;
@@ -210,12 +218,14 @@ compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
        {
            if (v1.type == v2.type)
            {
-               Assert(r1 != WJB_DONE && r2 != WJB_DONE);
-
                /*
                 * Types were the same, and yet since iterator return codes
                 * differed, one must have finished before the other (and thus
                 * there must be a variation in the number of pairs/elements).
+                *
+                * This code is just defensive, since control won't reach here
+                * in practice as it'll already be apparent that an underlying
+                * container type has a different number of elements.
                 */
                if (v1.type == jbvArray)
                {
index 479912791a28a363c81ebb654f0a3536dab20e73..c45230877b3fb4ec28d34923ae820553a10f7321 100644 (file)
@@ -763,7 +763,7 @@ get_path_all(FunctionCallInfo fcinfo, bool as_text)
    {
        Jsonb      *jb = PG_GETARG_JSONB(0);
 
-       json = cstring_to_text(JsonbToCString(NULL, (JB_ISEMPTY(jb)) ? NULL : VARDATA(jb), VARSIZE(jb)));
+       json = cstring_to_text(JsonbToCString(NULL, VARDATA(jb), VARSIZE(jb)));
    }
 
    if (array_contains_nulls(path))
@@ -1255,8 +1255,7 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
    if (as_text)
    {
        PG_RETURN_TEXT_P(cstring_to_text(JsonbToCString(NULL,
-                                                       (JB_ISEMPTY(res))?
-                                                       NULL : VARDATA(res),
+                                                       VARDATA(res),
                                                        VARSIZE(res))));
    }
    else
@@ -2145,7 +2144,7 @@ populate_record_worker(FunctionCallInfo fcinfo, bool have_record_arg)
        jb = PG_GETARG_JSONB(have_record_arg ? 1 : 0);
 
        /* same logic as for json */
-       if (JB_ISEMPTY(jb) && rec)
+       if (!have_record_arg && rec)
            PG_RETURN_POINTER(rec);
    }
 
@@ -2229,7 +2228,6 @@ populate_record_worker(FunctionCallInfo fcinfo, bool have_record_arg)
        }
        else
        {
-           if (!JB_ISEMPTY(jb))
            {
                char       *key = NameStr(tupdesc->attrs[i]->attname);
 
@@ -2524,7 +2522,6 @@ make_row_from_rec_and_jsonb(Jsonb * element, PopulateRecordsetState *state)
            continue;
        }
 
-       if (!JB_ISEMPTY(element))
        {
            char       *key = NameStr(tupdesc->attrs[i]->attname);
 
index f02657cbb43ddc0ff3c2f87cc6513b7e50031efc..099852eaa1a9d3987f6c9b0b196036ff1f197aab 100644 (file)
 #define JB_FARRAY              0x40000000
 
 /* Get information on varlena Jsonb */
-#define JB_ISEMPTY(jbp_)       (VARSIZE(jbp_) == 0)
-#define JB_ROOT_COUNT(jbp_)        (JB_ISEMPTY(jbp_) ? \
-                                0: ( *(uint32*) VARDATA(jbp_) & JB_CMASK))
-#define JB_ROOT_IS_SCALAR(jbp_) (JB_ISEMPTY(jbp_) ? \
-                                0: ( *(uint32*) VARDATA(jbp_) & JB_FSCALAR))
-#define JB_ROOT_IS_OBJECT(jbp_) (JB_ISEMPTY(jbp_) ? \
-                                0: ( *(uint32*) VARDATA(jbp_) & JB_FOBJECT))
-#define JB_ROOT_IS_ARRAY(jbp_) (JB_ISEMPTY(jbp_) ? \
-                                0: ( *(uint32*) VARDATA(jbp_) & JB_FARRAY))
+#define JB_ROOT_COUNT(jbp_)        ( *(uint32*) VARDATA(jbp_) & JB_CMASK)
+#define JB_ROOT_IS_SCALAR(jbp_)    ( *(uint32*) VARDATA(jbp_) & JB_FSCALAR)
+#define JB_ROOT_IS_OBJECT(jbp_)    ( *(uint32*) VARDATA(jbp_) & JB_FOBJECT)
+#define JB_ROOT_IS_ARRAY(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FARRAY)
 
 /* Jentry macros */
 #define JENTRY_POSMASK         0x0FFFFFFF