Skip to content

Commit 2798d1f

Browse files
author
Nikita Glukhov
committed
Fix json value wrapping in JsonFindKeyInObject()
1 parent 7bca449 commit 2798d1f

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

src/backend/utils/adt/json_generic.c

Lines changed: 16 additions & 11 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 JsonValue *key, bool last)
155171
{
@@ -570,17 +586,6 @@ jsonvFindKeyInObject(JsonContainer *objc, const JsonValue *key)
570586
}
571587
}
572588

573-
if (res && (res->type == jbvObject || res->type == jbvArray))
574-
{ /* FIXME need to wrap containers into binary JsonValue */
575-
JsonContainer *jc = JsonValueToContainer(res);
576-
JsonValue *jv = (JsonValue *) palloc(sizeof(JsonValue));
577-
jv->type = jbvBinary;
578-
jv->val.binary.data = jc;
579-
jv->val.binary.len = jc->len;
580-
jv->val.binary.uniquified = JsonValueIsUniquified(res);
581-
res = jv;
582-
}
583-
584589
return res;
585590
}
586591

src/backend/utils/adt/jsonb_util.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,12 +1219,16 @@ JsonbDeepContains(JsonContainer *cval, JsonContainer *ccont)
12191219
while ((rcont = JsonIteratorNext(&icont, &vcont, false)) == WJB_KEY)
12201220
{
12211221
/* First, find value by key in lhs object ... */
1222+
JsonbValue lhsValBuf;
12221223
JsonbValue *lhsVal = findJsonbValueFromContainer(cval, JB_FOBJECT,
12231224
&vcont);
12241225

12251226
if (!lhsVal)
12261227
return false;
12271228

1229+
if (lhsVal->type == jbvObject || lhsVal->type == jbvArray)
1230+
lhsVal = JsonValueWrapInBinary(lhsVal, &lhsValBuf);
1231+
12281232
/*
12291233
* ...at this stage it is apparent that there is at least a key
12301234
* match for this rhs pair.

src/backend/utils/adt/jsonfuncs.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,7 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
782782
Jsonb *jb = PG_GETARG_JSONB(0);
783783
text *key = PG_GETARG_TEXT_PP(1);
784784
JsonbValue *v;
785+
JsonbValue vbuf;
785786

786787
if (!JB_ROOT_IS_OBJECT(jb))
787788
PG_RETURN_NULL();
@@ -808,6 +809,10 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
808809
result = cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out,
809810
PointerGetDatum(v->val.numeric))));
810811
break;
812+
case jbvObject:
813+
case jbvArray:
814+
v = JsonValueWrapInBinary(v, &vbuf);
815+
/* fall through */
811816
case jbvBinary:
812817
{
813818
StringInfo jtext = makeStringInfo();
@@ -897,6 +902,7 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
897902
Jsonb *jb = PG_GETARG_JSONB(0);
898903
int element = PG_GETARG_INT32(1);
899904
JsonbValue *v;
905+
JsonbValue vbuf;
900906

901907
if (!JB_ROOT_IS_ARRAY(jb))
902908
PG_RETURN_NULL();
@@ -933,6 +939,10 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
933939
result = cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out,
934940
PointerGetDatum(v->val.numeric))));
935941
break;
942+
case jbvObject:
943+
case jbvArray:
944+
v = JsonValueWrapInBinary(v, &vbuf);
945+
/* fall through */
936946
case jbvBinary:
937947
{
938948
StringInfo jtext = makeStringInfo();
@@ -1563,6 +1573,8 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
15631573
{
15641574
have_object = jbvp->type == jbvObject;
15651575
have_array = jbvp->type == jbvArray;
1576+
if (have_object || have_array)
1577+
container = JsonValueToContainer(jbvp);
15661578
}
15671579
}
15681580

@@ -2759,6 +2771,8 @@ JsValueToJsObject(JsValue *jsv, JsObject *jso)
27592771
if (jbv->type == jbvBinary &&
27602772
JsonContainerIsObject(jbv->val.binary.data))
27612773
jso->val.jsonb_cont = jbv->val.binary.data;
2774+
else if (jbv->type == jbvObject)
2775+
jso->val.jsonb_cont = JsonValueToContainer(jbv);
27622776
else
27632777
{
27642778
bool is_scalar = IsAJsonbScalar(jbv) ||
@@ -2891,6 +2905,8 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv)
28912905
else if (jbv->type == jbvNumeric)
28922906
str = DatumGetCString(DirectFunctionCall1(numeric_out,
28932907
PointerGetDatum(jbv->val.numeric)));
2908+
else if (jbv->type == jbvObject || jbv->type == jbvArray)
2909+
str = JsonbToCString(NULL, JsonValueToContainer(jbv), 0);
28942910
else if (jbv->type == jbvBinary)
28952911
str = JsonbToCString(NULL, jbv->val.binary.data,
28962912
jbv->val.binary.len);

src/include/utils/json_generic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ extern JsonValue *JsonValueUnpackBinary(const JsonValue *jbv);
347347
extern JsonContainer *JsonValueToContainer(const JsonValue *val);
348348
extern JsonValue *JsonValueCopy(JsonValue *res, const JsonValue *val);
349349
extern const JsonValue *JsonValueUnwrap(const JsonValue *val, JsonValue *buf);
350+
extern JsonValue *JsonValueWrapInBinary(const JsonValue *val, JsonValue *bin);
350351
extern JsonContainer *JsonCopyFlat(JsonContainer *flatContainer);
351352
extern JsonValue *JsonExtractScalar(JsonContainer *jc, JsonValue *scalar);
352353

0 commit comments

Comments
 (0)