Skip to content

Commit 28bedd9

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

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy