Variability
authorPeter Geoghegan <[email protected]>
Tue, 18 Mar 2014 08:20:13 +0000 (01:20 -0700)
committerPeter Geoghegan <[email protected]>
Tue, 18 Mar 2014 08:20:13 +0000 (01:20 -0700)
src/backend/utils/adt/jsonb_util.c

index ce192377f83ad6cecd4b44ff1f1db1c920834a20..cb32eecb5091fc8fa1eaa55747efc96972dbbb6c 100644 (file)
@@ -52,6 +52,7 @@ typedef struct convertState
 static int compareJsonbScalarValue(JsonbValue * a, JsonbValue * b);
 static int lexicalCompareJsonbStringValue(const void *a, const void *b);
 static Size convertJsonb(JsonbValue * v, Jsonb* buffer);
+static inline short addPaddingInt(convertState * state);
 static void walkJsonbValueConversion(JsonbValue * value, convertState * state,
                                     uint32 nestlevel);
 static void putJsonbValueConversion(convertState * state, JsonbValue * value,
@@ -1093,7 +1094,7 @@ static Size
 convertJsonb(JsonbValue * v, Jsonb *buffer)
 {
    convertState    state;
-   Size            len = 0;
+   Size            len;
 
    /* Should not already have binary representation */
    Assert(v->type != jbvBinary);
@@ -1170,6 +1171,26 @@ walkJsonbValueConversion(JsonbValue * value, convertState * state,
    }
 }
 
+/*
+ * Add padding sufficient to int-align our access to conversion buffer
+ */
+static inline
+short addPaddingInt(convertState * state)
+{
+   short       padlen, p;
+
+   padlen = INTALIGN(state->ptr - VARDATA(state->buffer)) -
+       (state->ptr - VARDATA(state->buffer));
+
+   for (p = padlen; p > 0; p--)
+   {
+       *state->ptr = '\0';
+       state->ptr++;
+   }
+
+   return padlen;
+}
+
 /*
  * As part of the process of converting an arbitrary JsonbValue to a Jsonb,
  * copy an arbitrary individual JsonbValue.  This function may copy over any
@@ -1196,24 +1217,12 @@ putJsonbValueConversion(convertState * state, JsonbValue * value, uint32 flags,
 
    if (flags & (WJB_BEGIN_ARRAY | WJB_BEGIN_OBJECT))
    {
-       short       padlen, p;
-
        Assert(((flags & WJB_BEGIN_ARRAY) && value->type == jbvArray) ||
               ((flags & WJB_BEGIN_OBJECT) && value->type == jbvObject));
 
        state->curlptr->begin = state->ptr;
 
-       padlen = INTALIGN(state->ptr - VARDATA(state->buffer)) -
-           (state->ptr - VARDATA(state->buffer));
-
-       /*
-        * Add padding as necessary
-        */
-       for (p = padlen; p > 0; p--)
-       {
-           *state->ptr = '\0';
-           state->ptr++;
-       }
+       addPaddingInt(state);
 
        state->curlptr->header = (uint32 *) state->ptr;
        /* Advance past header */
@@ -1319,7 +1328,8 @@ static void
 putStringConversion(convertState * state, JsonbValue * value,
                    uint32 level, uint32 i)
 {
-   short       p, padlen;
+   int         numlen;
+   short       padlen;
 
    state->curlptr = state->levelstate + level;
 
@@ -1352,38 +1362,29 @@ putStringConversion(convertState * state, JsonbValue * value,
            state->curlptr->meta[i].header |= (value->boolean) ?
                JENTRY_ISTRUE : JENTRY_ISFALSE;
 
+           /*
+            * Store a delta from start of meta array until end (add last
+            * item's offset to length of item to get our offset)
+            */
            if (i > 0)
                state->curlptr->meta[i].header |=
                    state->curlptr->meta[i - 1].header & JENTRY_POSMASK;
            break;
        case jbvNumeric:
-           {
-               int numlen = VARSIZE_ANY(value->numeric);
-
-               padlen = INTALIGN(state->ptr - VARDATA(state->buffer)) -
-                   (state->ptr - VARDATA(state->buffer));
-
-               /*
-                * Add padding as necessary
-                */
-               for (p = padlen; p > 0; p--)
-               {
-                   *state->ptr = '\0';
-                   state->ptr++;
-               }
+           numlen = VARSIZE_ANY(value->numeric);
+           padlen = addPaddingInt(state);
 
-               memcpy(state->ptr, value->numeric, numlen);
-               state->ptr += numlen;
+           memcpy(state->ptr, value->numeric, numlen);
+           state->ptr += numlen;
 
-               state->curlptr->meta[i].header |= JENTRY_ISNUMERIC;
-               if (i == 0)
-                   state->curlptr->meta[i].header |= padlen + numlen;
-               else
-                   state->curlptr->meta[i].header |=
-                       (state->curlptr->meta[i - 1].header & JENTRY_POSMASK) +
-                       padlen + numlen;
-               break;
-           }
+           state->curlptr->meta[i].header |= JENTRY_ISNUMERIC;
+           if (i == 0)
+               state->curlptr->meta[i].header |= padlen + numlen;
+           else
+               state->curlptr->meta[i].header |=
+                   (state->curlptr->meta[i - 1].header & JENTRY_POSMASK)
+                   + padlen + numlen;
+           break;
        default:
            elog(ERROR, "invalid jsonb scalar type");
    }
@@ -1645,8 +1646,7 @@ lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
 }
 
 /*
- * Sort and unique-ify pairs in JsonbValue (associative "object" data
- * structure)
+ * Sort and unique-ify pairs in JsonbValue object
  */
 static void
 uniqueifyJsonbObject(JsonbValue * v)