diff options
author | Pavan Deolasee | 2015-06-05 13:35:08 +0000 |
---|---|---|
committer | Pavan Deolasee | 2015-06-05 13:35:08 +0000 |
commit | bbf2fec2f194a40b25561c2d2d62c432b49bdd1a (patch) | |
tree | aef582c5cba2ab7b111c0e20e9ebf71dab32c91f /src/backend/utils/adt/jsonb_util.c | |
parent | 633da80d8080348ae59dcdd1404a061abc8d0ead (diff) | |
parent | 38d500ac2e5d4d4f3468b505962fb85850c1ff4b (diff) |
Merge remote-tracking branch 'remotes/PGSQL/master' into XL_NEW_MASTER
Conflicts:
.gitignore
contrib/Makefile
src/backend/access/common/heaptuple.c
src/backend/access/transam/rmgr.c
src/backend/access/transam/xact.c
src/backend/catalog/Makefile
src/backend/catalog/catalog.c
src/backend/catalog/genbki.pl
src/backend/catalog/namespace.c
src/backend/commands/sequence.c
src/backend/executor/execMain.c
src/backend/executor/functions.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeModifyTable.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/util/pathnode.c
src/backend/parser/gram.y
src/backend/parser/parse_agg.c
src/backend/parser/parse_utilcmd.c
src/backend/postmaster/postmaster.c
src/backend/replication/logical/decode.c
src/backend/storage/file/fd.c
src/backend/storage/ipc/procsignal.c
src/backend/tcop/utility.c
src/backend/utils/adt/lockfuncs.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/sort/tuplesort.c
src/backend/utils/time/snapmgr.c
src/include/access/rmgrlist.h
src/include/catalog/pg_aggregate.h
src/include/catalog/pg_proc.h
src/include/nodes/execnodes.h
src/include/nodes/plannodes.h
src/include/nodes/primnodes.h
src/include/nodes/relation.h
src/include/storage/lwlock.h
src/include/storage/procsignal.h
src/include/utils/plancache.h
src/include/utils/snapshot.h
src/test/regress/expected/foreign_key.out
src/test/regress/expected/triggers.out
src/test/regress/expected/with.out
src/test/regress/input/constraints.source
src/test/regress/output/constraints.source
src/test/regress/pg_regress.c
src/test/regress/serial_schedule
src/test/regress/sql/returning.sql
Diffstat (limited to 'src/backend/utils/adt/jsonb_util.c')
-rw-r--r-- | src/backend/utils/adt/jsonb_util.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index 5cd9140896..4d733159d0 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -57,6 +57,9 @@ static void appendElement(JsonbParseState *pstate, JsonbValue *scalarVal); static int lengthCompareJsonbStringValue(const void *a, const void *b); static int lengthCompareJsonbPair(const void *a, const void *b, void *arg); static void uniqueifyJsonbObject(JsonbValue *object); +static JsonbValue *pushJsonbValueScalar(JsonbParseState **pstate, + JsonbIteratorToken seq, + JsonbValue *scalarVal); /* * Turn an in-memory JsonbValue into a Jsonb for on-disk storage. @@ -503,11 +506,44 @@ fillJsonbValue(JsonbContainer *container, int index, * * 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. + * "raw scalar" pseudo array to append it - the actual scalar should be passed + * next and it will be added as the only member of the array. + * + * Values of type jvbBinary, which are rolled up arrays and objects, + * are unpacked before being added to the result. */ JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, - JsonbValue *scalarVal) + JsonbValue *jbval) +{ + JsonbIterator *it; + JsonbValue *res = NULL; + JsonbValue v; + JsonbIteratorToken tok; + + if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE) || + jbval->type != jbvBinary) + { + /* drop through */ + return pushJsonbValueScalar(pstate, seq, jbval); + } + + /* unpack the binary and add each piece to the pstate */ + it = JsonbIteratorInit(jbval->val.binary.data); + while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) + res = pushJsonbValueScalar(pstate, tok, + tok < WJB_BEGIN_ARRAY ? &v : NULL); + + return res; +} + +/* + * Do the actual pushing, with only scalar or pseudo-scalar-array values + * accepted. + */ +static JsonbValue * +pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq, + JsonbValue *scalarVal) { JsonbValue *result = NULL; @@ -549,13 +585,11 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, appendKey(*pstate, scalarVal); break; case WJB_VALUE: - Assert(IsAJsonbScalar(scalarVal) || - scalarVal->type == jbvBinary); + Assert(IsAJsonbScalar(scalarVal)); appendValue(*pstate, scalarVal); break; case WJB_ELEM: - Assert(IsAJsonbScalar(scalarVal) || - scalarVal->type == jbvBinary); + Assert(IsAJsonbScalar(scalarVal)); appendElement(*pstate, scalarVal); break; case WJB_END_OBJECT: @@ -1197,6 +1231,7 @@ JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash) break; case jbvBool: tmp = scalarVal->val.boolean ? 0x02 : 0x04; + break; default: elog(ERROR, "invalid jsonb scalar type"); @@ -1270,7 +1305,7 @@ compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar) case jbvBool: if (aScalar->val.boolean == bScalar->val.boolean) return 0; - else if (aScalar->val.boolean > bScalar->val.boolean) + else if (aScalar->val.boolean >bScalar->val.boolean) return 1; else return -1; |