From f33a71a7865a1dd54f04b370e2637f88665f8db8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 2 Apr 2014 14:30:08 -0400 Subject: [PATCH] De-anonymize the union in JsonbValue. Needed for strict C89 compliance. --- contrib/hstore/hstore_io.c | 32 ++-- src/backend/utils/adt/jsonb.c | 34 ++-- src/backend/utils/adt/jsonb_gin.c | 6 +- src/backend/utils/adt/jsonb_op.c | 16 +- src/backend/utils/adt/jsonb_util.c | 266 ++++++++++++++--------------- src/backend/utils/adt/jsonfuncs.c | 46 ++--- src/include/utils/jsonb.h | 4 +- 7 files changed, 202 insertions(+), 202 deletions(-) diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c index 6cfc935788..6ec0b9cbf1 100644 --- a/contrib/hstore/hstore_io.c +++ b/contrib/hstore/hstore_io.c @@ -1397,9 +1397,9 @@ hstore_to_jsonb(PG_FUNCTION_ARGS) key.estSize = sizeof(JEntry); key.type = jbvString; - key.string.len = HS_KEYLEN(entries, i); - key.string.val = pnstrdup(HS_KEY(entries, base, i), key.string.len); - key.estSize += key.string.len; + key.val.string.len = HS_KEYLEN(entries, i); + key.val.string.val = pnstrdup(HS_KEY(entries, base, i), key.val.string.len); + key.estSize += key.val.string.len; res = pushJsonbValue(&state, WJB_KEY, &key); @@ -1412,9 +1412,9 @@ hstore_to_jsonb(PG_FUNCTION_ARGS) { val.estSize = sizeof(JEntry); val.type = jbvString; - val.string.len = HS_VALLEN(entries, i); - val.string.val = pnstrdup(HS_VAL(entries, base, i), val.string.len); - val.estSize += val.string.len; + val.val.string.len = HS_VALLEN(entries, i); + val.val.string.val = pnstrdup(HS_VAL(entries, base, i), val.val.string.len); + val.estSize += val.val.string.len; } res = pushJsonbValue(&state, WJB_VALUE, &val); } @@ -1449,9 +1449,9 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS) key.estSize = sizeof(JEntry); key.type = jbvString; - key.string.len = HS_KEYLEN(entries, i); - key.string.val = pnstrdup(HS_KEY(entries, base, i), key.string.len); - key.estSize += key.string.len; + key.val.string.len = HS_KEYLEN(entries, i); + key.val.string.val = pnstrdup(HS_KEY(entries, base, i), key.val.string.len); + key.estSize += key.val.string.len; res = pushJsonbValue(&state, WJB_KEY, &key); @@ -1465,12 +1465,12 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS) else if (HS_VALLEN(entries, i) == 1 && *(HS_VAL(entries, base, i)) == 't') { val.type = jbvBool; - val.boolean = true; + val.val.boolean = true; } else if (HS_VALLEN(entries, i) == 1 && *(HS_VAL(entries, base, i)) == 'f') { val.type = jbvBool; - val.boolean = false; + val.val.boolean = false; } else { @@ -1519,17 +1519,17 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS) if (is_number) { val.type = jbvNumeric; - val.numeric = DatumGetNumeric( + val.val.numeric = DatumGetNumeric( DirectFunctionCall3(numeric_in, CStringGetDatum(tmp.data), 0, -1)); - val.estSize += VARSIZE_ANY(val.numeric) +sizeof(JEntry); + val.estSize += VARSIZE_ANY(val.val.numeric) +sizeof(JEntry); } else { val.estSize = sizeof(JEntry); val.type = jbvString; - val.string.len = HS_VALLEN(entries, i); - val.string.val = pnstrdup(HS_VAL(entries, base, i), val.string.len); - val.estSize += val.string.len; + val.val.string.len = HS_VALLEN(entries, i); + val.val.string.val = pnstrdup(HS_VAL(entries, base, i), val.val.string.len); + val.estSize += val.val.string.len; } } res = pushJsonbValue(&state, WJB_VALUE, &val); diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index b30e79e425..781ab66ef2 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -247,9 +247,9 @@ jsonb_in_object_field_start(void *pstate, char *fname, bool isnull) Assert (fname != NULL); v.type = jbvString; - v.string.len = checkStringLen(strlen(fname)); - v.string.val = pnstrdup(fname, v.string.len); - v.estSize = sizeof(JEntry) + v.string.len; + v.val.string.len = checkStringLen(strlen(fname)); + v.val.string.val = pnstrdup(fname, v.val.string.len); + v.estSize = sizeof(JEntry) + v.val.string.len; _state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v); } @@ -263,15 +263,15 @@ jsonb_put_escaped_value(StringInfo out, JsonbValue * scalarVal) appendBinaryStringInfo(out, "null", 4); break; case jbvString: - escape_json(out, pnstrdup(scalarVal->string.val, scalarVal->string.len)); + escape_json(out, pnstrdup(scalarVal->val.string.val, scalarVal->val.string.len)); break; case jbvNumeric: appendStringInfoString(out, DatumGetCString(DirectFunctionCall1(numeric_out, - PointerGetDatum(scalarVal->numeric)))); + PointerGetDatum(scalarVal->val.numeric)))); break; case jbvBool: - if (scalarVal->boolean) + if (scalarVal->val.boolean) appendBinaryStringInfo(out, "true", 4); else appendBinaryStringInfo(out, "false", 5); @@ -298,9 +298,9 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype) case JSON_TOKEN_STRING: Assert (token != NULL); v.type = jbvString; - v.string.len = checkStringLen(strlen(token)); - v.string.val = pnstrdup(token, v.string.len); - v.estSize += v.string.len; + v.val.string.len = checkStringLen(strlen(token)); + v.val.string.val = pnstrdup(token, v.val.string.len); + v.estSize += v.val.string.len; break; case JSON_TOKEN_NUMBER: /* @@ -309,16 +309,16 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype) */ Assert (token != NULL); v.type = jbvNumeric; - v.numeric = DatumGetNumeric(DirectFunctionCall3(numeric_in, CStringGetDatum(token), 0, -1)); - v.estSize += VARSIZE_ANY(v.numeric) + sizeof(JEntry) /* alignment */ ; + v.val.numeric = DatumGetNumeric(DirectFunctionCall3(numeric_in, CStringGetDatum(token), 0, -1)); + v.estSize += VARSIZE_ANY(v.val.numeric) + sizeof(JEntry) /* alignment */ ; break; case JSON_TOKEN_TRUE: v.type = jbvBool; - v.boolean = true; + v.val.boolean = true; break; case JSON_TOKEN_FALSE: v.type = jbvBool; - v.boolean = false; + v.val.boolean = false; break; case JSON_TOKEN_NULL: v.type = jbvNull; @@ -335,8 +335,8 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype) JsonbValue va; va.type = jbvArray; - va.array.rawScalar = true; - va.array.nElems = 1; + va.val.array.rawScalar = true; + va.val.array.nElems = 1; _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, &va); _state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v); @@ -399,7 +399,7 @@ JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len) appendBinaryStringInfo(out, ", ", 2); first = true; - if (!v.array.rawScalar) + if (!v.val.array.rawScalar) appendStringInfoChar(out, '['); level++; break; @@ -448,7 +448,7 @@ JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len) break; case WJB_END_ARRAY: level--; - if (!v.array.rawScalar) + if (!v.val.array.rawScalar) appendStringInfoChar(out, ']'); first = false; break; diff --git a/src/backend/utils/adt/jsonb_gin.c b/src/backend/utils/adt/jsonb_gin.c index 32ca024c69..62546ebaf2 100644 --- a/src/backend/utils/adt/jsonb_gin.c +++ b/src/backend/utils/adt/jsonb_gin.c @@ -618,7 +618,7 @@ make_scalar_key(const JsonbValue * scalarVal, char flag) item = make_text_key("n", 1, flag); break; case jbvBool: - item = make_text_key(scalarVal->boolean ? "t" : "f", 1, flag); + item = make_text_key(scalarVal->val.boolean ? "t" : "f", 1, flag); break; case jbvNumeric: /* @@ -630,12 +630,12 @@ make_scalar_key(const JsonbValue * scalarVal, char flag) * storing a "union" type in the GIN B-Tree, and indexing Jsonb * strings takes precedence. */ - cstr = numeric_normalize(scalarVal->numeric); + cstr = numeric_normalize(scalarVal->val.numeric); item = make_text_key(cstr, strlen(cstr), flag); pfree(cstr); break; case jbvString: - item = make_text_key(scalarVal->string.val, scalarVal->string.len, + item = make_text_key(scalarVal->val.string.val, scalarVal->val.string.len, flag); break; default: diff --git a/src/backend/utils/adt/jsonb_op.c b/src/backend/utils/adt/jsonb_op.c index d6b1855c19..cfddccbbbb 100644 --- a/src/backend/utils/adt/jsonb_op.c +++ b/src/backend/utils/adt/jsonb_op.c @@ -31,8 +31,8 @@ jsonb_exists(PG_FUNCTION_ARGS) * top level. No recursion occurs. */ kval.type = jbvString; - kval.string.val = VARDATA_ANY(key); - kval.string.len = VARSIZE_ANY_EXHDR(key); + kval.val.string.val = VARDATA_ANY(key); + kval.val.string.len = VARSIZE_ANY_EXHDR(key); v = findJsonbValueFromSuperHeader(VARDATA(jb), JB_FOBJECT | JB_FARRAY, @@ -52,7 +52,7 @@ jsonb_exists_any(PG_FUNCTION_ARGS) lowbound = 0; int i; - if (arrKey == NULL || arrKey->object.nPairs == 0) + if (arrKey == NULL || arrKey->val.object.nPairs == 0) PG_RETURN_BOOL(false); if (JB_ROOT_IS_OBJECT(jb)) @@ -64,12 +64,12 @@ jsonb_exists_any(PG_FUNCTION_ARGS) * each search can start one entry past the previous "found" entry, or at * the lower bound of the last search. */ - for (i = 0; i < arrKey->array.nElems; i++) + for (i = 0; i < arrKey->val.array.nElems; i++) { if (findJsonbValueFromSuperHeader(VARDATA(jb), JB_FOBJECT | JB_FARRAY, plowbound, - arrKey->array.elems + i) != NULL) + arrKey->val.array.elems + i) != NULL) PG_RETURN_BOOL(true); } @@ -86,7 +86,7 @@ jsonb_exists_all(PG_FUNCTION_ARGS) uint32 lowbound = 0; int i; - if (arrKey == NULL || arrKey->array.nElems == 0) + if (arrKey == NULL || arrKey->val.array.nElems == 0) PG_RETURN_BOOL(true); if (JB_ROOT_IS_OBJECT(jb)) @@ -98,12 +98,12 @@ jsonb_exists_all(PG_FUNCTION_ARGS) * each search can start one entry past the previous "found" entry, or at * the lower bound of the last search. */ - for (i = 0; i < arrKey->array.nElems; i++) + for (i = 0; i < arrKey->val.array.nElems; i++) { if (findJsonbValueFromSuperHeader(VARDATA(jb), JB_FOBJECT | JB_FARRAY, plowbound, - arrKey->array.elems + i) == NULL) + arrKey->val.array.elems + i) == NULL) PG_RETURN_BOOL(false); } diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index 86e48a322e..1ac145b1cd 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -120,8 +120,8 @@ JsonbValueToJsonb(JsonbValue * val) JsonbValue scalarArray; scalarArray.type = jbvArray; - scalarArray.array.rawScalar = true; - scalarArray.array.nElems = 1; + scalarArray.val.array.rawScalar = true; + scalarArray.val.array.nElems = 1; pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray); pushJsonbValue(&pstate, WJB_ELEM, val); @@ -142,9 +142,9 @@ JsonbValueToJsonb(JsonbValue * val) else { Assert(val->type == jbvBinary); - out = palloc(VARHDRSZ + val->binary.len); - SET_VARSIZE(out, VARHDRSZ + val->binary.len); - memcpy(VARDATA(out), val->binary.data, val->binary.len); + out = palloc(VARHDRSZ + val->val.binary.len); + SET_VARSIZE(out, VARHDRSZ + val->val.binary.len); + memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len); } return out; @@ -214,14 +214,14 @@ compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b) * general type-based comparisons to apply, and as far * as we're concerned a pseudo array is just a scalar. */ - if (va.array.rawScalar != vb.array.rawScalar) - res = (va.array.rawScalar) ? -1 : 1; - if (va.array.nElems != vb.array.nElems) - res = (va.array.nElems > vb.array.nElems) ? 1 : -1; + if (va.val.array.rawScalar != vb.val.array.rawScalar) + res = (va.val.array.rawScalar) ? -1 : 1; + if (va.val.array.nElems != vb.val.array.nElems) + res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1; break; case jbvObject: - if (va.object.nPairs != vb.object.nPairs) - res = (va.object.nPairs > vb.object.nPairs) ? 1 : -1; + if (va.val.object.nPairs != vb.val.object.nPairs) + res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1; break; case jbvBinary: elog(ERROR, "unexpected jbvBinary value"); @@ -339,21 +339,21 @@ findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags, else if (JBE_ISSTRING(*e) && key->type == jbvString) { result->type = jbvString; - result->string.val = data + JBE_OFF(*e); - result->string.len = JBE_LEN(*e); - result->estSize = sizeof(JEntry) + result->string.len; + result->val.string.val = data + JBE_OFF(*e); + result->val.string.len = JBE_LEN(*e); + result->estSize = sizeof(JEntry) + result->val.string.len; } else if (JBE_ISNUMERIC(*e) && key->type == jbvNumeric) { result->type = jbvNumeric; - result->numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e))); + result->val.numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e))); result->estSize = 2 * sizeof(JEntry) + - VARSIZE_ANY(result->numeric); + VARSIZE_ANY(result->val.numeric); } else if (JBE_ISBOOL(*e) && key->type == jbvBool) { result->type = jbvBool; - result->boolean = JBE_ISBOOL_TRUE(*e) != 0; + result->val.boolean = JBE_ISBOOL_TRUE(*e) != 0; result->estSize = sizeof(JEntry); } else @@ -389,9 +389,9 @@ findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags, entry = array + stopMiddle * 2; candidate.type = jbvString; - candidate.string.val = data + JBE_OFF(*entry); - candidate.string.len = JBE_LEN(*entry); - candidate.estSize = sizeof(JEntry) + candidate.string.len; + candidate.val.string.val = data + JBE_OFF(*entry); + candidate.val.string.len = JBE_LEN(*entry); + candidate.estSize = sizeof(JEntry) + candidate.val.string.len; difference = lengthCompareJsonbStringValue(&candidate, key, NULL); @@ -411,21 +411,21 @@ findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags, else if (JBE_ISSTRING(*v)) { result->type = jbvString; - result->string.val = data + JBE_OFF(*v); - result->string.len = JBE_LEN(*v); - result->estSize = sizeof(JEntry) + result->string.len; + result->val.string.val = data + JBE_OFF(*v); + result->val.string.len = JBE_LEN(*v); + result->estSize = sizeof(JEntry) + result->val.string.len; } else if (JBE_ISNUMERIC(*v)) { result->type = jbvNumeric; - result->numeric = (Numeric) (data + INTALIGN(JBE_OFF(*v))); + result->val.numeric = (Numeric) (data + INTALIGN(JBE_OFF(*v))); result->estSize = 2 * sizeof(JEntry) + - VARSIZE_ANY(result->numeric); + VARSIZE_ANY(result->val.numeric); } else if (JBE_ISBOOL(*v)) { result->type = jbvBool; - result->boolean = JBE_ISBOOL_TRUE(*v) != 0; + result->val.boolean = JBE_ISBOOL_TRUE(*v) != 0; result->estSize = sizeof(JEntry); } else @@ -435,10 +435,10 @@ findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags, * with arrays */ result->type = jbvBinary; - result->binary.data = data + INTALIGN(JBE_OFF(*v)); - result->binary.len = JBE_LEN(*v) - + result->val.binary.data = data + INTALIGN(JBE_OFF(*v)); + result->val.binary.len = JBE_LEN(*v) - (INTALIGN(JBE_OFF(*v)) - JBE_OFF(*v)); - result->estSize = 2 * sizeof(JEntry) + result->binary.len; + result->estSize = 2 * sizeof(JEntry) + result->val.binary.len; } return result; @@ -500,28 +500,28 @@ getIthJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 i) else if (JBE_ISSTRING(*e)) { result->type = jbvString; - result->string.val = data + JBE_OFF(*e); - result->string.len = JBE_LEN(*e); - result->estSize = sizeof(JEntry) + result->string.len; + result->val.string.val = data + JBE_OFF(*e); + result->val.string.len = JBE_LEN(*e); + result->estSize = sizeof(JEntry) + result->val.string.len; } else if (JBE_ISNUMERIC(*e)) { result->type = jbvNumeric; - result->numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e))); - result->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(result->numeric); + result->val.numeric = (Numeric) (data + INTALIGN(JBE_OFF(*e))); + result->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(result->val.numeric); } else if (JBE_ISBOOL(*e)) { result->type = jbvBool; - result->boolean = JBE_ISBOOL_TRUE(*e) != 0; + result->val.boolean = JBE_ISBOOL_TRUE(*e) != 0; result->estSize = sizeof(JEntry); } else { result->type = jbvBinary; - result->binary.data = data + INTALIGN(JBE_OFF(*e)); - result->binary.len = JBE_LEN(*e) - (INTALIGN(JBE_OFF(*e)) - JBE_OFF(*e)); - result->estSize = result->binary.len + 2 * sizeof(JEntry); + result->val.binary.data = data + INTALIGN(JBE_OFF(*e)); + result->val.binary.len = JBE_LEN(*e) - (INTALIGN(JBE_OFF(*e)) - JBE_OFF(*e)); + result->estSize = result->val.binary.len + 2 * sizeof(JEntry); } return result; @@ -548,25 +548,25 @@ pushJsonbValue(JsonbParseState ** pstate, int seq, JsonbValue * scalarVal) switch (seq) { case WJB_BEGIN_ARRAY: - Assert(!scalarVal || scalarVal->array.rawScalar); + Assert(!scalarVal || scalarVal->val.array.rawScalar); *pstate = pushState(pstate); result = &(*pstate)->contVal; (*pstate)->contVal.type = jbvArray; (*pstate)->contVal.estSize = 3 * sizeof(JEntry); - (*pstate)->contVal.array.nElems = 0; - (*pstate)->contVal.array.rawScalar = (scalarVal && - scalarVal->array.rawScalar); - if (scalarVal && scalarVal->array.nElems > 0) + (*pstate)->contVal.val.array.nElems = 0; + (*pstate)->contVal.val.array.rawScalar = (scalarVal && + scalarVal->val.array.rawScalar); + if (scalarVal && scalarVal->val.array.nElems > 0) { /* Assume that this array is still really a scalar */ Assert(scalarVal->type == jbvArray); - (*pstate)->size = scalarVal->array.nElems; + (*pstate)->size = scalarVal->val.array.nElems; } else { (*pstate)->size = 4; } - (*pstate)->contVal.array.elems = palloc(sizeof(JsonbValue) * + (*pstate)->contVal.val.array.elems = palloc(sizeof(JsonbValue) * (*pstate)->size); break; case WJB_BEGIN_OBJECT: @@ -575,9 +575,9 @@ pushJsonbValue(JsonbParseState ** pstate, int seq, JsonbValue * scalarVal) result = &(*pstate)->contVal; (*pstate)->contVal.type = jbvObject; (*pstate)->contVal.estSize = 3 * sizeof(JEntry); - (*pstate)->contVal.object.nPairs = 0; + (*pstate)->contVal.val.object.nPairs = 0; (*pstate)->size = 4; - (*pstate)->contVal.object.pairs = palloc(sizeof(JsonbPair) * + (*pstate)->contVal.val.object.pairs = palloc(sizeof(JsonbPair) * (*pstate)->size); break; case WJB_KEY: @@ -693,12 +693,12 @@ JsonbIteratorNext(JsonbIterator ** it, JsonbValue * val, bool skipNested) { /* Set v to array on first array call */ val->type = jbvArray; - val->array.nElems = (*it)->nElems; + val->val.array.nElems = (*it)->nElems; /* - * v->array.elems is not actually set, because we aren't doing a + * v->val.array.elems is not actually set, because we aren't doing a * full conversion */ - val->array.rawScalar = (*it)->isScalar; + val->val.array.rawScalar = (*it)->isScalar; (*it)->i = 0; /* Set state for next call */ (*it)->state = jbi_elem; @@ -740,10 +740,10 @@ JsonbIteratorNext(JsonbIterator ** it, JsonbValue * val, bool skipNested) { /* Set v to object on first object call */ val->type = jbvObject; - val->object.nPairs = (*it)->nElems; + val->val.object.nPairs = (*it)->nElems; /* - * v->object.pairs is not actually set, because we aren't doing a - * full conversion + * v->val.object.pairs is not actually set, because we aren't + * doing a full conversion */ (*it)->i = 0; /* Set state for next call */ @@ -903,8 +903,8 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained) Assert(lhsVal->type == jbvBinary); Assert(vcontained.type == jbvBinary); - nestval = JsonbIteratorInit(lhsVal->binary.data); - nestContained = JsonbIteratorInit(vcontained.binary.data); + nestval = JsonbIteratorInit(lhsVal->val.binary.data); + nestContained = JsonbIteratorInit(vcontained.val.binary.data); /* * Match "value" side of rhs datum object's pair recursively. @@ -933,7 +933,7 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained) else if (rcont == WJB_BEGIN_ARRAY) { JsonbValue *lhsConts = NULL; - uint32 nLhsElems = vval.array.nElems; + uint32 nLhsElems = vval.val.array.nElems; Assert(vcontained.type == jbvArray); @@ -947,7 +947,7 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained) * only contain pairs, never raw scalars (a pair is represented by an * rhs object argument with a single contained pair). */ - if (vval.array.rawScalar && !vcontained.array.rawScalar) + if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar) return false; /* Work through rhs "is it contained within?" array */ @@ -1012,8 +1012,8 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained) JsonbIterator *nestval, *nestContained; bool contains; - nestval = JsonbIteratorInit(lhsConts[i].binary.data); - nestContained = JsonbIteratorInit(vcontained.binary.data); + nestval = JsonbIteratorInit(lhsConts[i].val.binary.data); + nestContained = JsonbIteratorInit(vcontained.val.binary.data); contains = JsonbDeepContains(&nestval, &nestContained); @@ -1081,20 +1081,20 @@ arrayToJsonbSortedArray(ArrayType *array) result = palloc(sizeof(JsonbValue)); result->type = jbvArray; - result->array.rawScalar = false; - result->array.elems = palloc(sizeof(JsonbPair) * elem_count); + result->val.array.rawScalar = false; + result->val.array.elems = palloc(sizeof(JsonbPair) * elem_count); for (i = 0, j = 0; i < elem_count; i++) { if (!key_nulls[i]) { - result->array.elems[j].type = jbvString; - result->array.elems[j].string.val = VARDATA(key_datums[i]); - result->array.elems[j].string.len = VARSIZE(key_datums[i]) - VARHDRSZ; + result->val.array.elems[j].type = jbvString; + result->val.array.elems[j].val.string.val = VARDATA(key_datums[i]); + result->val.array.elems[j].val.string.len = VARSIZE(key_datums[i]) - VARHDRSZ; j++; } } - result->array.nElems = j; + result->val.array.nElems = j; uniqueifyJsonbArray(result); return result; @@ -1124,18 +1124,18 @@ JsonbHashScalarValue(const JsonbValue * scalarVal, uint32 * hash) *hash ^= 0x01; return; case jbvString: - tmp = hash_any((unsigned char *) scalarVal->string.val, - scalarVal->string.len); + tmp = hash_any((unsigned char *) scalarVal->val.string.val, + scalarVal->val.string.len); *hash ^= tmp; return; case jbvNumeric: /* Must be unaffected by trailing zeroes */ tmp = DatumGetInt32(DirectFunctionCall1(hash_numeric, - NumericGetDatum(scalarVal->numeric))); + NumericGetDatum(scalarVal->val.numeric))); *hash ^= tmp; return; case jbvBool: - *hash ^= scalarVal->boolean? 0x02:0x04; + *hash ^= scalarVal->val.boolean? 0x02:0x04; return; default: elog(ERROR, "invalid jsonb scalar type"); @@ -1162,11 +1162,11 @@ compareJsonbScalarValue(JsonbValue * aScalar, JsonbValue * bScalar) return lengthCompareJsonbStringValue(aScalar, bScalar, NULL); case jbvNumeric: return DatumGetInt32(DirectFunctionCall2(numeric_cmp, - PointerGetDatum(aScalar->numeric), - PointerGetDatum(bScalar->numeric))); + PointerGetDatum(aScalar->val.numeric), + PointerGetDatum(bScalar->val.numeric))); case jbvBool: - if (aScalar->boolean != bScalar->boolean) - return (aScalar->boolean > bScalar->boolean) ? 1 : -1; + if (aScalar->val.boolean != bScalar->val.boolean) + return (aScalar->val.boolean > bScalar->val.boolean) ? 1 : -1; else return 0; default: @@ -1192,8 +1192,8 @@ lexicalCompareJsonbStringValue(const void *a, const void *b) Assert(va->type == jbvString); Assert(vb->type == jbvString); - return varstr_cmp(va->string.val, va->string.len, vb->string.val, - vb->string.len, DEFAULT_COLLATION_OID); + return varstr_cmp(va->val.string.val, va->val.string.len, vb->val.string.val, + vb->val.string.len, DEFAULT_COLLATION_OID); } /* @@ -1247,14 +1247,14 @@ walkJsonbValueConversion(JsonbValue * val, convertState * cstate, case jbvArray: putJsonbValueConversion(cstate, val, WJB_BEGIN_ARRAY, nestlevel); - for (i = 0; i < val->array.nElems; i++) + for (i = 0; i < val->val.array.nElems; i++) { - if (IsAJsonbScalar(&val->array.elems[i]) || - val->array.elems[i].type == jbvBinary) - putJsonbValueConversion(cstate, val->array.elems + i, + if (IsAJsonbScalar(&val->val.array.elems[i]) || + val->val.array.elems[i].type == jbvBinary) + putJsonbValueConversion(cstate, val->val.array.elems + i, WJB_ELEM, nestlevel); else - walkJsonbValueConversion(val->array.elems + i, cstate, + walkJsonbValueConversion(val->val.array.elems + i, cstate, nestlevel + 1); } putJsonbValueConversion(cstate, val, WJB_END_ARRAY, nestlevel); @@ -1263,18 +1263,18 @@ walkJsonbValueConversion(JsonbValue * val, convertState * cstate, case jbvObject: putJsonbValueConversion(cstate, val, WJB_BEGIN_OBJECT, nestlevel); - for (i = 0; i < val->object.nPairs; i++) + for (i = 0; i < val->val.object.nPairs; i++) { - putJsonbValueConversion(cstate, &val->object.pairs[i].key, + putJsonbValueConversion(cstate, &val->val.object.pairs[i].key, WJB_KEY, nestlevel); - if (IsAJsonbScalar(&val->object.pairs[i].value) || - val->object.pairs[i].value.type == jbvBinary) + if (IsAJsonbScalar(&val->val.object.pairs[i].value) || + val->val.object.pairs[i].value.type == jbvBinary) putJsonbValueConversion(cstate, - &val->object.pairs[i].value, + &val->val.object.pairs[i].value, WJB_VALUE, nestlevel); else - walkJsonbValueConversion(&val->object.pairs[i].value, + walkJsonbValueConversion(&val->val.object.pairs[i].value, cstate, nestlevel + 1); } putJsonbValueConversion(cstate, val, WJB_END_OBJECT, nestlevel); @@ -1351,20 +1351,20 @@ putJsonbValueConversion(convertState * cstate, JsonbValue * val, uint32 flags, if (val->type == jbvArray) { - *cstate->contPtr->header = val->array.nElems | JB_FARRAY; - cstate->ptr += sizeof(JEntry) * val->array.nElems; + *cstate->contPtr->header = val->val.array.nElems | JB_FARRAY; + cstate->ptr += sizeof(JEntry) * val->val.array.nElems; - if (val->array.rawScalar) + if (val->val.array.rawScalar) { - Assert(val->array.nElems == 1); + Assert(val->val.array.nElems == 1); Assert(level == 0); *cstate->contPtr->header |= JB_FSCALAR; } } else { - *cstate->contPtr->header = val->object.nPairs | JB_FOBJECT; - cstate->ptr += sizeof(JEntry) * val->object.nPairs * 2; + *cstate->contPtr->header = val->val.object.nPairs | JB_FOBJECT; + cstate->ptr += sizeof(JEntry) * val->val.object.nPairs * 2; } } else if (flags & WJB_ELEM) @@ -1466,21 +1466,21 @@ putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level, cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK; break; case jbvString: - memcpy(cstate->ptr, scalarVal->string.val, scalarVal->string.len); - cstate->ptr += scalarVal->string.len; + memcpy(cstate->ptr, scalarVal->val.string.val, scalarVal->val.string.len); + cstate->ptr += scalarVal->val.string.len; if (i == 0) - cstate->contPtr->meta[0].header |= scalarVal->string.len; + cstate->contPtr->meta[0].header |= scalarVal->val.string.len; else cstate->contPtr->meta[i].header |= (cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK) + - scalarVal->string.len; + scalarVal->val.string.len; break; case jbvNumeric: - numlen = VARSIZE_ANY(scalarVal->numeric); + numlen = VARSIZE_ANY(scalarVal->val.numeric); padlen = addPaddingInt(cstate); - memcpy(cstate->ptr, scalarVal->numeric, numlen); + memcpy(cstate->ptr, scalarVal->val.numeric, numlen); cstate->ptr += numlen; cstate->contPtr->meta[i].header |= JENTRY_ISNUMERIC; @@ -1492,7 +1492,7 @@ putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level, + padlen + numlen; break; case jbvBool: - cstate->contPtr->meta[i].header |= (scalarVal->boolean) ? + cstate->contPtr->meta[i].header |= (scalarVal->val.boolean) ? JENTRY_ISTRUE : JENTRY_ISFALSE; if (i > 0) @@ -1575,24 +1575,24 @@ formIterIsContainer(JsonbIterator ** it, JsonbValue * val, JEntry * ent, else if (JBE_ISSTRING(*ent)) { val->type = jbvString; - val->string.val = (*it)->dataProper + JBE_OFF(*ent); - val->string.len = JBE_LEN(*ent); - val->estSize = sizeof(JEntry) + val->string.len; + val->val.string.val = (*it)->dataProper + JBE_OFF(*ent); + val->val.string.len = JBE_LEN(*ent); + val->estSize = sizeof(JEntry) + val->val.string.len; return false; } else if (JBE_ISNUMERIC(*ent)) { val->type = jbvNumeric; - val->numeric = (Numeric) ((*it)->dataProper + INTALIGN(JBE_OFF(*ent))); - val->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(val->numeric); + val->val.numeric = (Numeric) ((*it)->dataProper + INTALIGN(JBE_OFF(*ent))); + val->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(val->val.numeric); return false; } else if (JBE_ISBOOL(*ent)) { val->type = jbvBool; - val->boolean = JBE_ISBOOL_TRUE(*ent) != 0; + val->val.boolean = JBE_ISBOOL_TRUE(*ent) != 0; val->estSize = sizeof(JEntry); return false; @@ -1600,9 +1600,9 @@ formIterIsContainer(JsonbIterator ** it, JsonbValue * val, JEntry * ent, else if (skipNested) { val->type = jbvBinary; - val->binary.data = (*it)->dataProper + INTALIGN(JBE_OFF(*ent)); - val->binary.len = JBE_LEN(*ent) - (INTALIGN(JBE_OFF(*ent)) - JBE_OFF(*ent)); - val->estSize = val->binary.len + 2 * sizeof(JEntry); + val->val.binary.data = (*it)->dataProper + INTALIGN(JBE_OFF(*ent)); + val->val.binary.len = JBE_LEN(*ent) - (INTALIGN(JBE_OFF(*ent)) - JBE_OFF(*ent)); + val->estSize = val->val.binary.len + 2 * sizeof(JEntry); return false; } @@ -1662,21 +1662,21 @@ appendKey(JsonbParseState * pstate, JsonbValue * string) Assert(object->type == jbvObject); Assert(string->type == jbvString); - if (object->object.nPairs >= JSONB_MAX_PAIRS) + if (object->val.object.nPairs >= JSONB_MAX_PAIRS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("number of jsonb object pairs exceeds the maximum allowed (%zu)", JSONB_MAX_PAIRS))); - if (object->object.nPairs >= pstate->size) + if (object->val.object.nPairs >= pstate->size) { pstate->size *= 2; - object->object.pairs = repalloc(object->object.pairs, + object->val.object.pairs = repalloc(object->val.object.pairs, sizeof(JsonbPair) * pstate->size); } - object->object.pairs[object->object.nPairs].key = *string; - object->object.pairs[object->object.nPairs].order = object->object.nPairs; + object->val.object.pairs[object->val.object.nPairs].key = *string; + object->val.object.pairs[object->val.object.nPairs].order = object->val.object.nPairs; object->estSize += string->estSize; } @@ -1692,7 +1692,7 @@ appendValue(JsonbParseState * pstate, JsonbValue * scalarVal) Assert(object->type == jbvObject); - object->object.pairs[object->object.nPairs++].value = *scalarVal; + object->val.object.pairs[object->val.object.nPairs++].value = *scalarVal; object->estSize += scalarVal->estSize; } @@ -1706,20 +1706,20 @@ appendElement(JsonbParseState * pstate, JsonbValue * scalarVal) Assert(array->type == jbvArray); - if (array->array.nElems >= JSONB_MAX_ELEMS) + if (array->val.array.nElems >= JSONB_MAX_ELEMS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("number of jsonb array elements exceeds the maximum allowed (%zu)", JSONB_MAX_ELEMS))); - if (array->array.nElems >= pstate->size) + if (array->val.array.nElems >= pstate->size) { pstate->size *= 2; - array->array.elems = repalloc(array->array.elems, + array->val.array.elems = repalloc(array->val.array.elems, sizeof(JsonbValue) * pstate->size); } - array->array.elems[array->array.nElems++] = *scalarVal; + array->val.array.elems[array->val.array.nElems++] = *scalarVal; array->estSize += scalarVal->estSize; } @@ -1749,15 +1749,15 @@ lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal) Assert(va->type == jbvString); Assert(vb->type == jbvString); - if (va->string.len == vb->string.len) + if (va->val.string.len == vb->val.string.len) { - res = memcmp(va->string.val, vb->string.val, va->string.len); + res = memcmp(va->val.string.val, vb->val.string.val, va->val.string.len); if (res == 0 && binequal) *((bool *) binequal) = true; } else { - res = (va->string.len > vb->string.len) ? 1 : -1; + res = (va->val.string.len > vb->val.string.len) ? 1 : -1; } return res; @@ -1803,16 +1803,16 @@ uniqueifyJsonbObject(JsonbValue * object) Assert(object->type == jbvObject); - if (object->object.nPairs > 1) - qsort_arg(object->object.pairs, object->object.nPairs, sizeof(JsonbPair), + if (object->val.object.nPairs > 1) + qsort_arg(object->val.object.pairs, object->val.object.nPairs, sizeof(JsonbPair), lengthCompareJsonbPair, &hasNonUniq); if (hasNonUniq) { - JsonbPair *ptr = object->object.pairs + 1, - *res = object->object.pairs; + JsonbPair *ptr = object->val.object.pairs + 1, + *res = object->val.object.pairs; - while (ptr - object->object.pairs < object->object.nPairs) + while (ptr - object->val.object.pairs < object->val.object.nPairs) { /* Avoid copying over duplicate */ if (lengthCompareJsonbStringValue(ptr, res, NULL) == 0) @@ -1828,7 +1828,7 @@ uniqueifyJsonbObject(JsonbValue * object) ptr++; } - object->object.nPairs = res + 1 - object->object.pairs; + object->val.object.nPairs = res + 1 - object->val.object.pairs; } } @@ -1848,17 +1848,17 @@ uniqueifyJsonbArray(JsonbValue * array) * Actually sort values, determining if any were equal on the basis of full * binary equality (rather than just having the same string length). */ - if (array->array.nElems > 1) - qsort_arg(array->array.elems, array->array.nElems, + if (array->val.array.nElems > 1) + qsort_arg(array->val.array.elems, array->val.array.nElems, sizeof(JsonbValue), lengthCompareJsonbStringValue, &hasNonUniq); if (hasNonUniq) { - JsonbValue *ptr = array->array.elems + 1, - *res = array->array.elems; + JsonbValue *ptr = array->val.array.elems + 1, + *res = array->val.array.elems; - while (ptr - array->array.elems < array->array.nElems) + while (ptr - array->val.array.elems < array->val.array.nElems) { /* Avoid copying over duplicate */ if (lengthCompareJsonbStringValue(ptr, res, NULL) != 0) @@ -1870,6 +1870,6 @@ uniqueifyJsonbArray(JsonbValue * array) ptr++; } - array->array.nElems = res + 1 - array->array.elems; + array->val.array.nElems = res + 1 - array->val.array.elems; } } diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index 73923951e8..2423b737c9 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -295,9 +295,9 @@ jsonb_object_keys(PG_FUNCTION_ARGS) { char *cstr; - cstr = palloc(v.string.len + 1 * sizeof(char)); - memcpy(cstr, v.string.val, v.string.len); - cstr[v.string.len] = '\0'; + cstr = palloc(v.val.string.len + 1 * sizeof(char)); + memcpy(cstr, v.val.string.val, v.val.string.len); + cstr[v.val.string.len] = '\0'; state->result[state->result_count++] = cstr; } } @@ -491,7 +491,7 @@ jsonb_object_field(PG_FUNCTION_ARGS) if (r == WJB_KEY) { - if (klen == v.string.len && strncmp(key, v.string.val, klen) == 0) + if (klen == v.val.string.len && strncmp(key, v.val.string.val, klen) == 0) { /* * The next thing the iterator fetches should be the value, no @@ -552,7 +552,7 @@ jsonb_object_field_text(PG_FUNCTION_ARGS) if (r == WJB_KEY) { - if (klen == v.string.len && strncmp(key, v.string.val, klen) == 0) + if (klen == v.val.string.len && strncmp(key, v.val.string.val, klen) == 0) { text *result; @@ -568,7 +568,7 @@ jsonb_object_field_text(PG_FUNCTION_ARGS) */ if (v.type == jbvString) { - result = cstring_to_text_with_len(v.string.val, v.string.len); + result = cstring_to_text_with_len(v.val.string.val, v.val.string.len); } else if (v.type == jbvNull) { @@ -699,7 +699,7 @@ jsonb_array_element_text(PG_FUNCTION_ARGS) if (v.type == jbvString) { - result = cstring_to_text_with_len(v.string.val, v.string.len); + result = cstring_to_text_with_len(v.val.string.val, v.val.string.len); } else if (v.type == jbvNull) { @@ -1209,11 +1209,11 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) if (jbvp->type == jbvBinary) { - JsonbIterator *it = JsonbIteratorInit(jbvp->binary.data); + JsonbIterator *it = JsonbIteratorInit(jbvp->val.binary.data); int r; r = JsonbIteratorNext(&it, &tv, true); - superHeader = (JsonbSuperHeader) jbvp->binary.data; + superHeader = (JsonbSuperHeader) jbvp->val.binary.data; have_object = r == WJB_BEGIN_OBJECT; have_array = r == WJB_BEGIN_ARRAY; } @@ -1227,7 +1227,7 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) if (as_text) { if (jbvp->type == jbvString) - PG_RETURN_TEXT_P(cstring_to_text_with_len(jbvp->string.val, jbvp->string.len)); + PG_RETURN_TEXT_P(cstring_to_text_with_len(jbvp->val.string.val, jbvp->val.string.len)); else if (jbvp->type == jbvNull) PG_RETURN_NULL(); } @@ -1443,7 +1443,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, bool as_text) /* Use the tmp context so we can clean up after each tuple is done */ old_cxt = MemoryContextSwitchTo(tmp_cxt); - key = cstring_to_text_with_len(v.string.val, v.string.len); + key = cstring_to_text_with_len(v.val.string.val, v.val.string.len); /* * The next thing the iterator fetches should be the value, no @@ -1468,7 +1468,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, bool as_text) if (v.type == jbvString) { /* In text mode, scalar strings should be dequoted */ - sv = cstring_to_text_with_len(v.string.val, v.string.len); + sv = cstring_to_text_with_len(v.val.string.val, v.val.string.len); } else { @@ -1788,7 +1788,7 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, bool as_text) if (v.type == jbvString) { /* in text mode scalar strings should be dequoted */ - sv = cstring_to_text_with_len(v.string.val, v.string.len); + sv = cstring_to_text_with_len(v.val.string.val, v.val.string.len); } else { @@ -2270,18 +2270,18 @@ populate_record_worker(FunctionCallInfo fcinfo, bool have_record_arg) else { if (v->type == jbvString) - s = pnstrdup(v->string.val, v->string.len); + s = pnstrdup(v->val.string.val, v->val.string.len); else if (v->type == jbvBool) - s = pnstrdup((v->boolean) ? "t" : "f", 1); + s = pnstrdup((v->val.boolean) ? "t" : "f", 1); else if (v->type == jbvNumeric) s = DatumGetCString(DirectFunctionCall1(numeric_out, - PointerGetDatum(v->numeric))); + PointerGetDatum(v->val.numeric))); else if (!use_json_as_text) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot populate with a nested object unless use_json_as_text is true"))); else if (v->type == jbvBinary) - s = JsonbToCString(NULL, v->binary.data, v->binary.len); + s = JsonbToCString(NULL, v->val.binary.data, v->val.binary.len); else elog(ERROR, "invalid jsonb type"); } @@ -2570,18 +2570,18 @@ make_row_from_rec_and_jsonb(Jsonb * element, PopulateRecordsetState *state) char *s = NULL; if (v->type == jbvString) - s = pnstrdup(v->string.val, v->string.len); + s = pnstrdup(v->val.string.val, v->val.string.len); else if (v->type == jbvBool) - s = pnstrdup((v->boolean) ? "t" : "f", 1); + s = pnstrdup((v->val.boolean) ? "t" : "f", 1); else if (v->type == jbvNumeric) s = DatumGetCString(DirectFunctionCall1(numeric_out, - PointerGetDatum(v->numeric))); + PointerGetDatum(v->val.numeric))); else if (!state->use_json_as_text) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot populate with a nested object unless use_json_as_text is true"))); else if (v->type == jbvBinary) - s = JsonbToCString(NULL, v->binary.data, v->binary.len); + s = JsonbToCString(NULL, v->val.binary.data, v->val.binary.len); else elog(ERROR, "invalid jsonb type"); @@ -3027,8 +3027,8 @@ findJsonbValueFromSuperHeaderLen(JsonbSuperHeader sheader, uint32 flags, JsonbValue k; k.type = jbvString; - k.string.val = key; - k.string.len = keylen; + k.val.string.val = key; + k.val.string.len = keylen; return findJsonbValueFromSuperHeader(sheader, flags, NULL, &k); } diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h index a70cbd5940..00a6d4f9e0 100644 --- a/src/include/utils/jsonb.h +++ b/src/include/utils/jsonb.h @@ -141,7 +141,7 @@ typedef struct /* * JsonbValue: In-memory representation of Jsonb. This is a convenient - * deserialized representation, that can easily support using the anonymous + * deserialized representation, that can easily support using the "val" * union across underlying types during manipulation. The Jsonb on-disk * representation has various alignment considerations. */ @@ -192,7 +192,7 @@ struct JsonbValue int len; char *data; } binary; - }; + } val; }; /* -- 2.40.0