Skip to content

Commit ea90961

Browse files
author
Nikita Glukhov
committed
Fix json value wrapping in JsonFindKeyInObject()
1 parent 1f8928c commit ea90961

File tree

4 files changed

+39
-15
lines changed

4 files changed

+39
-15
lines changed

src/backend/utils/adt/json_generic.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,22 @@ JsonValueUnwrap(const JsonValue *val, JsonValue *valbuf)
150150
return val;
151151
}
152152

153+
JsonValue *
154+
JsonValueWrapInBinary(const JsonValue *val, JsonValue *bin)
155+
{
156+
JsonContainer *jc = JsonValueToContainer(val);
157+
158+
if (!bin)
159+
bin = (JsonValue *) palloc(sizeof(JsonValue));
160+
161+
bin->type = jbvBinary;
162+
bin->val.binary.data = jc;
163+
bin->val.binary.len = jc->len;
164+
bin->val.binary.uniquified = JsonValueIsUniquified(val);
165+
166+
return bin;
167+
}
168+
153169
static inline JsonValue *
154170
jsonFindKeyInObjectInternal(JsonContainer *obj, const char *key, int len,
155171
bool last)
@@ -577,18 +593,7 @@ jsonvFindKeyInObject(JsonContainer *objc, const char *key, int len)
577593
return NULL;
578594

579595
jv = (JsonValue *) palloc(sizeof(JsonValue)); /* XXX palloced copy? */
580-
581-
if (res->type == jbvObject || res->type == jbvArray)
582-
{ /* FIXME need to wrap containers into binary JsonValue */
583-
JsonContainer *jc = JsonValueToContainer(res);
584-
585-
jv->type = jbvBinary;
586-
jv->val.binary.data = jc;
587-
jv->val.binary.len = jc->len;
588-
jv->val.binary.uniquified = JsonValueIsUniquified(res);
589-
}
590-
else
591-
*jv = *res;
596+
*jv = *res;
592597

593598
return jv;
594599
}

src/backend/utils/adt/jsonb_util.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,13 +1250,17 @@ JsonbDeepContains(JsonContainer *cval, JsonContainer *ccont)
12501250
while ((rcont = JsonIteratorNext(&icont, &vcont, false)) == WJB_KEY)
12511251
{
12521252
/* First, find value by key in lhs object ... */
1253+
JsonbValue lhsValBuf;
12531254
JsonbValue *lhsVal = JsonFindKeyInObject(cval,
12541255
vcont.val.string.val,
12551256
vcont.val.string.len);
12561257

12571258
if (!lhsVal)
12581259
return false;
12591260

1261+
if (lhsVal->type == jbvObject || lhsVal->type == jbvArray)
1262+
lhsVal = JsonValueWrapInBinary(lhsVal, &lhsValBuf);
1263+
12601264
/*
12611265
* ...at this stage it is apparent that there is at least a key
12621266
* match for this rhs pair.

src/backend/utils/adt/jsonfuncs.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,9 +1635,10 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
16351635
}
16361636
else
16371637
{
1638-
Assert(IsAJsonbScalar(jbvp));
1639-
have_object = false;
1640-
have_array = false;
1638+
have_object = jbvp->type == jbvObject;
1639+
have_array = jbvp->type == jbvArray;
1640+
if (have_object || have_array)
1641+
container = JsonValueToContainer(jbvp);
16411642
}
16421643
}
16431644

@@ -1663,6 +1664,8 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
16631664
static text *
16641665
JsonbValueAsText(JsonbValue *v)
16651666
{
1667+
JsonbValue vbuf;
1668+
16661669
switch (v->type)
16671670
{
16681671
case jbvNull:
@@ -1687,6 +1690,11 @@ JsonbValueAsText(JsonbValue *v)
16871690
return cstring_to_text(DatumGetCString(cstr));
16881691
}
16891692

1693+
case jbvObject:
1694+
case jbvArray:
1695+
v = JsonValueWrapInBinary(v, &vbuf);
1696+
/* fall through */
1697+
16901698
case jbvBinary:
16911699
{
16921700
StringInfoData jtext;
@@ -2842,6 +2850,10 @@ JsValueToJsObject(JsValue *jsv, JsObject *jso)
28422850
{
28432851
jso->val.jsonb_cont = jbv->val.binary.data;
28442852
}
2853+
else if (jbv->type == jbvObject)
2854+
{
2855+
jso->val.jsonb_cont = JsonValueToContainer(jbv);
2856+
}
28452857
else
28462858
{
28472859
bool is_scalar;
@@ -2996,6 +3008,8 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv)
29963008
else if (jbv->type == jbvNumeric)
29973009
str = DatumGetCString(DirectFunctionCall1(numeric_out,
29983010
PointerGetDatum(jbv->val.numeric)));
3011+
else if (jbv->type == jbvObject || jbv->type == jbvArray)
3012+
str = JsonbToCString(NULL, JsonValueToContainer(jbv), 0);
29993013
else if (jbv->type == jbvBinary)
30003014
str = JsonbToCString(NULL, jbv->val.binary.data,
30013015
jbv->val.binary.len);

src/include/utils/json_generic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ extern JsonValue *JsonValueUnpackBinary(const JsonValue *jbv);
361361
extern JsonContainer *JsonValueToContainer(const JsonValue *val);
362362
extern JsonValue *JsonValueCopy(JsonValue *res, const JsonValue *val);
363363
extern const JsonValue *JsonValueUnwrap(const JsonValue *val, JsonValue *buf);
364+
extern JsonValue *JsonValueWrapInBinary(const JsonValue *val, JsonValue *bin);
364365
extern JsonContainer *JsonCopyFlat(JsonContainer *flatContainer);
365366
extern JsonValue *JsonExtractScalar(JsonContainer *jc, JsonValue *scalar);
366367

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