13
13
#include "utils/json_generic.h"
14
14
#include "utils/memutils.h"
15
15
16
- static JsonContainerOps jsonvContainerOps ;
16
+ static Json * JsonExpand (Datum value , JsonContainerOps * ops ,
17
+ CompressionOptions opts );
17
18
18
- static Json * JsonExpand ( Datum value , JsonContainerOps * ops ) ;
19
+ static JsonContainerOps jsonvContainerOps ;
19
20
20
21
#if 0
21
22
static JsonValue *
@@ -544,6 +545,7 @@ jsonvContainerOps =
544
545
{
545
546
JsonContainerJsonv ,
546
547
NULL ,
548
+ NULL ,
547
549
jsonvIteratorInit ,
548
550
jsonvFindKeyInObject ,
549
551
jsonvFindValueInArray ,
@@ -577,20 +579,24 @@ typedef struct varatt_extended_json
577
579
{
578
580
varatt_extended_hdr vaext ;
579
581
JsonContainerType type ;
580
- char params [FLEXIBLE_ARRAY_MEMBER ];
582
+ char data [FLEXIBLE_ARRAY_MEMBER ];
581
583
} varatt_extended_json ;
582
584
583
585
static Size
584
586
jsonGetExtendedSize (JsonContainer * jc )
585
587
{
586
- return VARHDRSZ_EXTERNAL + offsetof(varatt_extended_json , params ) + jc -> len ;
588
+ return VARHDRSZ_EXTERNAL + offsetof(varatt_extended_json , data ) +
589
+ VARHDRSZ + jc -> len +
590
+ (jc -> ops -> compressionOps ?
591
+ jc -> ops -> compressionOps -> encodeOptions (jc , NULL ) : 0 );
587
592
}
588
593
589
594
static void
590
595
jsonWriteExtended (JsonContainer * jc , void * ptr , Size allocated_size )
591
596
{
592
597
varatt_extended_json extjs ,
593
598
* pextjs ;
599
+ Size optionsSize ;
594
600
595
601
Assert (allocated_size >= jsonGetExtendedSize (jc ));
596
602
@@ -600,8 +606,13 @@ jsonWriteExtended(JsonContainer *jc, void *ptr, Size allocated_size)
600
606
601
607
SET_VARTAG_EXTERNAL (ptr , VARTAG_EXTENDED );
602
608
pextjs = (varatt_extended_json * ) VARDATA_EXTERNAL (ptr );
603
- memcpy (pextjs , & extjs , offsetof(varatt_extended_json , params ));
604
- memcpy (& pextjs -> params , jc -> data , jc -> len );
609
+ memcpy (pextjs , & extjs , offsetof(varatt_extended_json , data ));
610
+
611
+ optionsSize = jc -> ops -> compressionOps ?
612
+ jc -> ops -> compressionOps -> encodeOptions (jc , & pextjs -> data ) : 0 ;
613
+
614
+ SET_VARSIZE (& pextjs -> data [optionsSize ], VARHDRSZ + jc -> len );
615
+ memcpy (VARDATA (& pextjs -> data [optionsSize ]), jc -> data , jc -> len );
605
616
}
606
617
607
618
static Json *
@@ -612,37 +623,51 @@ JsonInitExtended(const struct varlena *toasted,
612
623
CompressionMethodRoutine * cmr ;
613
624
varatt_extended_json * pextjs ,
614
625
extjs ;
615
- void * val ;
616
- int len ;
617
626
Datum value ;
627
+ CompressionOptions options ;
628
+ Size totalSize ;
629
+ Size optionsSize ;
630
+ Size (* decodeOptions )(const void * buf ,
631
+ CompressionOptions * options );
618
632
619
633
Assert (VARATT_IS_EXTERNAL_EXTENDED (detoasted ));
620
634
621
635
pextjs = (varatt_extended_json * ) VARDATA_EXTERNAL (detoasted );
622
- memcpy (& extjs , pextjs , offsetof(varatt_extended_json , params ));
636
+ memcpy (& extjs , pextjs , offsetof(varatt_extended_json , data ));
637
+
638
+ totalSize = extjs .vaext .size - offsetof(varatt_extended_json , data );
623
639
624
640
ops = JsonContainerGetOpsByType (extjs .type );
625
641
626
642
if (ops )
643
+ {
627
644
cmr = NULL ;
645
+ decodeOptions = ops -> compressionOps ?
646
+ ops -> compressionOps -> decodeOptions : NULL ;
647
+ }
628
648
else
629
649
{
630
650
cmr = GetCompressionMethodRoutine (extjs .type , InvalidOid );
631
651
632
652
if (!cmr )
633
653
elog (ERROR , "unrecognized json container type %d" , extjs .type );
654
+
655
+ decodeOptions = cmr -> options ? cmr -> options -> decode : NULL ;
634
656
}
635
657
636
- len = extjs . vaext . size - offsetof( varatt_extended_json , params ) ;
658
+ optionsSize = decodeOptions ? decodeOptions ( & pextjs -> data , & options ) : 0 ;
637
659
638
- val = palloc (VARHDRSZ + len ); /* FIXME save value with varlena header */
639
- SET_VARSIZE (val , VARHDRSZ + len );
640
- memcpy (VARDATA (val ), & pextjs -> params , len );
660
+ /* FIXME alignment
661
+ * value = PointerGetDatum(&pextjs->data[optionsSize]);
662
+ */
663
+ value = PointerGetDatum (memcpy (palloc (totalSize - optionsSize ),
664
+ & pextjs -> data [optionsSize ],
665
+ totalSize - optionsSize ));
641
666
642
667
if (ops )
643
- return JsonExpand (PointerGetDatum ( val ) , ops );
668
+ return JsonExpand (value , ops , options );
644
669
645
- value = cmr -> decompress (PointerGetDatum ( val ), NULL );
670
+ value = cmr -> decompress (value , options );
646
671
647
672
Assert (VARATT_IS_EXTERNAL_EXPANDED (DatumGetPointer (value )));
648
673
@@ -665,7 +690,7 @@ JsonInit(Json *json)
665
690
Assert (!VARATT_IS_EXTERNAL_EXTENDED (data ));
666
691
json -> obj .compressed = PointerGetDatum (data );
667
692
668
- ( * json -> root .ops -> init ) (& json -> root , json -> obj .compressed );
693
+ json -> root .ops -> init (& json -> root , json -> obj .compressed , json -> obj . options );
669
694
}
670
695
671
696
static Size
@@ -822,7 +847,7 @@ jsonExpandedObjectMethods =
822
847
};
823
848
824
849
static Json *
825
- JsonExpand (Datum value , JsonContainerOps * ops )
850
+ JsonExpand (Datum value , JsonContainerOps * ops , CompressionOptions options )
826
851
{
827
852
MemoryContext objcxt ;
828
853
Json * json ;
@@ -843,6 +868,7 @@ JsonExpand(Datum value, JsonContainerOps *ops)
843
868
EOH_init_header (& json -> obj .eoh , & jsonExpandedObjectMethods , objcxt );
844
869
845
870
json -> obj .compressed = value ;
871
+ json -> obj .options = options ;
846
872
json -> root .data = NULL ;
847
873
json -> root .len = 0 ;
848
874
json -> root .ops = ops ;
@@ -853,8 +879,8 @@ JsonExpand(Datum value, JsonContainerOps *ops)
853
879
return json ;
854
880
}
855
881
856
- Json *
857
- DatumGetJson (Datum value , JsonContainerOps * ops )
882
+ static Json *
883
+ JsonExpandDatum (Datum value , JsonContainerOps * ops , CompressionOptions options )
858
884
{
859
885
struct varlena * toasted = (struct varlena * ) DatumGetPointer (value );
860
886
Json * json ;
@@ -872,11 +898,17 @@ DatumGetJson(Datum value, JsonContainerOps *ops)
872
898
elog (ERROR , "unexpected extended json" );
873
899
#endif
874
900
875
- json = JsonExpand (PointerGetDatum (detoasted ), ops );
901
+ json = JsonExpand (PointerGetDatum (detoasted ), ops , options );
876
902
}
877
903
878
- JsonInit (json );
904
+ return json ;
905
+ }
879
906
907
+ Json *
908
+ DatumGetJson (Datum value , JsonContainerOps * ops , CompressionOptions options )
909
+ {
910
+ Json * json = JsonExpandDatum (value , ops , options );
911
+ JsonInit (json );
880
912
return json ;
881
913
}
882
914
@@ -885,13 +917,14 @@ JsonValueToJson(JsonValue *val)
885
917
{
886
918
if (val -> type == jbvBinary )
887
919
{
888
- Json * json = JsonExpand (PointerGetDatum (NULL ), NULL );
889
- json -> root = * val -> val .binary .data ;
920
+ JsonContainer * jc = val -> val .binary .data ;
921
+ Json * json = JsonExpand (PointerGetDatum (NULL ), jc -> ops , NULL );
922
+ json -> root = * jc ;
890
923
return json ;
891
924
}
892
925
else
893
926
{
894
- Json * json = JsonExpand (PointerGetDatum (NULL ), & jsonvContainerOps );
927
+ Json * json = JsonExpand (PointerGetDatum (NULL ), & jsonvContainerOps , NULL );
895
928
jsonvInitContainer (& json -> root , val );
896
929
return json ;
897
930
}
0 commit comments