Skip to content

Commit eff4c3a

Browse files
author
Nikita Glukhov
committed
Add non-uniquified json values for improving compatibility with text jsons
1 parent 28c708e commit eff4c3a

File tree

9 files changed

+406
-100
lines changed

9 files changed

+406
-100
lines changed

src/backend/tsearch/wparser.c

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

405-
out = transform_jsonb_string_values(jb, state, action);
405+
out = transform_jsonb_string_values(jb, state, action, false);
406406

407407
/* flatten result to jsonb before jb freeing */
408408
res = JsonFlattenToJsonbDatum(out);
@@ -491,7 +491,7 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
491491
PG_FREE_IF_COPY(json, 1);
492492
#else
493493
{
494-
Jsonb *jsonb = transform_jsonb_string_values(json, state, action);
494+
Jsonb *jsonb = transform_jsonb_string_values(json, state, action, true);
495495
char *str = JsonToCString(&jsonb->root);
496496

497497
out = cstring_to_text(str);

src/backend/utils/adt/json_generic.c

Lines changed: 99 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
#include "utils/builtins.h"
1414
#include "utils/json_generic.h"
1515
#include "utils/memutils.h"
16+
#include "utils/builtins.h"
1617

17-
static JsonContainerOps jsonvContainerOps;
18+
JsonContainerOps jsonvContainerOps;
1819

1920
static Json *JsonExpand(Json *tmp, Datum value, bool freeValue,
2021
JsonContainerOps *ops);
2122

22-
2323
#if 0
2424
static JsonValue *
2525
JsonValueCopy(JsonValue *val)
@@ -214,10 +214,7 @@ jsonvScalarIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
214214
switch (sit->next)
215215
{
216216
case WJB_BEGIN_ARRAY:
217-
res->type = jbvArray;
218-
res->val.array.rawScalar = true;
219-
res->val.array.nElems = 1;
220-
res->val.array.elems = NULL;
217+
JsonValueInitArray(res, 1, 0, true, true);
221218
sit->next = WJB_ELEM;
222219
return WJB_BEGIN_ARRAY;
223220

@@ -275,6 +272,7 @@ jsonvArrayIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
275272
Assert(res->type == jbvArray || res->type == jbvObject);
276273
res->val.binary.data = JsonValueToContainer(val);
277274
res->val.binary.len = 0;
275+
res->val.binary.uniquified = JsonValueIsUniquified(val);
278276
res->type = jbvBinary;
279277
}
280278
}
@@ -327,6 +325,8 @@ jsonvObjectIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
327325
Assert(res->type == jbvArray || res->type == jbvObject);
328326
res->val.binary.data = JsonValueToContainer(&pair->value);
329327
res->val.binary.len = 0;
328+
res->val.binary.uniquified =
329+
JsonValueIsUniquified(&pair->value);
330330
res->type = jbvBinary;
331331
}
332332
}
@@ -420,7 +420,10 @@ static JsonValue *
420420
jsonvFindKeyInObject(JsonContainer *objc, const char *key, int len)
421421
{
422422
JsonValue *obj = (JsonValue *) objc->data;
423+
JsonValue *res;
424+
JsonValue *jv;
423425
int i;
426+
bool uniquified;
424427

425428
Assert(JsonContainerIsObject(objc));
426429

@@ -433,32 +436,41 @@ jsonvFindKeyInObject(JsonContainer *objc, const char *key, int len)
433436

434437
Assert(obj->type == jbvObject);
435438

439+
res = NULL;
440+
uniquified = obj->val.object.uniquified;
441+
436442
for (i = 0; i < obj->val.object.nPairs; i++)
437443
{
438444
JsonPair *pair = &obj->val.object.pairs[i];
439445
if (!lengthCompareJsonbString(key, len,
440446
pair->key.val.string.val,
441447
pair->key.val.string.len))
442448
{
443-
JsonValue *jv = palloc(sizeof(JsonValue));
449+
res = &pair->value;
444450

445-
if (pair->value.type == jbvObject ||
446-
pair->value.type == jbvArray)
447-
{ /* FIXME need to wrap containers into binary JsonValue */
448-
JsonContainer *jc = JsonValueToContainer(&pair->value);
451+
if (uniquified)
452+
break;
453+
}
454+
}
449455

450-
jv->type = jbvBinary;
451-
jv->val.binary.data = jc;
452-
jv->val.binary.len = jc->len;
453-
}
454-
else
455-
*jv = pair->value;
456+
if (!res)
457+
return NULL;
456458

457-
return jv; /* XXX palloced copy? */
458-
}
459+
jv = (JsonValue *) palloc(sizeof(JsonValue)); /* XXX palloced copy? */
460+
461+
if (res->type == jbvObject || res->type == jbvArray)
462+
{ /* FIXME need to wrap containers into binary JsonValue */
463+
JsonContainer *jc = JsonValueToContainer(res);
464+
465+
jv->type = jbvBinary;
466+
jv->val.binary.data = jc;
467+
jv->val.binary.len = jc->len;
468+
jv->val.binary.uniquified = JsonValueIsUniquified(res);
459469
}
470+
else
471+
*jv = *res;
460472

461-
return NULL;
473+
return jv;
462474
}
463475

464476
static JsonValue *
@@ -548,7 +560,7 @@ jsonvGetArraySize(JsonContainer *arrc)
548560
}
549561
}
550562

551-
static JsonContainerOps
563+
JsonContainerOps
552564
jsonvContainerOps =
553565
{
554566
JsonContainerJsonv,
@@ -573,6 +585,7 @@ JsonToJsonValue(Json *json, JsonValue *jv)
573585
jv->type = jbvBinary;
574586
jv->val.binary.data = &json->root;
575587
jv->val.binary.len = json->root.len;
588+
jv->val.binary.uniquified = json->root.ops != &jsontContainerOps;
576589

577590
return jv;
578591
}
@@ -677,6 +690,40 @@ JsonInit(Json *json)
677690
json->root.ops->init(&json->root, json->obj.value);
678691
}
679692

693+
static Size
694+
jsonGetFlatSizeJsont(Json *json, void **context)
695+
{
696+
Size size;
697+
698+
if (json->root.ops == &jsontContainerOps)
699+
size = VARHDRSZ + json->root.len;
700+
else
701+
{
702+
char *str = JsonToCString(&json->root);
703+
size = VARHDRSZ + strlen(str);
704+
if (context)
705+
*context = str;
706+
else
707+
pfree(str);
708+
}
709+
710+
return size;
711+
}
712+
713+
static void *
714+
jsonFlattenJsont(Json *json, void **context)
715+
{
716+
if (json->root.ops == &jsontContainerOps)
717+
return cstring_to_text_with_len(json->root.data, json->root.len);
718+
else
719+
{
720+
char *str = context ? (char *) *context : JsonToCString(JsonRoot(json));
721+
text *text = cstring_to_text(str);
722+
pfree(str);
723+
return text;
724+
}
725+
}
726+
680727
static Size
681728
jsonGetFlatSize2(Json *json, void **context)
682729
{
@@ -685,20 +732,8 @@ jsonGetFlatSize2(Json *json, void **context)
685732
#ifdef JSON_FLATTEN_INTO_TARGET
686733
if (json->is_json)
687734
#endif
688-
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSON)
689-
{
690-
if (json->root.ops == &jsontContainerOps)
691-
size = VARHDRSZ + json->root.len;
692-
else
693-
{
694-
char *str = JsonToCString(&json->root);
695-
size = VARHDRSZ + strlen(str);
696-
if (context)
697-
*context = str;
698-
else
699-
pfree(str);
700-
}
701-
}
735+
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSONT)
736+
size = jsonGetFlatSizeJsont(json, context);
702737
#endif
703738
#ifdef JSON_FLATTEN_INTO_TARGET
704739
else
@@ -729,18 +764,8 @@ jsonFlatten(Json *json, void **context)
729764
#ifdef JSON_FLATTEN_INTO_TARGET
730765
if (json->is_json)
731766
#endif
732-
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSON)
733-
{
734-
if (json->root.ops == &jsontContainerOps)
735-
return cstring_to_text_with_len(json->root.data, json->root.len);
736-
else
737-
{
738-
char *str = context ? (char *) *context : JsonToCString(JsonRoot(json));
739-
text *text = cstring_to_text(str);
740-
pfree(str);
741-
return text;
742-
}
743-
}
767+
#if defined(JSON_FLATTEN_INTO_TARGET) || defined(JSON_FLATTEN_INTO_JSONT)
768+
return jsonFlattenJsont(json, context);
744769
#endif
745770
#ifdef JSON_FLATTEN_INTO_TARGET
746771
else
@@ -779,9 +804,21 @@ jsonGetFlatSize(ExpandedObjectHeader *eoh, void **context)
779804

780805
if (json->root.ops == &jsonvContainerOps)
781806
{
807+
JsonValue *val = (JsonValue *) flat->data;
808+
809+
if (JsonValueIsUniquified(val))
810+
{
811+
tmp.len = jsonGetFlatSize2(json, context) - VARHDRSZ;
812+
tmp.ops = flatContainerOps;
813+
}
814+
else
815+
{
816+
tmp.len = jsonGetFlatSizeJsont(json, context) - VARHDRSZ;
817+
tmp.ops = &jsontContainerOps;
818+
}
819+
782820
tmp.data = NULL;
783-
tmp.ops = flatContainerOps;
784-
tmp.len = jsonGetFlatSize2(json, context) - VARHDRSZ;
821+
785822
flat = &tmp;
786823
}
787824

@@ -808,11 +845,21 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size,
808845

809846
if (flat->ops == &jsonvContainerOps)
810847
{
811-
tmpData = jsonFlatten(json, context);
848+
JsonValue *val = (JsonValue *) flat->data;
849+
850+
if (JsonValueIsUniquified(val))
851+
{
852+
tmpData = jsonFlatten(json, context);
853+
tmp.ops = flatContainerOps;
854+
}
855+
else
856+
{
857+
tmpData = jsonFlattenJsont(json, context);
858+
tmp.ops = &jsontContainerOps;
859+
}
812860

813-
tmp.ops = flatContainerOps;
814861
tmp.data = VARDATA(tmpData);
815-
tmp.len = VARSIZE_ANY_EXHDR(tmpData);
862+
tmp.len = VARSIZE(tmpData) - VARHDRSZ;
816863

817864
flat = &tmp;
818865
}

0 commit comments

Comments
 (0)