* greater than zero, indicating whether a is less than, equal to, or greater
* than b. Consistent with the requirements for a B-Tree operator class
*
- * Strings are compared lexically. Since this is called from B-Tree support
- * function 1, we're careful about not leaking memory here.
+ * Strings are compared lexically, in contrast with other places where we use a
+ * much simpler comparator logic for searching through Strings. Since this is
+ * called from B-Tree support function 1, we're careful about not leaking
+ * memory here.
*/
int
compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
else
{
res = (v1.type > v2.type) ? 1 : -1; /* Type-defined order */
- break; /* out of while loop */
}
}
else
/* Type-defined order */
res = (v1.type > v2.type) ? 1 : -1;
}
- break; /* out of while loop */
}
}
while (res == 0);
}
/*
- * Find value in object (i.e. the value part of some key/value pair in an
- * object), or find a matching element in an array. Do so on the basis on
- * equality of the values/elements with a specified value "key".
+ * Find value in object (i.e. the "value" part of some key/value pair in an
+ * object), or find a matching element if we're looking through an array. Do
+ * so on the basis of equality of the object keys only, or alternatively
+ * element values only, with a caller-supplied value "key". "flags" argument
+ * allows caller to specify which container types are of interest.
+ *
+ * This exported utility function exists to facilitate various cases concerned
+ * with "containment". If asked to look through an object, the caller had
+ * better pass a Jsonb String, because their keys can only be strings.
+ * Otherwise, for an array, any type of JsonbValue will do.
*
* In order to proceed with the search, it is necessary for callers to have
- * both specified an interest in a particular container type with an
+ * both specified an interest in exactly one particular container type with an
* appropriate flag, as well as having the pointed-to Jsonb superheader be of
- * that same container type at the top level. If both of those conditions
- * don't hold, immediately fall through and return NULL. Otherwise, return
- * palloc()'d copy of value. "flags" allows caller to specify which container
- * types are of interest.
+ * one of those same container types at the top level. (Actually, we just do
+ * whichever makes sense to save callers the trouble of figuring it out - at
+ * most one can make sense, because the super header either points to an array
+ * (possible a "raw scalar" pseudo array) or an object.)
+ *
+ * Note that we can return a jbvBinary JsonbValue if this is called on an
+ * object, but we never do so on an array. That's because we bunch together
+ * keys and values in objects, whereas for the purposes of containment we just
+ * look at array elements when looking at arrays. Arrays may contain
+ * heterogeneous values, whereas objects must contain only pairs. That's a
+ * very fine distinction as regards their layout, but it is quite salient to
+ * the user-visible definition of containment.
+ *
+ * If the caller asks to look through a container type that is not of the type
+ * pointer to by the superheader, immediately fall through and return NULL. If
+ * we cannot find the value, return NULL. Otherwise, return palloc()'d copy of
+ * value.
*/
JsonbValue *
findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags,
{
uint32 superheader = *(uint32 *) sheader;
JEntry *array = (JEntry *) (sheader + sizeof(uint32));
- JsonbValue *r = palloc(sizeof(JsonbValue));
int count = (superheader & JB_CMASK);
+ JsonbValue *r = palloc(sizeof(JsonbValue));
Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
}
else if (flags & JB_FOBJECT & superheader)
{
- /* Since this is an object, account for double Jentrys */
+ /* Since this is an object, account for *Pairs* of Jentrys */
char *data = (char *) (array + (superheader & JB_CMASK) * 2);
uint32 stopLow = lowbound ? *lowbound : 0,
stopMiddle;
* Binary search for matching jsonb value using "inner comparator"
* logic (i.e. not doing lexical comparisons).
*
- * Searching by object pair key.
+ * Searching through object's pair "keys" *only*.
*/
while (stopLow < count)
{
if (difference == 0)
{
+ /* Found our value (from key/value pair) */
JEntry *v = entry + 1;
if (lowbound)
}
else
{
+ /*
+ * See header comments to understand why this function
+ * never does this for arrays
+ */
r->type = jbvBinary;
r->binary.data = data + INTALIGN(JBE_OFF(*v));
r->binary.len = JBE_LEN(*v) -
*lowbound = stopLow;
}
+ /* Not found */
return NULL;
}