1010
1111#include "postgres.h"
1212
13+ #include "miscadmin.h"
1314#include "utils/builtins.h"
1415#include "utils/json_generic.h"
1516#include "utils/memutils.h"
@@ -20,15 +21,88 @@ JsonContainerOps jsonvContainerOps;
2021static Json * JsonExpand (Json * tmp , Datum value , bool freeValue ,
2122 JsonContainerOps * ops );
2223
23- #if 0
24- static JsonValue *
25- JsonValueCopy (JsonValue * val )
24+ JsonValue *
25+ JsonValueCopy (JsonValue * res , const JsonValue * val )
2626{
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 ;
30105}
31- #endif
32106
33107static inline JsonValue *
34108jsonFindKeyInObjectInternal (JsonContainer * obj , const char * key , int len ,
@@ -560,6 +634,17 @@ jsonvGetArraySize(JsonContainer *arrc)
560634 }
561635}
562636
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+
563648JsonContainerOps
564649jsonvContainerOps =
565650{
@@ -571,6 +656,7 @@ jsonvContainerOps =
571656 jsonvGetArrayElement ,
572657 jsonvGetArraySize ,
573658 JsonbToCStringRaw ,
659+ jsonvCopy ,
574660};
575661
576662JsonValue *
@@ -1011,6 +1097,18 @@ JsonValueToJson(JsonValue *val)
10111097 }
10121098}
10131099
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+
10141112JsonValue *
10151113JsonContainerExtractKeys (JsonContainer * jsc )
10161114{
0 commit comments