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"
@@ -20,15 +21,88 @@ JsonContainerOps jsonvContainerOps;
20
21
static Json * JsonExpand (Json * tmp , Datum value , bool freeValue ,
21
22
JsonContainerOps * ops );
22
23
23
- #if 0
24
- static JsonValue *
25
- JsonValueCopy (JsonValue * val )
24
+ JsonValue *
25
+ JsonValueCopy (JsonValue * res , const JsonValue * val )
26
26
{
27
- JsonValue * copy = palloc (sizeof (JsonValue ));
28
- memcpy (copy , val , sizeof (JsonValue ));
29
- return copy ;
27
+ check_stack_depth ();
28
+
29
+ if (!res )
30
+ res = (JsonValue * ) palloc (sizeof (JsonValue ));
31
+
32
+ res -> type = val -> type ;
33
+
34
+ switch (val -> type )
35
+ {
36
+ case jbvNull :
37
+ break ;
38
+
39
+ case jbvBool :
40
+ res -> val .boolean = val -> val .boolean ;
41
+ break ;
42
+
43
+ case jbvString :
44
+ { /* copy string values in the current context */
45
+ char * buf = palloc (val -> val .string .len + 1 );
46
+ memcpy (buf , val -> val .string .val , val -> val .string .len );
47
+ buf [val -> val .string .len ] = 0 ;
48
+ res -> val .string .val = buf ;
49
+ res -> val .string .len = val -> val .string .len ;
50
+ break ;
51
+ }
52
+
53
+ case jbvNumeric :
54
+ /* same for numeric */
55
+ res -> val .numeric =
56
+ DatumGetNumeric (DirectFunctionCall1 (numeric_uplus ,
57
+ NumericGetDatum (val -> val .numeric )));
58
+ break ;
59
+
60
+ case jbvArray :
61
+ {
62
+ int i ;
63
+
64
+ res -> val .array = val -> val .array ;
65
+ res -> val .array .elems = (JsonValue * )
66
+ palloc (sizeof (JsonValue ) * val -> val .array .nElems );
67
+
68
+ for (i = 0 ; i < val -> val .array .nElems ; i ++ )
69
+ JsonValueCopy (& res -> val .array .elems [i ],
70
+ & val -> val .array .elems [i ]);
71
+
72
+ break ;
73
+ }
74
+
75
+ case jbvObject :
76
+ {
77
+ int i ;
78
+
79
+ res -> val .object = val -> val .object ;
80
+ res -> val .object .pairs = (JsonPair * )
81
+ palloc (sizeof (JsonPair ) * val -> val .object .nPairs );
82
+
83
+ for (i = 0 ; i < val -> val .object .nPairs ; i ++ )
84
+ {
85
+ res -> val .object .pairs [i ].order = val -> val .object .pairs [i ].order ;
86
+ JsonValueCopy (& res -> val .object .pairs [i ].key ,
87
+ & val -> val .object .pairs [i ].key );
88
+ JsonValueCopy (& res -> val .object .pairs [i ].value ,
89
+ & val -> val .object .pairs [i ].value );
90
+ }
91
+
92
+ break ;
93
+ }
94
+
95
+ case jbvBinary :
96
+ res -> val .binary = val -> val .binary ;
97
+ res -> val .binary .data = JsonCopy (val -> val .binary .data );
98
+ break ;
99
+
100
+ default :
101
+ elog (ERROR , "unknown json value type %d" , val -> type );
102
+ }
103
+
104
+ return res ;
30
105
}
31
- #endif
32
106
33
107
static inline JsonValue *
34
108
jsonFindKeyInObjectInternal (JsonContainer * obj , const char * key , int len ,
@@ -560,6 +634,17 @@ jsonvGetArraySize(JsonContainer *arrc)
560
634
}
561
635
}
562
636
637
+ static JsonContainer *
638
+ jsonvCopy (JsonContainer * jc )
639
+ {
640
+ JsonContainerData * res = JsonContainerAlloc ();
641
+
642
+ * res = * jc ;
643
+ res -> data = JsonValueCopy (NULL , (JsonValue * ) jc -> data );
644
+
645
+ return res ;
646
+ }
647
+
563
648
JsonContainerOps
564
649
jsonvContainerOps =
565
650
{
@@ -571,6 +656,7 @@ jsonvContainerOps =
571
656
jsonvGetArrayElement ,
572
657
jsonvGetArraySize ,
573
658
JsonbToCStringRaw ,
659
+ jsonvCopy ,
574
660
};
575
661
576
662
JsonValue *
@@ -1011,6 +1097,18 @@ JsonValueToJson(JsonValue *val)
1011
1097
}
1012
1098
}
1013
1099
1100
+ JsonContainer *
1101
+ JsonCopyFlat (JsonContainer * jc )
1102
+ {
1103
+ JsonContainerData * res = JsonContainerAlloc ();
1104
+
1105
+ * res = * jc ;
1106
+ res -> data = palloc (jc -> len );
1107
+ memcpy (res -> data , jc -> data , jc -> len );
1108
+
1109
+ return res ;
1110
+ }
1111
+
1014
1112
JsonValue *
1015
1113
JsonContainerExtractKeys (JsonContainer * jsc )
1016
1114
{
0 commit comments