13
13
#include "utils/builtins.h"
14
14
#include "utils/json_generic.h"
15
15
#include "utils/memutils.h"
16
+ #include "utils/builtins.h"
16
17
17
- static JsonContainerOps jsonvContainerOps ;
18
+ JsonContainerOps jsonvContainerOps ;
18
19
19
20
static Json * JsonExpand (Json * tmp , Datum value , bool freeValue ,
20
21
JsonContainerOps * ops );
21
22
22
-
23
23
#if 0
24
24
static JsonValue *
25
25
JsonValueCopy (JsonValue * val )
@@ -214,10 +214,7 @@ jsonvScalarIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
214
214
switch (sit -> next )
215
215
{
216
216
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);
221
218
sit -> next = WJB_ELEM ;
222
219
return WJB_BEGIN_ARRAY ;
223
220
@@ -275,6 +272,7 @@ jsonvArrayIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
275
272
Assert (res -> type == jbvArray || res -> type == jbvObject );
276
273
res -> val .binary .data = JsonValueToContainer (val );
277
274
res -> val .binary .len = 0 ;
275
+ res -> val .binary .uniquified = JsonValueIsUniquified (val );
278
276
res -> type = jbvBinary ;
279
277
}
280
278
}
@@ -327,6 +325,8 @@ jsonvObjectIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
327
325
Assert (res -> type == jbvArray || res -> type == jbvObject );
328
326
res -> val .binary .data = JsonValueToContainer (& pair -> value );
329
327
res -> val .binary .len = 0 ;
328
+ res -> val .binary .uniquified =
329
+ JsonValueIsUniquified (& pair -> value );
330
330
res -> type = jbvBinary ;
331
331
}
332
332
}
@@ -420,7 +420,10 @@ static JsonValue *
420
420
jsonvFindKeyInObject (JsonContainer * objc , const char * key , int len )
421
421
{
422
422
JsonValue * obj = (JsonValue * ) objc -> data ;
423
+ JsonValue * res ;
424
+ JsonValue * jv ;
423
425
int i ;
426
+ bool uniquified ;
424
427
425
428
Assert (JsonContainerIsObject (objc ));
426
429
@@ -433,32 +436,41 @@ jsonvFindKeyInObject(JsonContainer *objc, const char *key, int len)
433
436
434
437
Assert (obj -> type == jbvObject );
435
438
439
+ res = NULL ;
440
+ uniquified = obj -> val .object .uniquified ;
441
+
436
442
for (i = 0 ; i < obj -> val .object .nPairs ; i ++ )
437
443
{
438
444
JsonPair * pair = & obj -> val .object .pairs [i ];
439
445
if (!lengthCompareJsonbString (key , len ,
440
446
pair -> key .val .string .val ,
441
447
pair -> key .val .string .len ))
442
448
{
443
- JsonValue * jv = palloc ( sizeof ( JsonValue )) ;
449
+ res = & pair -> value ;
444
450
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
+ }
449
455
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 ;
456
458
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 );
459
469
}
470
+ else
471
+ * jv = * res ;
460
472
461
- return NULL ;
473
+ return jv ;
462
474
}
463
475
464
476
static JsonValue *
@@ -548,7 +560,7 @@ jsonvGetArraySize(JsonContainer *arrc)
548
560
}
549
561
}
550
562
551
- static JsonContainerOps
563
+ JsonContainerOps
552
564
jsonvContainerOps =
553
565
{
554
566
JsonContainerJsonv ,
@@ -573,6 +585,7 @@ JsonToJsonValue(Json *json, JsonValue *jv)
573
585
jv -> type = jbvBinary ;
574
586
jv -> val .binary .data = & json -> root ;
575
587
jv -> val .binary .len = json -> root .len ;
588
+ jv -> val .binary .uniquified = json -> root .ops != & jsontContainerOps ;
576
589
577
590
return jv ;
578
591
}
@@ -677,6 +690,40 @@ JsonInit(Json *json)
677
690
json -> root .ops -> init (& json -> root , json -> obj .value );
678
691
}
679
692
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
+
680
727
static Size
681
728
jsonGetFlatSize2 (Json * json , void * * context )
682
729
{
@@ -685,20 +732,8 @@ jsonGetFlatSize2(Json *json, void **context)
685
732
#ifdef JSON_FLATTEN_INTO_TARGET
686
733
if (json -> is_json )
687
734
#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 );
702
737
#endif
703
738
#ifdef JSON_FLATTEN_INTO_TARGET
704
739
else
@@ -729,18 +764,8 @@ jsonFlatten(Json *json, void **context)
729
764
#ifdef JSON_FLATTEN_INTO_TARGET
730
765
if (json -> is_json )
731
766
#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 );
744
769
#endif
745
770
#ifdef JSON_FLATTEN_INTO_TARGET
746
771
else
@@ -779,9 +804,21 @@ jsonGetFlatSize(ExpandedObjectHeader *eoh, void **context)
779
804
780
805
if (json -> root .ops == & jsonvContainerOps )
781
806
{
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
+
782
820
tmp .data = NULL ;
783
- tmp .ops = flatContainerOps ;
784
- tmp .len = jsonGetFlatSize2 (json , context ) - VARHDRSZ ;
821
+
785
822
flat = & tmp ;
786
823
}
787
824
@@ -808,11 +845,21 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size,
808
845
809
846
if (flat -> ops == & jsonvContainerOps )
810
847
{
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
+ }
812
860
813
- tmp .ops = flatContainerOps ;
814
861
tmp .data = VARDATA (tmpData );
815
- tmp .len = VARSIZE_ANY_EXHDR (tmpData );
862
+ tmp .len = VARSIZE (tmpData ) - VARHDRSZ ;
816
863
817
864
flat = & tmp ;
818
865
}
0 commit comments