@@ -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 ,
@@ -4872,9 +4872,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
48724872 break ;
48734873 case WJB_BEGIN_OBJECT :
48744874 (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 );
48784877 Assert (r == WJB_END_OBJECT );
48794878 res = pushJsonbValue (st , r , NULL );
48804879 break ;
@@ -4908,39 +4907,21 @@ setPath(JsonbIterator **it, Datum *path_elems,
49084907/*
49094908 * Object walker for setPath
49104909 */
4911- static void
4910+ static JsonbIteratorToken
49124911setPathObject (JsonbIterator * * it , Datum * path_elems , bool * path_nulls ,
49134912 int path_len , JsonbParseState * * st , int level ,
4914- JsonbValue * newval , uint32 npairs , int op_type )
4913+ JsonbValue * newval , int op_type )
49154914{
4916- int i ;
49174915 JsonbValue k ,
49184916 v ;
4917+ JsonbIteratorToken r ;
49194918 bool done = false;
49204919
49214920 if (level >= path_len || path_nulls [level ])
49224921 done = true;
49234922
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 )
49394924 {
4940- JsonbIteratorToken r = JsonbIteratorNext (it , & k , true);
4941-
4942- Assert (r == WJB_KEY );
4943-
49444925 if (!done &&
49454926 k .val .string .len == VARSIZE_ANY_EXHDR (path_elems [level ]) &&
49464927 memcmp (k .val .string .val , VARDATA_ANY (path_elems [level ]),
@@ -4962,6 +4943,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
49624943 "to replace key value." )));
49634944
49644945 r = JsonbIteratorNext (it , & v , true); /* skip value */
4946+ Assert (r == WJB_VALUE );
4947+
49654948 if (!(op_type & JB_PATH_DELETE ))
49664949 {
49674950 (void ) pushJsonbValue (st , WJB_KEY , & k );
@@ -4977,27 +4960,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
49774960 }
49784961 else
49794962 {
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-
49934963 (void ) pushJsonbValue (st , r , & k );
49944964 r = JsonbIteratorNext (it , & v , true);
49954965 Assert (r == WJB_VALUE );
49964966 (void ) pushJsonbValue (st , r , & v );
49974967 }
49984968 }
49994969
5000- /*--
4970+ if (done )
4971+ return r ;
4972+
4973+ /*
50014974 * If we got here there are only few possibilities:
50024975 * - no target path was found, and an open object with some keys/values was
50034976 * pushed into the state
@@ -5007,7 +4980,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
50074980 * generate the whole chain of empty objects and insert the new value
50084981 * there.
50094982 */
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 )))
50114985 {
50124986 JsonbValue newkey ;
50134987
@@ -5016,11 +4990,17 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
50164990 newkey .val .string .val = VARDATA_ANY (path_elems [level ]);
50174991
50184992 (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 );
50214999
50225000 /* Result is closed with WJB_END_OBJECT outside of this function */
50235001 }
5002+
5003+ return r ;
50245004}
50255005
50265006/*
0 commit comments