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
1920static Json * JsonExpand (Json * tmp , Datum value , bool freeValue ,
2021 JsonContainerOps * ops );
2122
22-
2323#if 0
2424static JsonValue *
2525JsonValueCopy (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 *
420420jsonvFindKeyInObject (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
464476static JsonValue *
@@ -548,7 +560,7 @@ jsonvGetArraySize(JsonContainer *arrc)
548560 }
549561}
550562
551- static JsonContainerOps
563+ JsonContainerOps
552564jsonvContainerOps =
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+
680727static Size
681728jsonGetFlatSize2 (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