Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0a3f747

Browse files
author
Nikita Glukhov
committed
Fix json value wrapping in JsonFindKeyInObject()
1 parent ff8ba39 commit 0a3f747

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
@@ -1313,13 +1313,17 @@ JsonbDeepContains(JsonContainer *cval, JsonContainer *ccont)
13131313
while ((rcont = JsonIteratorNext(&icont, &vcont, false)) == WJB_KEY)
13141314
{
13151315
/* First, find value by key in lhs object ... */
1316+
JsonbValue lhsValBuf;
13161317
JsonbValue *lhsVal = JsonFindKeyInObject(cval,
13171318
vcont.val.string.val,
13181319
vcont.val.string.len);
13191320

13201321
if (!lhsVal)
13211322
return false;
13221323

1324+
if (lhsVal->type == jbvObject || lhsVal->type == jbvArray)
1325+
lhsVal = JsonValueWrapInBinary(lhsVal, &lhsValBuf);
1326+
13231327
/*
13241328
* ...at this stage it is apparent that there is at least a key
13251329
* 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
@@ -1651,9 +1651,10 @@ jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
16511651
}
16521652
else
16531653
{
1654-
Assert(IsAJsonbScalar(jbvp));
1655-
have_object = false;
1656-
have_array = false;
1654+
have_object = jbvp->type == jbvObject;
1655+
have_array = jbvp->type == jbvArray;
1656+
if (have_object || have_array)
1657+
container = JsonValueToContainer(jbvp);
16571658
}
16581659
}
16591660

@@ -1805,6 +1806,8 @@ push_path(JsonbParseState **st, int level, Datum *path_elems,
18051806
static text *
18061807
JsonbValueAsText(JsonbValue *v)
18071808
{
1809+
JsonbValue vbuf;
1810+
18081811
switch (v->type)
18091812
{
18101813
case jbvNull:
@@ -1829,6 +1832,11 @@ JsonbValueAsText(JsonbValue *v)
18291832
return cstring_to_text(DatumGetCString(cstr));
18301833
}
18311834

1835+
case jbvObject:
1836+
case jbvArray:
1837+
v = JsonValueWrapInBinary(v, &vbuf);
1838+
/* fall through */
1839+
18321840
case jbvBinary:
18331841
{
18341842
StringInfoData jtext;
@@ -2984,6 +2992,10 @@ JsValueToJsObject(JsValue *jsv, JsObject *jso)
29842992
{
29852993
jso->val.jsonb_cont = jbv->val.binary.data;
29862994
}
2995+
else if (jbv->type == jbvObject)
2996+
{
2997+
jso->val.jsonb_cont = JsonValueToContainer(jbv);
2998+
}
29872999
else
29883000
{
29893001
bool is_scalar;
@@ -3138,6 +3150,8 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv)
31383150
else if (jbv->type == jbvNumeric)
31393151
str = DatumGetCString(DirectFunctionCall1(numeric_out,
31403152
PointerGetDatum(jbv->val.numeric)));
3153+
else if (jbv->type == jbvObject || jbv->type == jbvArray)
3154+
str = JsonbToCString(NULL, JsonValueToContainer(jbv), 0);
31413155
else if (jbv->type == jbvBinary)
31423156
str = JsonbToCString(NULL, jbv->val.binary.data,
31433157
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)