@@ -4583,36 +4583,39 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
4583
4583
rk1 ,
4584
4584
rk2 ;
4585
4585
4586
- r1 = rk1 = JsonbIteratorNext (it1 , & v1 , false);
4587
- r2 = rk2 = JsonbIteratorNext (it2 , & v2 , false);
4586
+ rk1 = JsonbIteratorNext (it1 , & v1 , false);
4587
+ rk2 = JsonbIteratorNext (it2 , & v2 , false);
4588
4588
4589
4589
/*
4590
- * Both elements are objects.
4590
+ * JsonbIteratorNext reports raw scalars as if they were single-element
4591
+ * arrays; hence we only need consider "object" and "array" cases here.
4591
4592
*/
4592
4593
if (rk1 == WJB_BEGIN_OBJECT && rk2 == WJB_BEGIN_OBJECT )
4593
4594
{
4594
4595
/*
4595
- * Append the all tokens from v1 to res, except last WJB_END_OBJECT
4596
+ * Both inputs are objects.
4597
+ *
4598
+ * Append all the tokens from v1 to res, except last WJB_END_OBJECT
4596
4599
* (because res will not be finished yet).
4597
4600
*/
4598
- pushJsonbValue (state , r1 , NULL );
4601
+ pushJsonbValue (state , rk1 , NULL );
4599
4602
while ((r1 = JsonbIteratorNext (it1 , & v1 , true)) != WJB_END_OBJECT )
4600
4603
pushJsonbValue (state , r1 , & v1 );
4601
4604
4602
4605
/*
4603
- * Append the all tokens from v2 to res, include last WJB_END_OBJECT
4604
- * (the concatenation will be completed).
4606
+ * Append all the tokens from v2 to res, including last WJB_END_OBJECT
4607
+ * (the concatenation will be completed). Any duplicate keys will
4608
+ * automatically override the value from the first object.
4605
4609
*/
4606
4610
while ((r2 = JsonbIteratorNext (it2 , & v2 , true)) != WJB_DONE )
4607
4611
res = pushJsonbValue (state , r2 , r2 != WJB_END_OBJECT ? & v2 : NULL );
4608
4612
}
4609
-
4610
- /*
4611
- * Both elements are arrays (either can be scalar).
4612
- */
4613
4613
else if (rk1 == WJB_BEGIN_ARRAY && rk2 == WJB_BEGIN_ARRAY )
4614
4614
{
4615
- pushJsonbValue (state , r1 , NULL );
4615
+ /*
4616
+ * Both inputs are arrays.
4617
+ */
4618
+ pushJsonbValue (state , rk1 , NULL );
4616
4619
4617
4620
while ((r1 = JsonbIteratorNext (it1 , & v1 , true)) != WJB_END_ARRAY )
4618
4621
{
@@ -4628,48 +4631,40 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
4628
4631
4629
4632
res = pushJsonbValue (state , WJB_END_ARRAY , NULL /* signal to sort */ );
4630
4633
}
4631
- /* have we got array || object or object || array? */
4632
- else if (((rk1 == WJB_BEGIN_ARRAY && !(* it1 )-> isScalar ) && rk2 == WJB_BEGIN_OBJECT ) ||
4633
- (rk1 == WJB_BEGIN_OBJECT && (rk2 == WJB_BEGIN_ARRAY && !(* it2 )-> isScalar )))
4634
+ else if (rk1 == WJB_BEGIN_OBJECT )
4634
4635
{
4635
-
4636
- JsonbIterator * * it_array = rk1 == WJB_BEGIN_ARRAY ? it1 : it2 ;
4637
- JsonbIterator * * it_object = rk1 == WJB_BEGIN_OBJECT ? it1 : it2 ;
4638
-
4639
- bool prepend = (rk1 == WJB_BEGIN_OBJECT );
4636
+ /*
4637
+ * We have object || array.
4638
+ */
4639
+ Assert (rk2 == WJB_BEGIN_ARRAY );
4640
4640
4641
4641
pushJsonbValue (state , WJB_BEGIN_ARRAY , NULL );
4642
4642
4643
- if (prepend )
4644
- {
4645
- pushJsonbValue (state , WJB_BEGIN_OBJECT , NULL );
4646
- while ((r1 = JsonbIteratorNext (it_object , & v1 , true)) != WJB_DONE )
4647
- pushJsonbValue (state , r1 , r1 != WJB_END_OBJECT ? & v1 : NULL );
4648
-
4649
- while ((r2 = JsonbIteratorNext (it_array , & v2 , true)) != WJB_DONE )
4650
- res = pushJsonbValue (state , r2 , r2 != WJB_END_ARRAY ? & v2 : NULL );
4651
- }
4652
- else
4653
- {
4654
- while ((r1 = JsonbIteratorNext (it_array , & v1 , true)) != WJB_END_ARRAY )
4655
- pushJsonbValue (state , r1 , & v1 );
4643
+ pushJsonbValue (state , WJB_BEGIN_OBJECT , NULL );
4644
+ while ((r1 = JsonbIteratorNext (it1 , & v1 , true)) != WJB_DONE )
4645
+ pushJsonbValue (state , r1 , r1 != WJB_END_OBJECT ? & v1 : NULL );
4656
4646
4657
- pushJsonbValue (state , WJB_BEGIN_OBJECT , NULL );
4658
- while ((r2 = JsonbIteratorNext (it_object , & v2 , true)) != WJB_DONE )
4659
- pushJsonbValue (state , r2 , r2 != WJB_END_OBJECT ? & v2 : NULL );
4660
-
4661
- res = pushJsonbValue (state , WJB_END_ARRAY , NULL );
4662
- }
4647
+ while ((r2 = JsonbIteratorNext (it2 , & v2 , true)) != WJB_DONE )
4648
+ res = pushJsonbValue (state , r2 , r2 != WJB_END_ARRAY ? & v2 : NULL );
4663
4649
}
4664
4650
else
4665
4651
{
4666
4652
/*
4667
- * This must be scalar || object or object || scalar, as that's all
4668
- * that's left. Both of these make no sense, so error out.
4653
+ * We have array || object.
4669
4654
*/
4670
- ereport (ERROR ,
4671
- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
4672
- errmsg ("invalid concatenation of jsonb objects" )));
4655
+ Assert (rk1 == WJB_BEGIN_ARRAY );
4656
+ Assert (rk2 == WJB_BEGIN_OBJECT );
4657
+
4658
+ pushJsonbValue (state , WJB_BEGIN_ARRAY , NULL );
4659
+
4660
+ while ((r1 = JsonbIteratorNext (it1 , & v1 , true)) != WJB_END_ARRAY )
4661
+ pushJsonbValue (state , r1 , & v1 );
4662
+
4663
+ pushJsonbValue (state , WJB_BEGIN_OBJECT , NULL );
4664
+ while ((r2 = JsonbIteratorNext (it2 , & v2 , true)) != WJB_DONE )
4665
+ pushJsonbValue (state , r2 , r2 != WJB_END_OBJECT ? & v2 : NULL );
4666
+
4667
+ res = pushJsonbValue (state , WJB_END_ARRAY , NULL );
4673
4668
}
4674
4669
4675
4670
return res ;
0 commit comments