JsonbIteratorGet() name and position altered.
Consistently use the term "scalar" in preference to the RFC term
"primitive" internally.
<para>
The following are all valid <type>jsonb</> expressions:
<programlisting>
--- Simple scalar value (explicitly required by RFC-7159)
+-- Simple scalar/primitive value (explicitly required by RFC-7159)
SELECT '5'::jsonb;
-- Array of heterogeneous, primitive-typed elements
</programlisting>
</para>
<para>
- Note the distinction between scalar values (primitive types) as
- elements, keys and values.
+ Note the distinction between scalar/primitive values as elements,
+ keys and values.
</para>
</sect2>
<sect2 id="json-indexing">
* A root scalar is stored as an array of one element, so we get the
* array and then its first (and only) member.
*/
- (void) JsonbIteratorGet(&it, &v, true);
- (void) JsonbIteratorGet(&it, &v, true);
+ (void) JsonbIteratorNext(&it, &v, true);
+ (void) JsonbIteratorNext(&it, &v, true);
switch (v.type)
{
case jbvNull:
it = JsonbIteratorInit(in);
- while (redo_switch || ((type = JsonbIteratorGet(&it, &v, false)) != 0))
+ while (redo_switch || ((type = JsonbIteratorNext(&it, &v, false)) != 0))
{
redo_switch = false;
switch (type)
jsonb_put_escaped_value(out, &v);
appendBinaryStringInfo(out, ": ", 2);
- type = JsonbIteratorGet(&it, &v, false);
+ type = JsonbIteratorNext(&it, &v, false);
if (type == WJB_VALUE)
{
first = false;
} PathHashStack;
static text *make_text_key(const char *str, int len, char flag);
-static text *make_primitive_text_key(const JsonbValue * v, char flag);
-static void hash_primitive_value(const JsonbValue * v, PathHashStack * stack);
+static text *make_scalar_text_key(const JsonbValue * v, char flag);
+static void hash_scalar_value(const JsonbValue * v, PathHashStack * stack);
/*
*
it = JsonbIteratorInit(VARDATA(jb));
- while ((r = JsonbIteratorGet(&it, &v, false)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, false)) != 0)
{
if (i >= total)
{
* benefit of JsonbContainsStrategyNumber.
*/
case WJB_ELEM:
- entries[i++] = PointerGetDatum(make_primitive_text_key(&v, KEYELEMFLAG));
+ entries[i++] = PointerGetDatum(make_scalar_text_key(&v, KEYELEMFLAG));
break;
case WJB_VALUE:
- entries[i++] = PointerGetDatum(make_primitive_text_key(&v, VALFLAG));
+ entries[i++] = PointerGetDatum(make_scalar_text_key(&v, VALFLAG));
break;
default:
break;
* path. For faster calculation of hashes, use a stack of precalculated
* hashes of prefixes.
*/
- while ((r = JsonbIteratorGet(&it, &v, false)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, false)) != 0)
{
pg_crc32 path_crc32;
PathHashStack *tmp;
case WJB_KEY:
/* Calc hash of key and separated into preserved stack item */
stack->hash_state = stack->next->hash_state;
- hash_primitive_value(&v, stack);
+ hash_scalar_value(&v, stack);
COMP_CRC32(stack->hash_state, PATH_SEPARATOR, 1);
break;
case WJB_VALUE:
case WJB_ELEM:
stack->hash_state = stack->next->hash_state;
COMP_CRC32(stack->hash_state, PATH_SEPARATOR, 1);
- hash_primitive_value(&v, stack);
+ hash_scalar_value(&v, stack);
path_crc32 = stack->hash_state;
FIN_CRC32(path_crc32);
entries[i++] = path_crc32;
* Create a textual representation of a jsonbValue for GIN storage.
*/
static text *
-make_primitive_text_key(const JsonbValue * v, char flag)
+make_scalar_text_key(const JsonbValue * v, char flag)
{
text *item;
char *cstr;
item = make_text_key(v->string.val, v->string.len, flag);
break;
default:
- elog(ERROR, "invalid jsonb primitive type: %d", v->type);
+ elog(ERROR, "invalid jsonb scalar type: %d", v->type);
}
return item;
}
/*
- * Hash a JsonbValue primitive value, and push it on to hashing stack
+ * Hash a JsonbValue scalar value, and push it on to hashing stack
*/
static void
-hash_primitive_value(const JsonbValue * v, PathHashStack * stack)
+hash_scalar_value(const JsonbValue * v, PathHashStack * stack)
{
switch (v->type)
{
COMP_CRC32(stack->hash_state, v->string.val, v->string.len);
break;
default:
- elog(ERROR, "invalid jsonb primitive type");
+ elog(ERROR, "invalid jsonb scalar type");
break;
}
}
JsonbIterator *it = JsonbIteratorInit(VARDATA(query));
JsonbValue v;
- while ((r = JsonbIteratorGet(&it, &v, false)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, false)) != 0)
{
if ((r == WJB_ELEM || r == WJB_KEY || r == WJB_VALUE) && v.type != jbvNull)
{
JsonbValue v;
int r;
- while ((r = JsonbIteratorGet(&it, &v, false)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, false)) != 0)
{
if ((r == WJB_ELEM || r == WJB_KEY || r == WJB_VALUE) &&
v.type != jbvNull)
it = JsonbIteratorInit(VARDATA(jb));
INIT_CRC32(crc);
- while ((r = JsonbIteratorGet(&it, &v, false)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, false)) != 0)
{
switch (r)
{
v2;
bool res = true;
- r1 = JsonbIteratorGet(it1, &v1, false);
- r2 = JsonbIteratorGet(it2, &v2, false);
+ r1 = JsonbIteratorNext(it1, &v1, false);
+ r2 = JsonbIteratorNext(it2, &v2, false);
if (r1 != r2)
{
for (;;)
{
- r2 = JsonbIteratorGet(it2, &v2, false);
+ r2 = JsonbIteratorNext(it2, &v2, false);
if (r2 == WJB_END_OBJECT)
break;
break;
}
- r2 = JsonbIteratorGet(it2, &v2, true);
+ r2 = JsonbIteratorNext(it2, &v2, true);
Assert(r2 == WJB_VALUE);
if (v->type != v2.type)
for (;;)
{
- r2 = JsonbIteratorGet(it2, &v2, true);
+ r2 = JsonbIteratorNext(it2, &v2, true);
if (r2 == WJB_END_ARRAY)
break;
for (i = 0; i < nelems; i++)
{
- r2 = JsonbIteratorGet(it1, &v1, true);
+ r2 = JsonbIteratorNext(it1, &v1, true);
Assert(r2 == WJB_ELEM);
if (v1.type == jbvBinary)
int r1,
r2;
- r1 = JsonbIteratorGet(&it1, &v1, false);
- r2 = JsonbIteratorGet(&it2, &v2, false);
+ r1 = JsonbIteratorNext(&it1, &v1, false);
+ r2 = JsonbIteratorNext(&it2, &v2, false);
if (r1 == r2)
{
return h;
}
+/*
+ * Given an unparsed varlena buffer, expand to JsonbIterator.
+ */
+JsonbIterator *
+JsonbIteratorInit(char *buffer)
+{
+ JsonbIterator *it = palloc(sizeof(*it));
+
+ parseBuffer(it, buffer);
+ it->next = NULL;
+
+ return it;
+}
+
+/* Get next JsonbValue while iterating */
int
-JsonbIteratorGet(JsonbIterator ** it, JsonbValue * v, bool skipNested)
+JsonbIteratorNext(JsonbIterator ** it, JsonbValue * v, bool skipNested)
{
int res;
}
else if (formAnswer(it, v, &(*it)->array[(*it)->i++], skipNested))
{
- res = JsonbIteratorGet(it, v, skipNested);
+ res = JsonbIteratorNext(it, v, skipNested);
}
else
{
case JB_FLAG_OBJECT | jbi_value:
(*it)->state = jbi_key;
if (formAnswer(it, v, &(*it)->array[((*it)->i++) * 2 + 1], skipNested))
- res = JsonbIteratorGet(it, v, skipNested);
+ res = JsonbIteratorNext(it, v, skipNested);
else
res = WJB_VALUE;
break;
return res;
}
-JsonbIterator *
-JsonbIteratorInit(char *buffer)
-{
- JsonbIterator *it = palloc(sizeof(*it));
-
- parseBuffer(it, buffer);
- it->next = NULL;
-
- return it;
-}
-
/****************************************************************************
* Walk the tree representation of jsonb *
****************************************************************************/
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
* The next thing the iterator fetches should be the value, no
* matter what shape it is.
*/
- r = JsonbIteratorGet(&it, &v, skipNested);
+ r = JsonbIteratorNext(&it, &v, skipNested);
PG_RETURN_JSONB(JsonbValueToJsonb(&v));
}
}
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
* The next thing the iterator fetches should be the value, no
* matter what shape it is.
*/
- r = JsonbIteratorGet(&it, &v, skipNested);
+ r = JsonbIteratorNext(&it, &v, skipNested);
/*
* if it's a scalar string it needs to be de-escaped,
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
JsonbIterator *it = JsonbIteratorInit(jbvp->binary.data);
int r;
- r = JsonbIteratorGet(&it, &tv, true);
+ r = JsonbIteratorNext(&it, &tv, true);
jbvp = (JsonbValue *) jbvp->binary.data;
have_object = r == WJB_BEGIN_OBJECT;
have_array = r == WJB_BEGIN_ARRAY;
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
* The next thing the iterator fetches should be the value, no
* matter what shape it is.
*/
- r = JsonbIteratorGet(&it, &v, skipNested);
+ r = JsonbIteratorNext(&it, &v, skipNested);
values[0] = PointerGetDatum(key);
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
it = JsonbIteratorInit(VARDATA_ANY(jb));
- while ((r = JsonbIteratorGet(&it, &v, skipNested)) != 0)
+ while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
{
skipNested = true;
{
enum
{
+ /* Scalar types */
jbvNull,
jbvString,
jbvNumeric,
jbvBool,
+ /* Composite types */
jbvArray,
jbvObject,
- jbvBinary /* Binary form of jbvArray/jbvObject */
+ /* Binary form of jbvArray/jbvObject */
+ jbvBinary
} type;
uint32 size; /* Estimation size of node (including
struct ToJsonbState *next;
} ToJsonbState;
+/*
+ * JsonbIterator holds details of the type for each iteration. It also stores
+ * an unoriginal unparsed varlena buffer.
+ */
typedef struct JsonbIterator
{
uint32 type;
extern JsonbValue *getJsonbValue(char *buffer, uint32 flags, int32 i);
extern JsonbValue *pushJsonbValue(ToJsonbState ** state, int r, JsonbValue *v);
extern JsonbIterator *JsonbIteratorInit(char *buffer);
-extern int JsonbIteratorGet(JsonbIterator **it, JsonbValue *v, bool skipNested);
+extern int JsonbIteratorNext(JsonbIterator **it, JsonbValue *v, bool skipNested);
extern Jsonb *JsonbValueToJsonb(JsonbValue *v);
/* jsonb.c support function */