@@ -127,7 +127,6 @@ static JsonbValue *findJsonbValueFromContainerLen(JsonbContainer *container,
127127/* functions supporting jsonb_delete, jsonb_replace and jsonb_concat */
128128static JsonbValue * IteratorConcat (JsonbIterator * * it1 , JsonbIterator * * it2 ,
129129 JsonbParseState * * state );
130- static JsonbValue * walkJsonb (JsonbIterator * * it , JsonbParseState * * state , bool stop_at_level_zero );
131130static JsonbValue * replacePath (JsonbIterator * * it , Datum * path_elems ,
132131 bool * path_nulls , int path_len ,
133132 JsonbParseState * * st , int level , Jsonb * newval );
@@ -3287,7 +3286,6 @@ jsonb_pretty(PG_FUNCTION_ARGS)
32873286 PG_RETURN_TEXT_P (cstring_to_text_with_len (str -> data , str -> len ));
32883287}
32893288
3290-
32913289/*
32923290 * SQL function jsonb_concat (jsonb, jsonb)
32933291 *
@@ -3298,7 +3296,6 @@ jsonb_concat(PG_FUNCTION_ARGS)
32983296{
32993297 Jsonb * jb1 = PG_GETARG_JSONB (0 );
33003298 Jsonb * jb2 = PG_GETARG_JSONB (1 );
3301- Jsonb * out = palloc (VARSIZE (jb1 ) + VARSIZE (jb2 ));
33023299 JsonbParseState * state = NULL ;
33033300 JsonbValue * res ;
33043301 JsonbIterator * it1 ,
@@ -3308,35 +3305,18 @@ jsonb_concat(PG_FUNCTION_ARGS)
33083305 * If one of the jsonb is empty, just return other.
33093306 */
33103307 if (JB_ROOT_COUNT (jb1 ) == 0 )
3311- {
3312- memcpy (out , jb2 , VARSIZE (jb2 ));
3313- PG_RETURN_POINTER (out );
3314- }
3308+ PG_RETURN_JSONB (jb2 );
33153309 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 );
33203311
33213312 it1 = JsonbIteratorInit (& jb1 -> root );
33223313 it2 = JsonbIteratorInit (& jb2 -> root );
33233314
33243315 res = IteratorConcat (& it1 , & it2 , & state );
33253316
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 );
33383318
3339- PG_RETURN_JSONB (out );
3319+ PG_RETURN_JSONB (JsonbValueToJsonb ( res ) );
33403320}
33413321
33423322
@@ -3550,7 +3530,6 @@ jsonb_delete_path(PG_FUNCTION_ARGS)
35503530 PG_RETURN_JSONB (JsonbValueToJsonb (res ));
35513531}
35523532
3553-
35543533/*
35553534 * Iterate over all jsonb objects and merge them into one.
35563535 * The logic of this function copied from the same hstore function,
@@ -3578,67 +3557,42 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
35783557 */
35793558 if (rk1 == WJB_BEGIN_OBJECT && rk2 == WJB_BEGIN_OBJECT )
35803559 {
3581- int level = 1 ;
3582-
35833560 /*
35843561 * Append the all tokens from v1 to res, except last WJB_END_OBJECT
35853562 * (because res will not be finished yet).
35863563 */
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 );
35983567
35993568 /*
36003569 * Append the all tokens from v2 to res, include last WJB_END_OBJECT
36013570 * (the concatenation will be completed).
36023571 */
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 );
36053574 }
36063575
36073576 /*
36083577 * Both elements are arrays (either can be scalar).
36093578 */
36103579 else if (rk1 == WJB_BEGIN_ARRAY && rk2 == WJB_BEGIN_ARRAY )
36113580 {
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 );
36183582
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 );
36203586 pushJsonbValue (state , r1 , & v1 );
36213587 }
36223588
3623- while ((r2 = JsonbIteratorNext (it2 , & v2 , true)) != 0 )
3589+ while ((r2 = JsonbIteratorNext (it2 , & v2 , true)) != WJB_END_ARRAY )
36243590 {
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 );
36373593 }
36383594
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 */ );
36423596 }
36433597 /* have we got array || object or object || array? */
36443598 else if (((rk1 == WJB_BEGIN_ARRAY && !(* it1 )-> isScalar ) && rk2 == WJB_BEGIN_OBJECT ) ||
@@ -3648,22 +3602,27 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
36483602 JsonbIterator * * it_array = rk1 == WJB_BEGIN_ARRAY ? it1 : it2 ;
36493603 JsonbIterator * * it_object = rk1 == WJB_BEGIN_OBJECT ? it1 : it2 ;
36503604
3651- bool prepend = (rk1 == WJB_BEGIN_OBJECT ) ? true : false ;
3605+ bool prepend = (rk1 == WJB_BEGIN_OBJECT );
36523606
36533607 pushJsonbValue (state , WJB_BEGIN_ARRAY , NULL );
3608+
36543609 if (prepend )
36553610 {
36563611 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 );
36583614
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 );
36603617 }
36613618 else
36623619 {
3663- walkJsonb (it_array , state , true);
3620+ while ((r1 = JsonbIteratorNext (it_array , & v1 , true)) != WJB_END_ARRAY )
3621+ pushJsonbValue (state , r1 , & v1 );
36643622
36653623 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 );
36673626
36683627 res = pushJsonbValue (state , WJB_END_ARRAY , NULL );
36693628 }
@@ -3682,35 +3641,6 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
36823641 return res ;
36833642}
36843643
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-
37143644/*
37153645 * do most of the heavy work for jsonb_replace
37163646 */
0 commit comments