@@ -127,7 +127,6 @@ static JsonbValue *findJsonbValueFromContainerLen(JsonbContainer *container,
127
127
/* functions supporting jsonb_delete, jsonb_replace and jsonb_concat */
128
128
static JsonbValue * IteratorConcat (JsonbIterator * * it1 , JsonbIterator * * it2 ,
129
129
JsonbParseState * * state );
130
- static JsonbValue * walkJsonb (JsonbIterator * * it , JsonbParseState * * state , bool stop_at_level_zero );
131
130
static JsonbValue * replacePath (JsonbIterator * * it , Datum * path_elems ,
132
131
bool * path_nulls , int path_len ,
133
132
JsonbParseState * * st , int level , Jsonb * newval );
@@ -3287,7 +3286,6 @@ jsonb_pretty(PG_FUNCTION_ARGS)
3287
3286
PG_RETURN_TEXT_P (cstring_to_text_with_len (str -> data , str -> len ));
3288
3287
}
3289
3288
3290
-
3291
3289
/*
3292
3290
* SQL function jsonb_concat (jsonb, jsonb)
3293
3291
*
@@ -3298,7 +3296,6 @@ jsonb_concat(PG_FUNCTION_ARGS)
3298
3296
{
3299
3297
Jsonb * jb1 = PG_GETARG_JSONB (0 );
3300
3298
Jsonb * jb2 = PG_GETARG_JSONB (1 );
3301
- Jsonb * out = palloc (VARSIZE (jb1 ) + VARSIZE (jb2 ));
3302
3299
JsonbParseState * state = NULL ;
3303
3300
JsonbValue * res ;
3304
3301
JsonbIterator * it1 ,
@@ -3308,35 +3305,18 @@ jsonb_concat(PG_FUNCTION_ARGS)
3308
3305
* If one of the jsonb is empty, just return other.
3309
3306
*/
3310
3307
if (JB_ROOT_COUNT (jb1 ) == 0 )
3311
- {
3312
- memcpy (out , jb2 , VARSIZE (jb2 ));
3313
- PG_RETURN_POINTER (out );
3314
- }
3308
+ PG_RETURN_JSONB (jb2 );
3315
3309
else if (JB_ROOT_COUNT (jb2 ) == 0 )
3316
- {
3317
- memcpy (out , jb1 , VARSIZE (jb1 ));
3318
- PG_RETURN_POINTER (out );
3319
- }
3310
+ PG_RETURN_JSONB (jb1 );
3320
3311
3321
3312
it1 = JsonbIteratorInit (& jb1 -> root );
3322
3313
it2 = JsonbIteratorInit (& jb2 -> root );
3323
3314
3324
3315
res = IteratorConcat (& it1 , & it2 , & state );
3325
3316
3326
- if (res == NULL || (res -> type == jbvArray && res -> val .array .nElems == 0 ) ||
3327
- (res -> type == jbvObject && res -> val .object .nPairs == 0 ))
3328
- {
3329
- SET_VARSIZE (out , VARHDRSZ );
3330
- }
3331
- else
3332
- {
3333
- if (res -> type == jbvArray && res -> val .array .nElems > 1 )
3334
- res -> val .array .rawScalar = false;
3335
-
3336
- out = JsonbValueToJsonb (res );
3337
- }
3317
+ Assert (res != NULL );
3338
3318
3339
- PG_RETURN_JSONB (out );
3319
+ PG_RETURN_JSONB (JsonbValueToJsonb ( res ) );
3340
3320
}
3341
3321
3342
3322
@@ -3550,7 +3530,6 @@ jsonb_delete_path(PG_FUNCTION_ARGS)
3550
3530
PG_RETURN_JSONB (JsonbValueToJsonb (res ));
3551
3531
}
3552
3532
3553
-
3554
3533
/*
3555
3534
* Iterate over all jsonb objects and merge them into one.
3556
3535
* The logic of this function copied from the same hstore function,
@@ -3578,67 +3557,42 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
3578
3557
*/
3579
3558
if (rk1 == WJB_BEGIN_OBJECT && rk2 == WJB_BEGIN_OBJECT )
3580
3559
{
3581
- int level = 1 ;
3582
-
3583
3560
/*
3584
3561
* Append the all tokens from v1 to res, except last WJB_END_OBJECT
3585
3562
* (because res will not be finished yet).
3586
3563
*/
3587
- (void ) pushJsonbValue (state , r1 , NULL );
3588
- while ((r1 = JsonbIteratorNext (it1 , & v1 , false)) != 0 )
3589
- {
3590
- if (r1 == WJB_BEGIN_OBJECT )
3591
- ++ level ;
3592
- else if (r1 == WJB_END_OBJECT )
3593
- -- level ;
3594
-
3595
- if (level != 0 )
3596
- res = pushJsonbValue (state , r1 , r1 < WJB_BEGIN_ARRAY ? & v1 : NULL );
3597
- }
3564
+ pushJsonbValue (state , r1 , NULL );
3565
+ while ((r1 = JsonbIteratorNext (it1 , & v1 , true)) != WJB_END_OBJECT )
3566
+ pushJsonbValue (state , r1 , & v1 );
3598
3567
3599
3568
/*
3600
3569
* Append the all tokens from v2 to res, include last WJB_END_OBJECT
3601
3570
* (the concatenation will be completed).
3602
3571
*/
3603
- while ((r2 = JsonbIteratorNext (it2 , & v2 , false )) != 0 )
3604
- res = pushJsonbValue (state , r2 , r2 < WJB_BEGIN_ARRAY ? & v2 : NULL );
3572
+ while ((r2 = JsonbIteratorNext (it2 , & v2 , true )) != 0 )
3573
+ res = pushJsonbValue (state , r2 , r2 != WJB_END_OBJECT ? & v2 : NULL );
3605
3574
}
3606
3575
3607
3576
/*
3608
3577
* Both elements are arrays (either can be scalar).
3609
3578
*/
3610
3579
else if (rk1 == WJB_BEGIN_ARRAY && rk2 == WJB_BEGIN_ARRAY )
3611
3580
{
3612
- res = pushJsonbValue (state , r1 , NULL );
3613
- for (;;)
3614
- {
3615
- r1 = JsonbIteratorNext (it1 , & v1 , true);
3616
- if (r1 == WJB_END_OBJECT || r1 == WJB_END_ARRAY )
3617
- break ;
3581
+ pushJsonbValue (state , r1 , NULL );
3618
3582
3619
- Assert (r1 == WJB_KEY || r1 == WJB_VALUE || r1 == WJB_ELEM );
3583
+ while ((r1 = JsonbIteratorNext (it1 , & v1 , true)) != WJB_END_ARRAY )
3584
+ {
3585
+ Assert (r1 == WJB_ELEM );
3620
3586
pushJsonbValue (state , r1 , & v1 );
3621
3587
}
3622
3588
3623
- while ((r2 = JsonbIteratorNext (it2 , & v2 , true)) != 0 )
3589
+ while ((r2 = JsonbIteratorNext (it2 , & v2 , true)) != WJB_END_ARRAY )
3624
3590
{
3625
- if (!(r2 == WJB_END_OBJECT || r2 == WJB_END_ARRAY ))
3626
- {
3627
- if (rk1 == WJB_BEGIN_OBJECT )
3628
- {
3629
- pushJsonbValue (state , WJB_KEY , NULL );
3630
- r2 = JsonbIteratorNext (it2 , & v2 , true);
3631
- Assert (r2 == WJB_ELEM );
3632
- pushJsonbValue (state , WJB_VALUE , & v2 );
3633
- }
3634
- else
3635
- pushJsonbValue (state , WJB_ELEM , & v2 );
3636
- }
3591
+ Assert (r2 == WJB_ELEM );
3592
+ pushJsonbValue (state , WJB_ELEM , & v2 );
3637
3593
}
3638
3594
3639
- res = pushJsonbValue (state ,
3640
- (rk1 == WJB_BEGIN_OBJECT ) ? WJB_END_OBJECT : WJB_END_ARRAY ,
3641
- NULL /* signal to sort */ );
3595
+ res = pushJsonbValue (state , WJB_END_ARRAY , NULL /* signal to sort */ );
3642
3596
}
3643
3597
/* have we got array || object or object || array? */
3644
3598
else if (((rk1 == WJB_BEGIN_ARRAY && !(* it1 )-> isScalar ) && rk2 == WJB_BEGIN_OBJECT ) ||
@@ -3648,22 +3602,27 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
3648
3602
JsonbIterator * * it_array = rk1 == WJB_BEGIN_ARRAY ? it1 : it2 ;
3649
3603
JsonbIterator * * it_object = rk1 == WJB_BEGIN_OBJECT ? it1 : it2 ;
3650
3604
3651
- bool prepend = (rk1 == WJB_BEGIN_OBJECT ) ? true : false ;
3605
+ bool prepend = (rk1 == WJB_BEGIN_OBJECT );
3652
3606
3653
3607
pushJsonbValue (state , WJB_BEGIN_ARRAY , NULL );
3608
+
3654
3609
if (prepend )
3655
3610
{
3656
3611
pushJsonbValue (state , WJB_BEGIN_OBJECT , NULL );
3657
- walkJsonb (it_object , state , false);
3612
+ while ((r1 = JsonbIteratorNext (it_object , & v1 , true)) != 0 )
3613
+ pushJsonbValue (state , r1 , r1 != WJB_END_OBJECT ? & v1 : NULL );
3658
3614
3659
- res = walkJsonb (it_array , state , false);
3615
+ while ((r2 = JsonbIteratorNext (it_array , & v2 , true)) != 0 )
3616
+ res = pushJsonbValue (state , r2 , r2 != WJB_END_ARRAY ? & v2 : NULL );
3660
3617
}
3661
3618
else
3662
3619
{
3663
- walkJsonb (it_array , state , true);
3620
+ while ((r1 = JsonbIteratorNext (it_array , & v1 , true)) != WJB_END_ARRAY )
3621
+ pushJsonbValue (state , r1 , & v1 );
3664
3622
3665
3623
pushJsonbValue (state , WJB_BEGIN_OBJECT , NULL );
3666
- walkJsonb (it_object , state , false);
3624
+ while ((r2 = JsonbIteratorNext (it_object , & v2 , true)) != 0 )
3625
+ pushJsonbValue (state , r2 , r2 != WJB_END_OBJECT ? & v2 : NULL );
3667
3626
3668
3627
res = pushJsonbValue (state , WJB_END_ARRAY , NULL );
3669
3628
}
@@ -3682,35 +3641,6 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
3682
3641
return res ;
3683
3642
}
3684
3643
3685
- /*
3686
- * copy elements from the iterator to the parse state
3687
- * stopping at level zero if required.
3688
- */
3689
- static JsonbValue *
3690
- walkJsonb (JsonbIterator * * it , JsonbParseState * * state , bool stop_at_level_zero )
3691
- {
3692
- uint32 r ,
3693
- level = 1 ;
3694
- JsonbValue v ;
3695
- JsonbValue * res = NULL ;
3696
-
3697
- while ((r = JsonbIteratorNext (it , & v , false)) != WJB_DONE )
3698
- {
3699
- if (r == WJB_BEGIN_OBJECT || r == WJB_BEGIN_ARRAY )
3700
- ++ level ;
3701
- else if (r == WJB_END_OBJECT || r == WJB_END_ARRAY )
3702
- -- level ;
3703
-
3704
- if (stop_at_level_zero && level == 0 )
3705
- break ;
3706
-
3707
- res = pushJsonbValue (state , r , r < WJB_BEGIN_ARRAY ? & v : NULL );
3708
- }
3709
-
3710
- return res ;
3711
- }
3712
-
3713
-
3714
3644
/*
3715
3645
* do most of the heavy work for jsonb_replace
3716
3646
*/
0 commit comments