@@ -468,10 +468,10 @@ static JsonbValue *setPath(JsonbIterator **it, Datum *path_elems,
468468 bool * path_nulls , int path_len ,
469469 JsonbParseState * * st , int level , JsonbValue * newval ,
470470 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 );
475475static void setPathArray (JsonbIterator * * it , Datum * path_elems ,
476476 bool * path_nulls , int path_len , JsonbParseState * * st ,
477477 int level ,
@@ -4942,9 +4942,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
49424942 break ;
49434943 case WJB_BEGIN_OBJECT :
49444944 (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 );
49484947 Assert (r == WJB_END_OBJECT );
49494948 res = pushJsonbValue (st , r , NULL );
49504949 break ;
@@ -4978,39 +4977,21 @@ setPath(JsonbIterator **it, Datum *path_elems,
49784977/*
49794978 * Object walker for setPath
49804979 */
4981- static void
4980+ static JsonbIteratorToken
49824981setPathObject (JsonbIterator * * it , Datum * path_elems , bool * path_nulls ,
49834982 int path_len , JsonbParseState * * st , int level ,
4984- JsonbValue * newval , uint32 npairs , int op_type )
4983+ JsonbValue * newval , int op_type )
49854984{
4986- int i ;
49874985 JsonbValue k ,
49884986 v ;
4987+ JsonbIteratorToken r ;
49894988 bool done = false;
49904989
49914990 if (level >= path_len || path_nulls [level ])
49924991 done = true;
49934992
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 )
50094994 {
5010- JsonbIteratorToken r = JsonbIteratorNext (it , & k , true);
5011-
5012- Assert (r == WJB_KEY );
5013-
50144995 if (!done &&
50154996 k .val .string .len == VARSIZE_ANY_EXHDR (path_elems [level ]) &&
50164997 memcmp (k .val .string .val , VARDATA_ANY (path_elems [level ]),
@@ -5032,6 +5013,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
50325013 "to replace key value." )));
50335014
50345015 r = JsonbIteratorNext (it , & v , true); /* skip value */
5016+ Assert (r == WJB_VALUE );
5017+
50355018 if (!(op_type & JB_PATH_DELETE ))
50365019 {
50375020 (void ) pushJsonbValue (st , WJB_KEY , & k );
@@ -5047,27 +5030,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
50475030 }
50485031 else
50495032 {
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-
50635033 (void ) pushJsonbValue (st , r , & k );
50645034 r = JsonbIteratorNext (it , & v , true);
50655035 Assert (r == WJB_VALUE );
50665036 (void ) pushJsonbValue (st , r , & v );
50675037 }
50685038 }
50695039
5070- /*--
5040+ if (done )
5041+ return r ;
5042+
5043+ /*
50715044 * If we got here there are only few possibilities:
50725045 * - no target path was found, and an open object with some keys/values was
50735046 * pushed into the state
@@ -5077,7 +5050,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
50775050 * generate the whole chain of empty objects and insert the new value
50785051 * there.
50795052 */
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 )))
50815055 {
50825056 JsonbValue newkey ;
50835057
@@ -5086,11 +5060,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
50865060 newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
50875061
50885062 (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 );
50915069
50925070 /* Result is closed with WJB_END_OBJECT outside of this function */
50935071 }
5072+
5073+ return r ;
50945074}
50955075
50965076/*
0 commit comments