@@ -468,10 +468,10 @@ static JsonbValue *setPath(JsonbIterator **it, Datum *path_elems,
468
468
bool * path_nulls , int path_len ,
469
469
JsonbParseState * * st , int level , JsonbValue * newval ,
470
470
int op_type );
471
- static void setPathObject (JsonbIterator * * it , Datum * path_elems ,
472
- bool * path_nulls , int path_len , JsonbParseState * * st ,
473
- int level ,
474
- JsonbValue * newval , uint32 npairs , int op_type );
471
+ static JsonbIteratorToken setPathObject (JsonbIterator * * it , Datum * path_elems ,
472
+ bool * path_nulls , int path_len ,
473
+ JsonbParseState * * st , int level ,
474
+ JsonbValue * newval , int op_type );
475
475
static void setPathArray (JsonbIterator * * it , Datum * path_elems ,
476
476
bool * path_nulls , int path_len , JsonbParseState * * st ,
477
477
int level ,
@@ -4872,9 +4872,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
4872
4872
break ;
4873
4873
case WJB_BEGIN_OBJECT :
4874
4874
(void ) pushJsonbValue (st , r , NULL );
4875
- setPathObject (it , path_elems , path_nulls , path_len , st , level ,
4876
- newval , v .val .object .nPairs , op_type );
4877
- r = JsonbIteratorNext (it , & v , true);
4875
+ r = setPathObject (it , path_elems , path_nulls , path_len , st , level ,
4876
+ newval , op_type );
4878
4877
Assert (r == WJB_END_OBJECT );
4879
4878
res = pushJsonbValue (st , r , NULL );
4880
4879
break ;
@@ -4908,39 +4907,21 @@ setPath(JsonbIterator **it, Datum *path_elems,
4908
4907
/*
4909
4908
* Object walker for setPath
4910
4909
*/
4911
- static void
4910
+ static JsonbIteratorToken
4912
4911
setPathObject (JsonbIterator * * it , Datum * path_elems , bool * path_nulls ,
4913
4912
int path_len , JsonbParseState * * st , int level ,
4914
- JsonbValue * newval , uint32 npairs , int op_type )
4913
+ JsonbValue * newval , int op_type )
4915
4914
{
4916
- int i ;
4917
4915
JsonbValue k ,
4918
4916
v ;
4917
+ JsonbIteratorToken r ;
4919
4918
bool done = false;
4920
4919
4921
4920
if (level >= path_len || path_nulls [level ])
4922
4921
done = true;
4923
4922
4924
- /* empty object is a special case for create */
4925
- if ((npairs == 0 ) && (op_type & JB_PATH_CREATE_OR_INSERT ) &&
4926
- (level == path_len - 1 ))
4927
- {
4928
- JsonbValue newkey ;
4929
-
4930
- newkey .type = jbvString ;
4931
- newkey .val .string .len = VARSIZE_ANY_EXHDR (path_elems [level ]);
4932
- newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
4933
-
4934
- (void ) pushJsonbValue (st , WJB_KEY , & newkey );
4935
- (void ) pushJsonbValue (st , WJB_VALUE , newval );
4936
- }
4937
-
4938
- for (i = 0 ; i < npairs ; i ++ )
4923
+ while ((r = JsonbIteratorNext (it , & k , true)) == WJB_KEY )
4939
4924
{
4940
- JsonbIteratorToken r = JsonbIteratorNext (it , & k , true);
4941
-
4942
- Assert (r == WJB_KEY );
4943
-
4944
4925
if (!done &&
4945
4926
k .val .string .len == VARSIZE_ANY_EXHDR (path_elems [level ]) &&
4946
4927
memcmp (k .val .string .val , VARDATA_ANY (path_elems [level ]),
@@ -4962,6 +4943,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
4962
4943
"to replace key value." )));
4963
4944
4964
4945
r = JsonbIteratorNext (it , & v , true); /* skip value */
4946
+ Assert (r == WJB_VALUE );
4947
+
4965
4948
if (!(op_type & JB_PATH_DELETE ))
4966
4949
{
4967
4950
(void ) pushJsonbValue (st , WJB_KEY , & k );
@@ -4977,27 +4960,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
4977
4960
}
4978
4961
else
4979
4962
{
4980
- if ((op_type & JB_PATH_CREATE_OR_INSERT ) && !done &&
4981
- level == path_len - 1 && i == npairs - 1 )
4982
- {
4983
- JsonbValue newkey ;
4984
-
4985
- newkey .type = jbvString ;
4986
- newkey .val .string .len = VARSIZE_ANY_EXHDR (path_elems [level ]);
4987
- newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
4988
-
4989
- (void ) pushJsonbValue (st , WJB_KEY , & newkey );
4990
- (void ) pushJsonbValue (st , WJB_VALUE , newval );
4991
- }
4992
-
4993
4963
(void ) pushJsonbValue (st , r , & k );
4994
4964
r = JsonbIteratorNext (it , & v , true);
4995
4965
Assert (r == WJB_VALUE );
4996
4966
(void ) pushJsonbValue (st , r , & v );
4997
4967
}
4998
4968
}
4999
4969
5000
- /*--
4970
+ if (done )
4971
+ return r ;
4972
+
4973
+ /*
5001
4974
* If we got here there are only few possibilities:
5002
4975
* - no target path was found, and an open object with some keys/values was
5003
4976
* pushed into the state
@@ -5007,7 +4980,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
5007
4980
* generate the whole chain of empty objects and insert the new value
5008
4981
* there.
5009
4982
*/
5010
- if (!done && (op_type & JB_PATH_FILL_GAPS ) && (level < path_len - 1 ))
4983
+ if ((level < path_len - 1 && (op_type & JB_PATH_FILL_GAPS )) ||
4984
+ (level == path_len - 1 && (op_type & JB_PATH_CREATE_OR_INSERT )))
5011
4985
{
5012
4986
JsonbValue newkey ;
5013
4987
@@ -5016,11 +4990,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
5016
4990
newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
5017
4991
5018
4992
(void ) pushJsonbValue (st , WJB_KEY , & newkey );
5019
- (void ) push_path (st , level , path_elems , path_nulls ,
5020
- path_len , newval );
4993
+
4994
+ if (level == path_len - 1 )
4995
+ (void ) pushJsonbValue (st , WJB_VALUE , newval );
4996
+ else
4997
+ (void ) push_path (st , level , path_elems , path_nulls ,
4998
+ path_len , newval );
5021
4999
5022
5000
/* Result is closed with WJB_END_OBJECT outside of this function */
5023
5001
}
5002
+
5003
+ return r ;
5024
5004
}
5025
5005
5026
5006
/*
0 commit comments