Skip to content

Commit 161c89b

Browse files
author
Nikita Glukhov
committed
Fix json value wrapping in JsonFindKeyInObject()
1 parent 48c1aee commit 161c89b

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)