Skip to content

Commit 0cdfaaf

Browse files
author
Nikita Glukhov
committed
Add non-uniquified json values for improving compatibility with text jsons
1 parent f83c886 commit 0cdfaaf

File tree

9 files changed

+393
-98
lines changed

9 files changed

+393
-98
lines changed

src/backend/tsearch/wparser.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
407407
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
408408
errmsg("text search parser does not support headline creation")));
409409

410-
out = transform_jsonb_string_values(jb, state, action);
410+
out = transform_jsonb_string_values(jb, state, action, false);
411411

412412
/* flatten result to jsonb before jb freeing */
413413
out = DatumGetJsonb(PointerGetDatum(JsonValueToJsonb(JsonToJsonValue(out, &jv))));
@@ -495,7 +495,7 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
495495
PG_FREE_IF_COPY(json, 1);
496496
#else
497497
{
498-
Jsonb *jsonb = transform_jsonb_string_values(json, state, action);
498+
Jsonb *jsonb = transform_jsonb_string_values(json, state, action, true);
499499
char *str = JsonToCString(&jsonb->root);
500500

501501
out = cstring_to_text(str);

src/backend/utils/adt/json.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,7 @@ jsontFillValue(JsonIterator **pit, JsonValue *res, bool skipNested,
27692769
res->type = jbvBinary;
27702770
res->val.binary.len = 0;
27712771
res->val.binary.data = JsonContainerAlloc();
2772+
res->val.binary.uniquified = false;
27722773

27732774
if (skipNested)
27742775
{
@@ -2823,10 +2824,8 @@ JsontIteratorNext(JsonIterator **pit, JsonValue *val, bool skipNested)
28232824
switch (it->state)
28242825
{
28252826
case JTI_ARRAY_START:
2826-
val->type = jbvArray;
2827-
val->val.array.nElems = it->ji.container->size;
2828-
val->val.array.rawScalar = it->isScalar;
2829-
val->val.array.elems = NULL;
2827+
JsonValueInitArray(val, it->isScalar ? 1 : -1, 0, it->isScalar,
2828+
false);
28302829
it->state = it->isScalar ? JTI_ARRAY_ELEM_SCALAR : JTI_ARRAY_ELEM;
28312830
return WJB_BEGIN_ARRAY;
28322831

@@ -2871,9 +2870,7 @@ JsontIteratorNext(JsonIterator **pit, JsonValue *val, bool skipNested)
28712870
return WJB_ELEM;
28722871

28732872
case JTI_OBJECT_START:
2874-
val->type = jbvObject;
2875-
val->val.object.nPairs = -1;
2876-
val->val.object.pairs = NULL;
2873+
JsonValueInitObject(val, -1, 0, false);
28772874
it->state = JTI_OBJECT_KEY;
28782875
return WJB_BEGIN_OBJECT;
28792876

src/backend/utils/adt/json_generic.c

Lines changed: 94 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
#include "utils/builtins.h"
1313
#include "utils/json_generic.h"
1414
#include "utils/memutils.h"
15+
#include "utils/builtins.h"
1516

1617
static Json *JsonExpand(Json *tmp, Datum value, bool freeValue,
1718
JsonContainerOps *ops, CompressionOptions options);
1819

19-
static JsonContainerOps jsonvContainerOps;
20+
JsonContainerOps jsonvContainerOps;
2021

2122
#if 0
2223
static JsonValue *
@@ -210,10 +211,7 @@ jsonvScalarIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
210211
switch (sit->next)
211212
{
212213
case WJB_BEGIN_ARRAY:
213-
res->type = jbvArray;
214-
res->val.array.rawScalar = true;
215-
res->val.array.nElems = 1;
216-
res->val.array.elems = NULL;
214+
JsonValueInitArray(res, 1, 0, true, true);
217215
sit->next = WJB_ELEM;
218216
return WJB_BEGIN_ARRAY;
219217

@@ -271,6 +269,7 @@ jsonvArrayIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
271269
Assert(res->type == jbvArray || res->type == jbvObject);
272270
res->val.binary.data = JsonValueToContainer(val);
273271
res->val.binary.len = 0;
272+
res->val.binary.uniquified = JsonValueIsUniquified(val);
274273
res->type = jbvBinary;
275274
}
276275
}
@@ -323,6 +322,8 @@ jsonvObjectIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
323322
Assert(res->type == jbvArray || res->type == jbvObject);
324323
res->val.binary.data = JsonValueToContainer(&pair->value);
325324
res->val.binary.len = 0;
325+
res->val.binary.uniquified =
326+
JsonValueIsUniquified(&pair->value);
326327
res->type = jbvBinary;
327328
}
328329
}
@@ -416,7 +417,9 @@ static JsonValue *
416417
jsonvFindKeyInObject(JsonContainer *objc, const JsonValue *key)
417418
{
418419
JsonValue *obj = (JsonValue *) objc->data;
420+
JsonValue *res;
419421
int i;
422+
bool uniquified;
420423

421424
Assert(JsonContainerIsObject(objc));
422425
Assert(key->type == jbvString);
@@ -430,27 +433,34 @@ jsonvFindKeyInObject(JsonContainer *objc, const JsonValue *key)
430433

431434
Assert(obj->type == jbvObject);
432435

436+
res = NULL;
437+
uniquified = obj->val.object.uniquified;
438+
433439
for (i = 0; i < obj->val.object.nPairs; i++)
434440
{
435441
JsonPair *pair = &obj->val.object.pairs[i];
442+
436443
if (!lengthCompareJsonbStringValue(key, &pair->key))
437444
{
438-
if (pair->value.type == jbvObject ||
439-
pair->value.type == jbvArray)
440-
{ /* FIXME need to wrap containers into binary JsonValue */
441-
JsonContainer *jc = JsonValueToContainer(&pair->value);
442-
JsonValue *jv = (JsonValue *) palloc(sizeof(JsonValue));
443-
jv->type = jbvBinary;
444-
jv->val.binary.data = jc;
445-
jv->val.binary.len = jc->len;
446-
return jv;
447-
}
445+
res = &pair->value; /* FIXME palloced copy */
448446

449-
return &pair->value; /* FIXME palloced copy */
447+
if (uniquified)
448+
break;
450449
}
451450
}
452451

453-
return NULL;
452+
if (res && (res->type == jbvObject || res->type == jbvArray))
453+
{ /* FIXME need to wrap containers into binary JsonValue */
454+
JsonContainer *jc = JsonValueToContainer(res);
455+
JsonValue *jv = (JsonValue *) palloc(sizeof(JsonValue));
456+
jv->type = jbvBinary;
457+
jv->val.binary.data = jc;
458+
jv->val.binary.len = jc->len;
459+
jv->val.binary.uniquified = JsonValueIsUniquified(res);
460+
res = jv;
461+
}
462+
463+
return res;
454464
}
455465

456466
static JsonValue *
@@ -540,7 +550,7 @@ jsonvGetArraySize(JsonContainer *arrc)
540550
}
541551
}
542552

543-
static JsonContainerOps
553+
JsonContainerOps
544554
jsonvContainerOps =
545555
{
546556
JsonContainerJsonv,
@@ -566,6 +576,7 @@ JsonToJsonValue(Json *json, JsonValue *jv)
566576
jv->type = jbvBinary;
567577
jv->val.binary.data = &json->root;
568578
jv->val.binary.len = json->root.len;
579+
jv->val.binary.uniquified = json->root.ops != &jsontContainerOps;
569580

570581
return jv;
571582
}
@@ -698,6 +709,40 @@ JsonInit(Json *json)
698709
json->root.ops->init(&json->root, json->obj.value, json->obj.options);
699710
}
700711

712+
static Size
713+
jsonGetFlatSizeJsont(Json *json, void **context)
714+
{
715+
Size size;
716+
717+
if (json->root.ops == &jsontContainerOps)
718+
size = VARHDRSZ + json->root.len;
719+
else
720+
{
721+
char *str = JsonToCString(&json->root);
722+
size = VARHDRSZ + strlen(str);
723+
if (context)
724+
*context = str;
725+
else
726+
pfree(str);
727+
}
728+
729+
return size;
730+
}
731+
732+
static void *
733+
jsonFlattenJsont(Json *json, void **context)
734+
{
735+
if (json->root.ops == &jsontContainerOps)
736+
return cstring_to_text_with_len(json->root.data, json->root.len);
737+
else
738+
{
739+
char *str = context ? (char *) *context : JsonToCString(JsonRoot(json));
740+
text *text = cstring_to_text(str);
741+
pfree(str);
742+
return text;
743+
}
744+
}
745+
701746
static Size
702747
jsonGetFlatSize2(Json *json, void **context)
703748
{
@@ -706,20 +751,8 @@ jsonGetFlatSize2(Json *json, void **context)
706751
#ifdef JSON_FLATTEN_INTO_TARGET
707752
if (json->is_json)
708753
#endif
709-
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSON)
710-
{
711-
if (json->root.ops == &jsontContainerOps)
712-
size = VARHDRSZ + json->root.len;
713-
else
714-
{
715-
char *str = JsonToCString(&json->root);
716-
size = VARHDRSZ + strlen(str);
717-
if (context)
718-
*context = str;
719-
else
720-
pfree(str);
721-
}
722-
}
754+
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSONT)
755+
size = jsonGetFlatSizeJsont(json, context);
723756
#endif
724757
#ifdef JSON_FLATTEN_INTO_TARGET
725758
else
@@ -750,18 +783,8 @@ jsonFlatten(Json *json, void **context)
750783
#ifdef JSON_FLATTEN_INTO_TARGET
751784
if (json->is_json)
752785
#endif
753-
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSON)
754-
{
755-
if (json->root.ops == &jsontContainerOps)
756-
return cstring_to_text_with_len(json->root.data, json->root.len);
757-
else
758-
{
759-
char *str = context ? (char *) *context : JsonToCString(JsonRoot(json));
760-
text *text = cstring_to_text(str);
761-
pfree(str);
762-
return text;
763-
}
764-
}
786+
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSONT)
787+
return jsonFlattenJsont(json, context);
765788
#endif
766789
#ifdef JSON_FLATTEN_INTO_TARGET
767790
else
@@ -800,9 +823,21 @@ jsonGetFlatSize(ExpandedObjectHeader *eoh, void **context)
800823

801824
if (json->root.ops == &jsonvContainerOps)
802825
{
826+
JsonValue *val = (JsonValue *) flat->data;
827+
828+
if (JsonValueIsUniquified(val))
829+
{
830+
tmp.len = jsonGetFlatSize2(json, context) - VARHDRSZ;
831+
tmp.ops = flatContainerOps;
832+
}
833+
else
834+
{
835+
tmp.len = jsonGetFlatSizeJsont(json, context) - VARHDRSZ;
836+
tmp.ops = &jsontContainerOps;
837+
}
838+
803839
tmp.data = NULL;
804-
tmp.ops = flatContainerOps;
805-
tmp.len = jsonGetFlatSize2(json, context) - VARHDRSZ;
840+
806841
flat = &tmp;
807842
}
808843

@@ -829,11 +864,21 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size,
829864

830865
if (flat->ops == &jsonvContainerOps)
831866
{
832-
tmpData = jsonFlatten(json, context);
867+
JsonValue *val = (JsonValue *) flat->data;
868+
869+
if (JsonValueIsUniquified(val))
870+
{
871+
tmpData = jsonFlatten(json, context);
872+
tmp.ops = flatContainerOps;
873+
}
874+
else
875+
{
876+
tmpData = jsonFlattenJsont(json, context);
877+
tmp.ops = &jsontContainerOps;
878+
}
833879

834-
tmp.ops = flatContainerOps;
835880
tmp.data = VARDATA(tmpData);
836-
tmp.len = VARSIZE_ANY_EXHDR(tmpData);
881+
tmp.len = VARSIZE(tmpData) - VARHDRSZ;
837882

838883
flat = &tmp;
839884
}

0 commit comments

Comments
 (0)