@@ -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 ,
@@ -4942,9 +4942,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
4942
4942
break ;
4943
4943
case WJB_BEGIN_OBJECT :
4944
4944
(void )pushJsonbValue (st ,r ,NULL );
4945
- setPathObject (it ,path_elems ,path_nulls ,path_len ,st ,level ,
4946
- newval ,v .val .object .nPairs ,op_type );
4947
- r = JsonbIteratorNext (it ,& v , true);
4945
+ r = setPathObject (it ,path_elems ,path_nulls ,path_len ,st ,level ,
4946
+ newval ,op_type );
4948
4947
Assert (r == WJB_END_OBJECT );
4949
4948
res = pushJsonbValue (st ,r ,NULL );
4950
4949
break ;
@@ -4978,39 +4977,21 @@ setPath(JsonbIterator **it, Datum *path_elems,
4978
4977
/*
4979
4978
* Object walker for setPath
4980
4979
*/
4981
- static void
4980
+ static JsonbIteratorToken
4982
4981
setPathObject (JsonbIterator * * it ,Datum * path_elems ,bool * path_nulls ,
4983
4982
int path_len ,JsonbParseState * * st ,int level ,
4984
- JsonbValue * newval ,uint32 npairs , int op_type )
4983
+ JsonbValue * newval ,int op_type )
4985
4984
{
4986
- int i ;
4987
4985
JsonbValue k ,
4988
4986
v ;
4987
+ JsonbIteratorToken r ;
4989
4988
bool done = false;
4990
4989
4991
4990
if (level >=path_len || path_nulls [level ])
4992
4991
done = true;
4993
4992
4994
- /* empty object is a special case for create */
4995
- if ((npairs == 0 )&& (op_type & JB_PATH_CREATE_OR_INSERT )&&
4996
- (level == path_len - 1 ))
4997
- {
4998
- JsonbValue newkey ;
4999
-
5000
- newkey .type = jbvString ;
5001
- newkey .val .string .len = VARSIZE_ANY_EXHDR (path_elems [level ]);
5002
- newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
5003
-
5004
- (void )pushJsonbValue (st ,WJB_KEY ,& newkey );
5005
- (void )pushJsonbValue (st ,WJB_VALUE ,newval );
5006
- }
5007
-
5008
- for (i = 0 ;i < npairs ;i ++ )
4993
+ while ((r = JsonbIteratorNext (it ,& k , true))== WJB_KEY )
5009
4994
{
5010
- JsonbIteratorToken r = JsonbIteratorNext (it ,& k , true);
5011
-
5012
- Assert (r == WJB_KEY );
5013
-
5014
4995
if (!done &&
5015
4996
k .val .string .len == VARSIZE_ANY_EXHDR (path_elems [level ])&&
5016
4997
memcmp (k .val .string .val ,VARDATA_ANY (path_elems [level ]),
@@ -5032,6 +5013,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
5032
5013
"to replace key value." )));
5033
5014
5034
5015
r = JsonbIteratorNext (it ,& v , true);/* skip value */
5016
+ Assert (r == WJB_VALUE );
5017
+
5035
5018
if (!(op_type & JB_PATH_DELETE ))
5036
5019
{
5037
5020
(void )pushJsonbValue (st ,WJB_KEY ,& k );
@@ -5047,27 +5030,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
5047
5030
}
5048
5031
else
5049
5032
{
5050
- if ((op_type & JB_PATH_CREATE_OR_INSERT )&& !done &&
5051
- level == path_len - 1 && i == npairs - 1 )
5052
- {
5053
- JsonbValue newkey ;
5054
-
5055
- newkey .type = jbvString ;
5056
- newkey .val .string .len = VARSIZE_ANY_EXHDR (path_elems [level ]);
5057
- newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
5058
-
5059
- (void )pushJsonbValue (st ,WJB_KEY ,& newkey );
5060
- (void )pushJsonbValue (st ,WJB_VALUE ,newval );
5061
- }
5062
-
5063
5033
(void )pushJsonbValue (st ,r ,& k );
5064
5034
r = JsonbIteratorNext (it ,& v , true);
5065
5035
Assert (r == WJB_VALUE );
5066
5036
(void )pushJsonbValue (st ,r ,& v );
5067
5037
}
5068
5038
}
5069
5039
5070
- /*--
5040
+ if (done )
5041
+ return r ;
5042
+
5043
+ /*
5071
5044
* If we got here there are only few possibilities:
5072
5045
* - no target path was found, and an open object with some keys/values was
5073
5046
* pushed into the state
@@ -5077,7 +5050,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
5077
5050
* generate the whole chain of empty objects and insert the new value
5078
5051
* there.
5079
5052
*/
5080
- if (!done && (op_type & JB_PATH_FILL_GAPS )&& (level < path_len - 1 ))
5053
+ if ((level < path_len - 1 && (op_type & JB_PATH_FILL_GAPS ))||
5054
+ (level == path_len - 1 && (op_type & JB_PATH_CREATE_OR_INSERT )))
5081
5055
{
5082
5056
JsonbValue newkey ;
5083
5057
@@ -5086,11 +5060,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
5086
5060
newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
5087
5061
5088
5062
(void )pushJsonbValue (st ,WJB_KEY ,& newkey );
5089
- (void )push_path (st ,level ,path_elems ,path_nulls ,
5090
- path_len ,newval );
5063
+
5064
+ if (level == path_len - 1 )
5065
+ (void )pushJsonbValue (st ,WJB_VALUE ,newval );
5066
+ else
5067
+ (void )push_path (st ,level ,path_elems ,path_nulls ,
5068
+ path_len ,newval );
5091
5069
5092
5070
/* Result is closed with WJB_END_OBJECT outside of this function */
5093
5071
}
5072
+
5073
+ return r ;
5094
5074
}
5095
5075
5096
5076
/*