@@ -567,6 +567,8 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
567567 state = palloc (sizeof (OkeysState ));
568568
569569 state -> result_size = JB_ROOT_COUNT (jb );
570+ if (state -> result_size < 0 )
571+ state -> result_size = 8 ;
570572 state -> result_count = 0 ;
571573 state -> sent_count = 0 ;
572574 state -> result = palloc (state -> result_size * sizeof (char * ));
@@ -584,6 +586,12 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
584586 cstr = palloc (v .val .string .len + 1 * sizeof (char ));
585587 memcpy (cstr , v .val .string .val , v .val .string .len );
586588 cstr [v .val .string .len ] = '\0' ;
589+ if (state -> result_count >= state -> result_size )
590+ {
591+ state -> result_size *= 2 ;
592+ state -> result = repalloc (state -> result , state -> result_size *
593+ sizeof (char * ));
594+ }
587595 state -> result [state -> result_count ++ ] = cstr ;
588596 }
589597 }
@@ -900,7 +908,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
900908 /* Handle negative subscript */
901909 if (element < 0 )
902910 {
903- uint32 nelements = JB_ROOT_COUNT (jb );
911+ int nelements = JB_ROOT_COUNT (jb );
912+ if (nelements < 0 )
913+ nelements = JsonGetArraySize (JsonRoot (jb ));
904914
905915 if (- element > nelements )
906916 PG_RETURN_NULL ();
@@ -944,6 +954,8 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
944954 if (element < 0 )
945955 {
946956 uint32 nelements = JB_ROOT_COUNT (jb );
957+ if (nelements < 0 )
958+ nelements = JsonGetArraySize (JsonRoot (jb ));
947959
948960 if (- element > nelements )
949961 PG_RETURN_NULL ();
@@ -1827,7 +1839,8 @@ jsonb_array_length(PG_FUNCTION_ARGS)
18271839 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
18281840 errmsg ("cannot get array length of a non-array" )));
18291841
1830- PG_RETURN_INT32 (JB_ROOT_COUNT (jb ));
1842+ PG_RETURN_INT32 (JB_ROOT_COUNT (jb ) >= 0 ? JB_ROOT_COUNT (jb )
1843+ : JsonGetArraySize (JsonRoot (jb )));
18311844}
18321845
18331846/*
@@ -4536,16 +4549,19 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
45364549 Assert (r == WJB_BEGIN_ARRAY );
45374550 n = v .val .array .nElems ;
45384551
4539- if (idx < 0 )
4552+ if (v . val . array . nElems >= 0 )
45404553 {
4541- if (- idx > n )
4542- idx = n ;
4543- else
4544- idx = n + idx ;
4545- }
4554+ if (idx < 0 )
4555+ {
4556+ if (- idx > n )
4557+ idx = n ;
4558+ else
4559+ idx = n + idx ;
4560+ }
45464561
4547- if (idx >= n )
4548- PG_RETURN_JSONB_P (in );
4562+ if (idx >= n )
4563+ PG_RETURN_JSONB_P (in );
4564+ }
45494565
45504566 pushJsonbValue (& state , r , NULL );
45514567
@@ -4562,6 +4578,15 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
45624578
45634579 Assert (res != NULL );
45644580
4581+ if (idx < 0 && - idx <= res -> val .array .nElems )
4582+ {
4583+ idx = res -> val .array .nElems + idx ;
4584+ res -> val .array .nElems -- ;
4585+ memmove (& res -> val .array .elems [idx ],
4586+ & res -> val .array .elems [idx + 1 ],
4587+ sizeof (JsonValue ) * (res -> val .array .nElems - idx ));
4588+ }
4589+
45654590 PG_RETURN_JSONB_P (JsonbValueToJsonb (res ));
45664591}
45674592
@@ -4946,7 +4971,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
49464971
49474972 (void ) pushJsonbValue (st , r , NULL );
49484973 setPathArray (it , path_elems , path_nulls , path_len , st , level ,
4949- newval , v .val .array .nElems , op_type );
4974+ newval , v .val .array .nElems >= 0 ? v .val .array .nElems :
4975+ JsonGetArraySize ((* it )-> container ), op_type );
49504976 r = JsonbIteratorNext (it , & v , false);
49514977 Assert (r == WJB_END_ARRAY );
49524978 res = pushJsonbValue (st , r , NULL );
0 commit comments