12
12
#include "utils/builtins.h"
13
13
#include "utils/json_generic.h"
14
14
#include "utils/memutils.h"
15
+ #include "utils/builtins.h"
15
16
16
17
static Json * JsonExpand (Json * tmp ,Datum value ,bool freeValue ,
17
18
JsonContainerOps * ops ,CompressionOptions options );
18
19
19
- static JsonContainerOps jsonvContainerOps ;
20
+ JsonContainerOps jsonvContainerOps ;
20
21
21
22
#if 0
22
23
static JsonValue *
@@ -210,10 +211,7 @@ jsonvScalarIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
210
211
switch (sit -> next )
211
212
{
212
213
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);
217
215
sit -> next = WJB_ELEM ;
218
216
return WJB_BEGIN_ARRAY ;
219
217
@@ -271,6 +269,7 @@ jsonvArrayIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
271
269
Assert (res -> type == jbvArray || res -> type == jbvObject );
272
270
res -> val .binary .data = JsonValueToContainer (val );
273
271
res -> val .binary .len = 0 ;
272
+ res -> val .binary .uniquified = JsonValueIsUniquified (val );
274
273
res -> type = jbvBinary ;
275
274
}
276
275
}
@@ -323,6 +322,8 @@ jsonvObjectIteratorNext(JsonIterator **it, JsonValue *res, bool skipNested)
323
322
Assert (res -> type == jbvArray || res -> type == jbvObject );
324
323
res -> val .binary .data = JsonValueToContainer (& pair -> value );
325
324
res -> val .binary .len = 0 ;
325
+ res -> val .binary .uniquified =
326
+ JsonValueIsUniquified (& pair -> value );
326
327
res -> type = jbvBinary ;
327
328
}
328
329
}
@@ -416,7 +417,9 @@ static JsonValue *
416
417
jsonvFindKeyInObject (JsonContainer * objc ,const JsonValue * key )
417
418
{
418
419
JsonValue * obj = (JsonValue * )objc -> data ;
420
+ JsonValue * res ;
419
421
int i ;
422
+ bool uniquified ;
420
423
421
424
Assert (JsonContainerIsObject (objc ));
422
425
Assert (key -> type == jbvString );
@@ -430,27 +433,34 @@ jsonvFindKeyInObject(JsonContainer *objc, const JsonValue *key)
430
433
431
434
Assert (obj -> type == jbvObject );
432
435
436
+ res = NULL ;
437
+ uniquified = obj -> val .object .uniquified ;
438
+
433
439
for (i = 0 ;i < obj -> val .object .nPairs ;i ++ )
434
440
{
435
441
JsonPair * pair = & obj -> val .object .pairs [i ];
442
+
436
443
if (!lengthCompareJsonbStringValue (key ,& pair -> key ))
437
444
{
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 */
448
446
449
- return & pair -> value ;/* FIXME palloced copy */
447
+ if (uniquified )
448
+ break ;
450
449
}
451
450
}
452
451
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 ;
454
464
}
455
465
456
466
static JsonValue *
@@ -540,7 +550,7 @@ jsonvGetArraySize(JsonContainer *arrc)
540
550
}
541
551
}
542
552
543
- static JsonContainerOps
553
+ JsonContainerOps
544
554
jsonvContainerOps =
545
555
{
546
556
JsonContainerJsonv ,
@@ -566,6 +576,7 @@ JsonToJsonValue(Json *json, JsonValue *jv)
566
576
jv -> type = jbvBinary ;
567
577
jv -> val .binary .data = & json -> root ;
568
578
jv -> val .binary .len = json -> root .len ;
579
+ jv -> val .binary .uniquified = json -> root .ops != & jsontContainerOps ;
569
580
570
581
return jv ;
571
582
}
@@ -698,6 +709,40 @@ JsonInit(Json *json)
698
709
json -> root .ops -> init (& json -> root ,json -> obj .value ,json -> obj .options );
699
710
}
700
711
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
+
701
746
static Size
702
747
jsonGetFlatSize2 (Json * json ,void * * context )
703
748
{
@@ -706,20 +751,8 @@ jsonGetFlatSize2(Json *json, void **context)
706
751
#ifdef JSON_FLATTEN_INTO_TARGET
707
752
if (json -> is_json )
708
753
#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 );
723
756
#endif
724
757
#ifdef JSON_FLATTEN_INTO_TARGET
725
758
else
@@ -750,18 +783,8 @@ jsonFlatten(Json *json, void **context)
750
783
#ifdef JSON_FLATTEN_INTO_TARGET
751
784
if (json -> is_json )
752
785
#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 );
765
788
#endif
766
789
#ifdef JSON_FLATTEN_INTO_TARGET
767
790
else
@@ -800,9 +823,21 @@ jsonGetFlatSize(ExpandedObjectHeader *eoh, void **context)
800
823
801
824
if (json -> root .ops == & jsonvContainerOps )
802
825
{
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
+
803
839
tmp .data = NULL ;
804
- tmp .ops = flatContainerOps ;
805
- tmp .len = jsonGetFlatSize2 (json ,context )- VARHDRSZ ;
840
+
806
841
flat = & tmp ;
807
842
}
808
843
@@ -829,11 +864,21 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size,
829
864
830
865
if (flat -> ops == & jsonvContainerOps )
831
866
{
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
+ }
833
879
834
- tmp .ops = flatContainerOps ;
835
880
tmp .data = VARDATA (tmpData );
836
- tmp .len = VARSIZE_ANY_EXHDR (tmpData );
881
+ tmp .len = VARSIZE (tmpData )- VARHDRSZ ;
837
882
838
883
flat = & tmp ;
839
884
}