if (!JB_ISEMPTY(jb))
v = findJsonbValueFromSuperHeaderLen(VARDATA(jb),
- JB_FLAG_OBJECT | JB_FLAG_ARRAY,
+ JB_FOBJECT | JB_FARRAY,
NULL,
VARDATA_ANY(key),
VARSIZE_ANY_EXHDR(key));
for (i = 0; i < v->array.nElems; i++)
{
if (findJsonbValueFromSuperHeader(VARDATA(jb),
- JB_FLAG_OBJECT | JB_FLAG_ARRAY,
+ JB_FOBJECT | JB_FARRAY,
plowbound,
v->array.elems + i) != NULL)
PG_RETURN_BOOL(true);
for (i = 0; i < v->array.nElems; i++)
{
if (findJsonbValueFromSuperHeader(VARDATA(jb),
- JB_FLAG_OBJECT | JB_FLAG_ARRAY,
+ JB_FOBJECT | JB_FARRAY,
plowbound,
v->array.elems + i) == NULL)
PG_RETURN_BOOL(false);
Assert(r2 == WJB_KEY);
v = findJsonbValueFromSuperHeader((*it1)->buffer,
- JB_FLAG_OBJECT,
+ JB_FOBJECT,
&lowbound,
&v2);
if (v2.type >= jbvNull && v2.type < jbvArray)
{
v = findJsonbValueFromSuperHeader((*it1)->buffer,
- JB_FLAG_ARRAY,
+ JB_FARRAY,
NULL,
&v2);
if (v == NULL)
JEntry *array = (JEntry *) (sheader + sizeof(uint32));
JsonbValue *r = palloc(sizeof(JsonbValue));
- Assert((superheader & (JB_FLAG_ARRAY | JB_FLAG_OBJECT)) !=
- (JB_FLAG_ARRAY | JB_FLAG_OBJECT));
+ Assert((superheader & (JB_FARRAY | JB_FOBJECT)) !=
+ (JB_FARRAY | JB_FOBJECT));
- if (flags & JB_FLAG_ARRAY & superheader)
+ if (flags & JB_FARRAY & superheader)
{
- char *data = (char *) (array + (superheader & JB_COUNT_MASK));
+ char *data = (char *) (array + (superheader & JB_CMASK));
int i;
- for (i = (lowbound) ? *lowbound : 0; i < (superheader & JB_COUNT_MASK); i++)
+ for (i = (lowbound) ? *lowbound : 0; i < (superheader & JB_CMASK); i++)
{
JEntry *e = array + i;
}
}
}
- else if (flags & JB_FLAG_OBJECT & superheader)
+ else if (flags & JB_FOBJECT & superheader)
{
- char *data = (char *) (array + (superheader & JB_COUNT_MASK) * 2);
+ char *data = (char *) (array + (superheader & JB_CMASK) * 2);
uint32 stopLow = lowbound ? *lowbound : 0,
- stopHigh = (superheader & JB_COUNT_MASK),
+ stopHigh = (superheader & JB_CMASK),
stopMiddle;
/* Object keys must be strings */
r = palloc(sizeof(JsonbValue));
- Assert((superheader & (JB_FLAG_ARRAY | JB_FLAG_OBJECT)) !=
- (JB_FLAG_ARRAY | JB_FLAG_OBJECT));
+ Assert((superheader & (JB_FARRAY | JB_FOBJECT)) !=
+ (JB_FARRAY | JB_FOBJECT));
Assert(i >= 0);
- if (i >= (superheader & JB_COUNT_MASK))
+ if (i >= (superheader & JB_CMASK))
return NULL;
array = (JEntry *) (sheader + sizeof(uint32));
- if (flags & JB_FLAG_ARRAY & superheader)
+ if (flags & JB_FARRAY & superheader)
{
e = array + i;
- data = (char *) (array + (superheader & JB_COUNT_MASK));
+ data = (char *) (array + (superheader & JB_CMASK));
}
- else if (flags & JB_FLAG_OBJECT & superheader)
+ else if (flags & JB_FOBJECT & superheader)
{
e = array + i * 2 + 1;
- data = (char *) (array + (superheader & JB_COUNT_MASK) * 2);
+ data = (char *) (array + (superheader & JB_CMASK) * 2);
}
else
{
state = (*it)->state;
- if ((*it)->containerType == JB_FLAG_ARRAY)
+ if ((*it)->containerType == JB_FARRAY)
{
if (state == jbi_start)
{
}
}
}
- else if ((*it)->containerType == JB_FLAG_OBJECT)
+ else if ((*it)->containerType == JB_FOBJECT)
{
if (state == jbi_start)
{
if (value->type == jbvArray)
{
- *state->curlptr->header = value->array.nElems | JB_FLAG_ARRAY;
+ *state->curlptr->header = value->array.nElems | JB_FARRAY;
state->ptr += sizeof(JEntry) * value->array.nElems;
if (value->array.scalar)
{
Assert(value->array.nElems == 1);
Assert(level == 0);
- *state->curlptr->header |= JB_FLAG_SCALAR;
+ *state->curlptr->header |= JB_FSCALAR;
}
}
else
{
- *state->curlptr->header = value->object.nPairs | JB_FLAG_OBJECT;
+ *state->curlptr->header = value->object.nPairs | JB_FOBJECT;
state->ptr += sizeof(JEntry) * value->object.nPairs * 2;
}
}
state->prvlptr = state->curlptr - 1;
- if (*state->prvlptr->header & JB_FLAG_ARRAY)
+ if (*state->prvlptr->header & JB_FARRAY)
{
i = state->prvlptr->i;
state->prvlptr->meta[i].header |=
(state->prvlptr->meta[i - 1].header & JENTRY_POSMASK) + len;
}
- else if (*state->prvlptr->header & JB_FLAG_OBJECT)
+ else if (*state->prvlptr->header & JB_FOBJECT)
{
i = 2 * state->prvlptr->i + 1; /* Value, not key */
{
uint32 superheader = *(uint32 *) sheader;
- it->containerType = superheader & (JB_FLAG_ARRAY | JB_FLAG_OBJECT);
- it->nElems = superheader & JB_COUNT_MASK;
+ it->containerType = superheader & (JB_FARRAY | JB_FOBJECT);
+ it->nElems = superheader & JB_CMASK;
it->buffer = sheader;
/* Array starts just after header */
switch (it->containerType)
{
- case JB_FLAG_ARRAY:
+ case JB_FARRAY:
it->dataProper =
(char *) it->meta + it->nElems * sizeof(JEntry);
- it->isScalar = (superheader & JB_FLAG_SCALAR) != 0;
+ it->isScalar = (superheader & JB_FSCALAR) != 0;
/* This is either a "raw scalar", or an array */
Assert(!it->isScalar || it->nElems == 1);
break;
- case JB_FLAG_OBJECT:
+ case JB_FOBJECT:
/*
* Offset reflects that nElems indicates JsonbPairs in an object
*
if (have_object)
{
jbvp = findJsonbValueFromSuperHeaderLen((JsonbSuperHeader) jbvp,
- JB_FLAG_OBJECT, NULL,
+ JB_FOBJECT, NULL,
VARDATA_ANY(pathtext[i]),
VARSIZE_ANY_EXHDR(pathtext[i]));
}
PG_RETURN_NULL();
index = (uint32) lindex;
jbvp = getIthJsonbValueFromSuperHeader((JsonbSuperHeader) jbvp,
- JB_FLAG_ARRAY, index);
+ JB_FARRAY, index);
}
else
{
char *key = NameStr(tupdesc->attrs[i]->attname);
v = findJsonbValueFromSuperHeaderLen(VARDATA(jb),
- JB_FLAG_OBJECT, NULL, key,
+ JB_FOBJECT, NULL, key,
strlen(key));
}
}
char *key = NameStr(tupdesc->attrs[i]->attname);
v = findJsonbValueFromSuperHeaderLen(VARDATA(element),
- JB_FLAG_OBJECT, NULL, key,
+ JB_FOBJECT, NULL, key,
strlen(key));
}
/*
* it's not possible to get more than 2^28 items into an jsonb.
+ *
+ * JB_CMASK is count mask
*/
-#define JB_COUNT_MASK 0x0FFFFFFF
+#define JB_CMASK 0x0FFFFFFF
-#define JB_FLAG_SCALAR 0x10000000
-#define JB_FLAG_OBJECT 0x20000000
-#define JB_FLAG_ARRAY 0x40000000
+#define JB_FSCALAR 0x10000000
+#define JB_FOBJECT 0x20000000
+#define JB_FARRAY 0x40000000
/* Get information on varlena Jsonb */
-#define JB_ISEMPTY(jbp_) (VARSIZE(jbp_) <= VARHDRSZ)
+#define JB_ISEMPTY(jbp_) (VARSIZE(jbp_) == 0)
#define JB_ROOT_COUNT(jbp_) (JB_ISEMPTY(jbp_) \
- ? 0 : ( *(uint32*)VARDATA(jbp_) & JB_COUNT_MASK))
+ ? 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_FLAG_OBJECT))
+ ? 0: ( *(uint32*) VARDATA(jbp_) & JB_FOBJECT))
#define JB_ROOT_IS_ARRAY(jbp_) (JB_ISEMPTY(jbp_) \
- ? 0 : ( *(uint32*)VARDATA(jbp_) & JB_FLAG_ARRAY))
-#define JB_ROOT_IS_SCALAR(jbp_) (JB_ISEMPTY(jbp_) \
- ? 0 : ( *(uint32*)VARDATA(jbp_) & JB_FLAG_SCALAR))
+ ? 0: ( *(uint32*) VARDATA(jbp_) & JB_FARRAY))
/* Flags indicating a stage of sequential Jsonb processing */
#define WJB_KEY 0x001
typedef struct JsonbValue JsonbValue;
typedef char* JsonbSuperHeader;
+
/*
+ * Jsonbs are varlena objects, so must meet the varlena convention that the
+ * first int32 of the object contains the total object size in bytes. Be sure
+ * to use VARSIZE() and SET_VARSIZE() to access it, though!
+ *
* We have an abstraction called a "superheader". This is a pointer that
* conventionally points to the first item after our 4-byte uncompressed
* varlena header, from which we can read uint32 values through bitwise
* consistent to the extent that it matters between the least nested level
* (Jsonb), and deeper nested levels (Jentry).
*/
+
typedef struct
{
int32 vl_len_; /* varlena header (do not touch directly!) */
- /* (uint32/Jsonb superheader of top-level Jsonb object/array follows) */
+ uint32 superheader;
/* (array of JEntry follows, size determined using uint32 superheader) */
} Jsonb;