35
35
#include "utils/typcache.h"
36
36
#include "parser/parse_node.h"
37
37
38
- #define add_newval (state , newval , unpacked ) \
39
- if (unpacked) \
40
- (void) pushJsonbValue(st, WJB_VALUE, (JsonbValue *)newval); \
41
- else \
42
- addJsonbToParseState(st, (Jsonb *)newval);
43
-
44
38
/* Operations available for setPath */
45
39
#define JB_PATH_NOOP 0x0000
46
40
#define JB_PATH_CREATE 0x0001
@@ -148,17 +142,13 @@ static Datum jsonb_set_element(Datum datum, text **path, int path_len, Datum sou
148
142
static Datum jsonb_get_element (Datum datum , text * * path , int path_len , bool * isNull );
149
143
static JsonbValue * setPath (JsonbIterator * * it , Datum * path_elems ,
150
144
bool * path_nulls , int path_len ,
151
- JsonbParseState * * st , int level , Jsonb * newval ,
152
- bool unpacked , int op_type );
145
+ JsonbParseState * * st , int level , JsonbValue * newval , int op_type );
153
146
static void setPathObject (JsonbIterator * * it , Datum * path_elems ,
154
147
bool * path_nulls , int path_len , JsonbParseState * * st ,
155
- int level ,
156
- Jsonb * newval , bool unpacked , uint32 npairs , int op_type );
148
+ int level , JsonbValue * newval , uint32 npairs , int op_type );
157
149
static void setPathArray (JsonbIterator * * it , Datum * path_elems ,
158
150
bool * path_nulls , int path_len , JsonbParseState * * st ,
159
- int level ,
160
- Jsonb * newval , bool unpacked , uint32 nelems , int op_type );
161
- static void addJsonbToParseState (JsonbParseState * * jbps , Jsonb * jb );
151
+ int level , JsonbValue * newval , uint32 nelems , int op_type );
162
152
static Datum jsonb_subscription_evaluate (PG_FUNCTION_ARGS );
163
153
static Datum jsonb_subscription_prepare (PG_FUNCTION_ARGS );
164
154
@@ -3298,57 +3288,6 @@ jsonb_strip_nulls(PG_FUNCTION_ARGS)
3298
3288
PG_RETURN_POINTER (JsonbValueToJsonb (res ));
3299
3289
}
3300
3290
3301
- /*
3302
- * Add values from the jsonb to the parse state.
3303
- *
3304
- * If the parse state container is an object, the jsonb is pushed as
3305
- * a value, not a key.
3306
- *
3307
- * This needs to be done using an iterator because pushJsonbValue doesn't
3308
- * like getting jbvBinary values, so we can't just push jb as a whole.
3309
- */
3310
- static void
3311
- addJsonbToParseState (JsonbParseState * * jbps , Jsonb * jb )
3312
- {
3313
- JsonbIterator * it ;
3314
- JsonbValue * o = & (* jbps )-> contVal ;
3315
- JsonbValue v ;
3316
- JsonbIteratorToken type ;
3317
-
3318
- it = JsonbIteratorInit (& jb -> root );
3319
-
3320
- Assert (o -> type == jbvArray || o -> type == jbvObject );
3321
-
3322
- if (JB_ROOT_IS_SCALAR (jb ))
3323
- {
3324
- (void ) JsonbIteratorNext (& it , & v , false); /* skip array header */
3325
- (void ) JsonbIteratorNext (& it , & v , false); /* fetch scalar value */
3326
-
3327
- switch (o -> type )
3328
- {
3329
- case jbvArray :
3330
- (void ) pushJsonbValue (jbps , WJB_ELEM , & v );
3331
- break ;
3332
- case jbvObject :
3333
- (void ) pushJsonbValue (jbps , WJB_VALUE , & v );
3334
- break ;
3335
- default :
3336
- elog (ERROR , "unexpected parent of nested structure" );
3337
- }
3338
- }
3339
- else
3340
- {
3341
- while ((type = JsonbIteratorNext (& it , & v , false)) != WJB_DONE )
3342
- {
3343
- if (type == WJB_KEY || type == WJB_VALUE || type == WJB_ELEM )
3344
- (void ) pushJsonbValue (jbps , type , & v );
3345
- else
3346
- (void ) pushJsonbValue (jbps , type , NULL );
3347
- }
3348
- }
3349
-
3350
- }
3351
-
3352
3291
/*
3353
3292
* SQL function jsonb_pretty (jsonb)
3354
3293
*
@@ -3535,7 +3474,9 @@ jsonb_set(PG_FUNCTION_ARGS)
3535
3474
{
3536
3475
Jsonb * in = PG_GETARG_JSONB (0 );
3537
3476
ArrayType * path = PG_GETARG_ARRAYTYPE_P (1 );
3538
- Jsonb * newval = PG_GETARG_JSONB (2 );
3477
+ Jsonb * newjsonb = PG_GETARG_JSONB (2 );
3478
+ JsonbValue newvalbuf ;
3479
+ JsonbValue * newval = JsonbToJsonbValue (newjsonb , & newvalbuf );
3539
3480
bool create = PG_GETARG_BOOL (3 );
3540
3481
JsonbValue * res = NULL ;
3541
3482
Datum * path_elems ;
@@ -3566,7 +3507,7 @@ jsonb_set(PG_FUNCTION_ARGS)
3566
3507
it = JsonbIteratorInit (& in -> root );
3567
3508
3568
3509
res = setPath (& it , path_elems , path_nulls , path_len , & st ,
3569
- 0 , newval , false, create ? JB_PATH_CREATE : JB_PATH_NOOP );
3510
+ 0 , newval , create ? JB_PATH_CREATE : JB_PATH_NOOP );
3570
3511
3571
3512
Assert (res != NULL );
3572
3513
@@ -3611,7 +3552,7 @@ jsonb_delete_path(PG_FUNCTION_ARGS)
3611
3552
it = JsonbIteratorInit (& in -> root );
3612
3553
3613
3554
res = setPath (& it , path_elems , path_nulls , path_len , & st ,
3614
- 0 , NULL , false, JB_PATH_DELETE );
3555
+ 0 , NULL , JB_PATH_DELETE );
3615
3556
3616
3557
Assert (res != NULL );
3617
3558
@@ -3627,7 +3568,9 @@ jsonb_insert(PG_FUNCTION_ARGS)
3627
3568
{
3628
3569
Jsonb * in = PG_GETARG_JSONB (0 );
3629
3570
ArrayType * path = PG_GETARG_ARRAYTYPE_P (1 );
3630
- Jsonb * newval = PG_GETARG_JSONB (2 );
3571
+ Jsonb * newjsonb = PG_GETARG_JSONB (2 );
3572
+ JsonbValue newvalbuf ;
3573
+ JsonbValue * newval = JsonbToJsonbValue (newjsonb , & newvalbuf );
3631
3574
bool after = PG_GETARG_BOOL (3 );
3632
3575
JsonbValue * res = NULL ;
3633
3576
Datum * path_elems ;
@@ -3655,7 +3598,7 @@ jsonb_insert(PG_FUNCTION_ARGS)
3655
3598
it = JsonbIteratorInit (& in -> root );
3656
3599
3657
3600
res = setPath (& it , path_elems , path_nulls , path_len , & st , 0 , newval ,
3658
- false, after ? JB_PATH_INSERT_AFTER : JB_PATH_INSERT_BEFORE );
3601
+ after ? JB_PATH_INSERT_AFTER : JB_PATH_INSERT_BEFORE );
3659
3602
3660
3603
Assert (res != NULL );
3661
3604
@@ -3790,7 +3733,7 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
3790
3733
JsonbValue *
3791
3734
setPath (JsonbIterator * * it , Datum * path_elems ,
3792
3735
bool * path_nulls , int path_len ,
3793
- JsonbParseState * * st , int level , Jsonb * newval , bool unpacked , int op_type )
3736
+ JsonbParseState * * st , int level , JsonbValue * newval , int op_type )
3794
3737
{
3795
3738
JsonbValue v ;
3796
3739
JsonbIteratorToken r ;
@@ -3811,15 +3754,15 @@ setPath(JsonbIterator **it, Datum *path_elems,
3811
3754
case WJB_BEGIN_ARRAY :
3812
3755
(void ) pushJsonbValue (st , r , NULL );
3813
3756
setPathArray (it , path_elems , path_nulls , path_len , st , level ,
3814
- newval , unpacked , v .val .array .nElems , op_type );
3757
+ newval , v .val .array .nElems , op_type );
3815
3758
r = JsonbIteratorNext (it , & v , false);
3816
3759
Assert (r == WJB_END_ARRAY );
3817
3760
res = pushJsonbValue (st , r , NULL );
3818
3761
break ;
3819
3762
case WJB_BEGIN_OBJECT :
3820
3763
(void ) pushJsonbValue (st , r , NULL );
3821
3764
setPathObject (it , path_elems , path_nulls , path_len , st , level ,
3822
- newval , unpacked , v .val .object .nPairs , op_type );
3765
+ newval , v .val .object .nPairs , op_type );
3823
3766
r = JsonbIteratorNext (it , & v , true);
3824
3767
Assert (r == WJB_END_OBJECT );
3825
3768
res = pushJsonbValue (st , r , NULL );
@@ -3843,10 +3786,11 @@ setPath(JsonbIterator **it, Datum *path_elems,
3843
3786
static void
3844
3787
setPathObject (JsonbIterator * * it , Datum * path_elems , bool * path_nulls ,
3845
3788
int path_len , JsonbParseState * * st , int level ,
3846
- Jsonb * newval , bool unpacked , uint32 npairs , int op_type )
3789
+ JsonbValue * newval , uint32 npairs , int op_type )
3847
3790
{
3848
3791
int i ;
3849
- JsonbValue k , v ;
3792
+ JsonbValue k ,
3793
+ v ;
3850
3794
bool done = false;
3851
3795
3852
3796
if (level >= path_len || path_nulls [level ])
@@ -3863,7 +3807,7 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
3863
3807
newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
3864
3808
3865
3809
(void ) pushJsonbValue (st , WJB_KEY , & newkey );
3866
- add_newval ( st , newval , unpacked );
3810
+ ( void ) pushJsonbValue ( st , WJB_VALUE , newval );
3867
3811
}
3868
3812
3869
3813
for (i = 0 ; i < npairs ; i ++ )
@@ -3894,15 +3838,15 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
3894
3838
if (!(op_type & JB_PATH_DELETE ))
3895
3839
{
3896
3840
(void ) pushJsonbValue (st , WJB_KEY , & k );
3897
- add_newval ( st , newval , unpacked );
3841
+ ( void ) pushJsonbValue ( st , WJB_VALUE , newval );
3898
3842
}
3899
3843
done = true;
3900
3844
}
3901
3845
else
3902
3846
{
3903
3847
(void ) pushJsonbValue (st , r , & k );
3904
3848
setPath (it , path_elems , path_nulls , path_len ,
3905
- st , level + 1 , newval , unpacked , op_type );
3849
+ st , level + 1 , newval , op_type );
3906
3850
}
3907
3851
}
3908
3852
else
@@ -3917,7 +3861,7 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
3917
3861
newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
3918
3862
3919
3863
(void ) pushJsonbValue (st , WJB_KEY , & newkey );
3920
- add_newval ( st , newval , unpacked );
3864
+ ( void ) pushJsonbValue ( st , WJB_VALUE , newval );
3921
3865
}
3922
3866
3923
3867
(void ) pushJsonbValue (st , r , & k );
@@ -3949,7 +3893,7 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
3949
3893
static void
3950
3894
setPathArray (JsonbIterator * * it , Datum * path_elems , bool * path_nulls ,
3951
3895
int path_len , JsonbParseState * * st , int level ,
3952
- Jsonb * newval , bool unpacked , uint32 nelems , int op_type )
3896
+ Jsonb * newval , uint32 nelems , int op_type )
3953
3897
{
3954
3898
JsonbValue v ;
3955
3899
int idx ,
@@ -3997,7 +3941,7 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
3997
3941
(op_type & JB_PATH_CREATE_OR_INSERT ))
3998
3942
{
3999
3943
Assert (newval != NULL );
4000
- add_newval ( st , newval , unpacked );
3944
+ ( void ) pushJsonbValue ( st , WJB_ELEM , newval );
4001
3945
done = true;
4002
3946
}
4003
3947
@@ -4013,7 +3957,7 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
4013
3957
r = JsonbIteratorNext (it , & v , true); /* skip */
4014
3958
4015
3959
if (op_type & (JB_PATH_INSERT_BEFORE | JB_PATH_CREATE ))
4016
- add_newval ( st , newval , unpacked );
3960
+ ( void ) pushJsonbValue ( st , WJB_ELEM , newval );
4017
3961
4018
3962
/*
4019
3963
* We should keep current value only in case of
@@ -4024,13 +3968,13 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
4024
3968
(void ) pushJsonbValue (st , r , & v );
4025
3969
4026
3970
if (op_type & JB_PATH_INSERT_AFTER )
4027
- add_newval ( st , newval , unpacked );
3971
+ ( void ) pushJsonbValue ( st , WJB_ELEM , newval );
4028
3972
4029
3973
done = true;
4030
3974
}
4031
3975
else
4032
3976
(void ) setPath (it , path_elems , path_nulls , path_len ,
4033
- st , level + 1 , newval , unpacked , op_type );
3977
+ st , level + 1 , newval , op_type );
4034
3978
}
4035
3979
else
4036
3980
{
@@ -4058,7 +4002,7 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
4058
4002
if (op_type & JB_PATH_CREATE_OR_INSERT && !done &&
4059
4003
level == path_len - 1 && i == nelems - 1 )
4060
4004
{
4061
- add_newval ( st , newval , unpacked );
4005
+ ( void ) pushJsonbValue ( st , WJB_ELEM , newval );
4062
4006
}
4063
4007
}
4064
4008
}
@@ -4234,7 +4178,7 @@ jsonb_set_element(Datum jsonbdatum, text **path, int path_len,
4234
4178
path_nulls [i ] = false;
4235
4179
4236
4180
res = setPath (& it , (Datum * ) path , path_nulls , path_len , & state , 0 ,
4237
- ( void * ) newval , true , JB_PATH_CREATE );
4181
+ newval , JB_PATH_CREATE );
4238
4182
4239
4183
PG_RETURN_JSONB (JsonbValueToJsonb (res ));
4240
4184
}
0 commit comments