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"
@@ -19,16 +20,88 @@ static JsonContainerOps jsonvContainerOps;
1920static Json * JsonExpand (Json * tmp , Datum value , bool freeValue ,
2021 JsonContainerOps * ops );
2122
22-
23- #if 0
24- static JsonValue *
25- JsonValueCopy (JsonValue * val )
23+ JsonValue *
24+ JsonValueCopy (JsonValue * res , const JsonValue * val )
2625{
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 ;
30104}
31- #endif
32105
33106static inline JsonValue *
34107jsonFindKeyInObjectInternal (JsonContainer * obj , const char * key , int len ,
@@ -549,6 +622,17 @@ jsonvGetArraySize(JsonContainer *arrc)
549622 }
550623}
551624
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+
552636static JsonContainerOps
553637jsonvContainerOps =
554638{
@@ -559,6 +643,7 @@ jsonvContainerOps =
559643 jsonvGetArrayElement ,
560644 jsonvGetArraySize ,
561645 JsonbToCStringRaw ,
646+ jsonvCopy ,
562647};
563648
564649JsonValue *
@@ -679,6 +764,18 @@ JsonValueToJson(JsonValue *val)
679764 }
680765}
681766
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+
682779JsonValue *
683780JsonContainerExtractKeys (JsonContainer * jsc )
684781{
0 commit comments