res = (v1.object.nPairs > v2.object.nPairs) ? 1 : -1;
break;
case jbvBinary:
- /*
- * Do nothing. We can rely on next iterator to have
- * details of underlying type.
- */
- break;
+ elog(ERROR, "unexpected jbvBinary value");
}
}
else
{
- res = (v1.type > v2.type) ? 1 : -1; /* Type-defined order */
+ /* Type-defined order */
+ res = (v1.type > v2.type) ? 1 : -1;
}
}
else
{
- if (v1.type == v2.type)
- {
- /*
- * 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)
- {
- Assert(v1.array.nElems != v2.array.nElems);
- res = (v1.array.nElems > v2.array.nElems) ? 1 : -1;
- }
- else if (v1.type == jbvObject)
- {
- Assert(v1.object.nPairs != v2.object.nPairs);
- res = (v1.object.nPairs > v2.object.nPairs) ? 1 : -1;
- }
- else
- {
- elog(ERROR, "unexpected non-container: %d", v1.type);
- }
- }
- else
- {
- /* Type-defined order */
- res = (v1.type > v2.type) ? 1 : -1;
- }
+ /*
+ * It's safe to assume that the types differed.
+ *
+ * If the two values were the same container type, then there'd
+ * have been a chance to observe the variation in the number of
+ * elements/pairs (when processing WJB_BEGIN_OBJECT, say). They
+ * can't be scalar types either, because then they'd have to be
+ * contained in containers already ruled unequal due to differing
+ * numbers of pairs/elements, or already directly ruled unequal
+ * with a call to the underlying type's comparator.
+ */
+ Assert(v1.type != v2.type);
+ Assert(v1.type == jbvArray || v1.type == jbvObject);
+ Assert(v2.type == jbvArray || v2.type == jbvObject);
+ /* Type-defined order */
+ res = (v1.type > v2.type) ? 1 : -1;
}
}
while (res == 0);
/*
* Push JsonbValue into ToJsonbState.
*
- * With r = WJB_END_OBJECT and v = NULL, this function sorts and unique-ifys
- * the passed object's key values. Otherwise, they are assumed to already be
- * sorted and unique.
+ * Initial state of *ToJsonbState is NULL, since it'll be allocated here
+ * originally (caller will get ToJsonbState back by reference).
*
- * Initial state of *ToJsonbState is NULL.
+ * Only sequential tokens pertaining to non-container types should pass a
+ * JsonbValue. There is one exception -- WJB_BEGIN_ARRAY callers may pass a
+ * "raw scalar" pseudo array to append that.
*/
JsonbValue *
-pushJsonbValue(ToJsonbState ** state, int r, JsonbValue * v)
+pushJsonbValue(ToJsonbState ** state, int seq, JsonbValue * v)
{
JsonbValue *result = NULL;
- switch (r)
+ switch (seq)
{
case WJB_BEGIN_ARRAY:
*state = pushState(state);
Assert((v->type >= jbvNull && v->type < jbvArray) || v->type == jbvBinary);
appendElement(*state, v);
break;
- case WJB_END_ARRAY:
case WJB_END_OBJECT:
+ uniqueifyJsonbObject(&(*state)->v);
+ case WJB_END_ARRAY:
+ /* Steps here common to WJB_END_OBJECT case */
result = &(*state)->v;
- /*
- * When v != NULL and control reaches here for an object, keys
- * should already be unique and sorted.
- */
- if (v == NULL && r == WJB_END_OBJECT)
- uniqueifyJsonbObject(result);
/*
- * Pop stack and push current array/"object" as value in parent
- * array/"object"
+ * Pop stack and push current array/object as value in parent
+ * array/object
*/
*state = (*state)->next;
if (*state)