Skip to content

Commit f168b8b

Browse files
author
Nikita Glukhov
committed
Add JsonValueUnwrap(), JsonExtractScalar()
1 parent 611cdfe commit f168b8b

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

src/backend/utils/adt/json_generic.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,52 @@ JsonValueCopy(JsonValue *res, const JsonValue *val)
103103
return res;
104104
}
105105

106+
JsonValue *
107+
JsonExtractScalar(JsonContainer *jc, JsonValue *scalar)
108+
{
109+
JsonIterator *it;
110+
JsonValue val;
111+
112+
Assert(JsonContainerIsScalar(jc));
113+
114+
it = JsonIteratorInit(jc);
115+
116+
if (JsonIteratorNext(&it, &val, false) != WJB_BEGIN_ARRAY ||
117+
JsonIteratorNext(&it, scalar, false) != WJB_ELEM ||
118+
JsonIteratorNext(&it, &val, false) != WJB_END_ARRAY)
119+
elog(ERROR, "unexpected structure of scalar json container");
120+
121+
return scalar;
122+
}
123+
124+
const JsonValue *
125+
JsonValueUnwrap(const JsonValue *val, JsonValue *valbuf)
126+
{
127+
if (val->type == jbvBinary)
128+
{
129+
JsonContainer *jc = val->val.binary.data;
130+
131+
if (jc->ops == &jsonvContainerOps)
132+
{
133+
val = (JsonbValue *) jc->data;
134+
Assert(val->type != jbvBinary);
135+
}
136+
else if (JsonContainerIsScalar(jc))
137+
{
138+
val = JsonExtractScalar(jc, valbuf);
139+
Assert(IsAJsonbScalar(val));
140+
}
141+
}
142+
143+
if (val->type == jbvArray && val->val.array.rawScalar)
144+
{
145+
val = &val->val.array.elems[0];
146+
Assert(IsAJsonbScalar(val));
147+
}
148+
149+
return val;
150+
}
151+
106152
static inline JsonValue *
107153
jsonFindKeyInObjectInternal(JsonContainer *obj, const char *key, int len,
108154
bool last)

src/backend/utils/adt/jsonb.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -846,15 +846,10 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
846846
case JSONBTYPE_JSONB:
847847
{
848848
Jsonb *jsonb = DatumGetJsonbP(val);
849-
JsonbIterator *it;
850-
851-
it = JsonbIteratorInit(&jsonb->root);
852849

853850
if (JB_ROOT_IS_SCALAR(jsonb))
854851
{
855-
(void) JsonbIteratorNext(&it, &jb, true);
856-
Assert(jb.type == jbvArray);
857-
(void) JsonbIteratorNext(&it, &jb, true);
852+
JsonExtractScalar(&jsonb->root, &jb);
858853
break;
859854
}
860855

@@ -866,6 +861,7 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
866861
else
867862
{
868863
JsonbIteratorToken type;
864+
JsonbIterator *it = JsonbIteratorInit(&jsonb->root);
869865

870866
while ((type = JsonbIteratorNext(&it, &jb, false))
871867
!= WJB_DONE)

src/backend/utils/adt/jsonb_util.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,16 @@ pushJsonbValueExt(JsonbParseState **pstate, JsonbIteratorToken seq,
747747
jbval->type != jbvBinary || !unpackBinary)
748748
{
749749
/* drop through */
750+
if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE))
751+
jbval = JsonValueUnwrap(jbval, &v);
752+
753+
return pushJsonbValueScalar(pstate, seq, jbval);
754+
}
755+
756+
if (*pstate && JsonContainerIsScalar(jbval->val.binary.data))
757+
{
758+
jbval = JsonExtractScalar(jbval->val.binary.data, &v);
759+
Assert(IsAJsonbScalar(jbval));
750760
return pushJsonbValueScalar(pstate, seq, jbval);
751761
}
752762

src/include/utils/json_generic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ extern JsonValue *JsonToJsonValue(Json *json, JsonValue *jv);
271271
extern JsonValue *JsonValueUnpackBinary(const JsonValue *jbv);
272272
extern JsonContainer *JsonValueToContainer(const JsonValue *val);
273273
extern JsonValue *JsonValueCopy(JsonValue *res, const JsonValue *val);
274+
extern const JsonValue *JsonValueUnwrap(const JsonValue *val, JsonValue *buf);
274275
extern JsonContainer *JsonCopyFlat(JsonContainer *flatContainer);
276+
extern JsonValue *JsonExtractScalar(JsonContainer *jc, JsonValue *scalar);
275277

276278
extern Jsonb *JsonbMakeEmptyArray(void);
277279
extern Jsonb *JsonbMakeEmptyObject(void);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy