10
10
11
11
#include "postgres.h"
12
12
13
+ #include "miscadmin.h"
13
14
#include "utils/builtins.h"
14
15
#include "utils/json_generic.h"
15
16
#include "utils/memutils.h"
@@ -19,16 +20,88 @@ static JsonContainerOps jsonvContainerOps;
19
20
static Json * JsonExpand (Json * tmp , Datum value , bool freeValue ,
20
21
JsonContainerOps * ops );
21
22
22
-
23
- #if 0
24
- static JsonValue *
25
- JsonValueCopy (JsonValue * val )
23
+ JsonValue *
24
+ JsonValueCopy (JsonValue * res , const JsonValue * val )
26
25
{
27
- JsonValue * copy = palloc (sizeof (JsonValue ));
28
- memcpy (copy , val , sizeof (JsonValue ));
29
- return copy ;
26
+ check_stack_depth ();
27
+
28
+ if (!res )
29
+ res = (JsonValue * ) palloc (sizeof (JsonValue ));
30
+
31
+ res -> type = val -> type ;
32
+
33
+ switch (val -> type )
34
+ {
35
+ case jbvNull :
36
+ break ;
37
+
38
+ case jbvBool :
39
+ res -> val .boolean = val -> val .boolean ;
40
+ break ;
41
+
42
+ case jbvString :
43
+ { /* copy string values in the current context */
44
+ char * buf = palloc (val -> val .string .len + 1 );
45
+ memcpy (buf , val -> val .string .val , val -> val .string .len );
46
+ buf [val -> val .string .len ] = 0 ;
47
+ res -> val .string .val = buf ;
48
+ res -> val .string .len = val -> val .string .len ;
49
+ break ;
50
+ }
51
+
52
+ case jbvNumeric :
53
+ /* same for numeric */
54
+ res -> val .numeric =
55
+ DatumGetNumeric (DirectFunctionCall1 (numeric_uplus ,
56
+ NumericGetDatum (val -> val .numeric )));
57
+ break ;
58
+
59
+ case jbvArray :
60
+ {
61
+ int i ;
62
+
63
+ res -> val .array = val -> val .array ;
64
+ res -> val .array .elems = (JsonValue * )
65
+ palloc (sizeof (JsonValue ) * val -> val .array .nElems );
66
+
67
+ for (i = 0 ; i < val -> val .array .nElems ; i ++ )
68
+ JsonValueCopy (& res -> val .array .elems [i ],
69
+ & val -> val .array .elems [i ]);
70
+
71
+ break ;
72
+ }
73
+
74
+ case jbvObject :
75
+ {
76
+ int i ;
77
+
78
+ res -> val .object = val -> val .object ;
79
+ res -> val .object .pairs = (JsonPair * )
80
+ palloc (sizeof (JsonPair ) * val -> val .object .nPairs );
81
+
82
+ for (i = 0 ; i < val -> val .object .nPairs ; i ++ )
83
+ {
84
+ res -> val .object .pairs [i ].order = val -> val .object .pairs [i ].order ;
85
+ JsonValueCopy (& res -> val .object .pairs [i ].key ,
86
+ & val -> val .object .pairs [i ].key );
87
+ JsonValueCopy (& res -> val .object .pairs [i ].value ,
88
+ & val -> val .object .pairs [i ].value );
89
+ }
90
+
91
+ break ;
92
+ }
93
+
94
+ case jbvBinary :
95
+ res -> val .binary = val -> val .binary ;
96
+ res -> val .binary .data = JsonCopy (val -> val .binary .data );
97
+ break ;
98
+
99
+ default :
100
+ elog (ERROR , "unknown json value type %d" , val -> type );
101
+ }
102
+
103
+ return res ;
30
104
}
31
- #endif
32
105
33
106
static inline JsonValue *
34
107
jsonFindKeyInObjectInternal (JsonContainer * obj , const char * key , int len ,
@@ -549,6 +622,17 @@ jsonvGetArraySize(JsonContainer *arrc)
549
622
}
550
623
}
551
624
625
+ static JsonContainer *
626
+ jsonvCopy (JsonContainer * jc )
627
+ {
628
+ JsonContainerData * res = JsonContainerAlloc ();
629
+
630
+ * res = * jc ;
631
+ res -> data = JsonValueCopy (NULL , (JsonValue * ) jc -> data );
632
+
633
+ return res ;
634
+ }
635
+
552
636
static JsonContainerOps
553
637
jsonvContainerOps =
554
638
{
@@ -559,6 +643,7 @@ jsonvContainerOps =
559
643
jsonvGetArrayElement ,
560
644
jsonvGetArraySize ,
561
645
JsonbToCStringRaw ,
646
+ jsonvCopy ,
562
647
};
563
648
564
649
JsonValue *
@@ -679,6 +764,18 @@ JsonValueToJson(JsonValue *val)
679
764
}
680
765
}
681
766
767
+ JsonContainer *
768
+ JsonCopyFlat (JsonContainer * jc )
769
+ {
770
+ JsonContainerData * res = JsonContainerAlloc ();
771
+
772
+ * res = * jc ;
773
+ res -> data = palloc (jc -> len );
774
+ memcpy (res -> data , jc -> data , jc -> len );
775
+
776
+ return res ;
777
+ }
778
+
682
779
JsonValue *
683
780
JsonContainerExtractKeys (JsonContainer * jsc )
684
781
{
0 commit comments