@@ -562,6 +562,8 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
562562 state = palloc (sizeof (OkeysState ));
563563
564564 state -> result_size = JB_ROOT_COUNT (jb );
565+ if (state -> result_size < 0 )
566+ state -> result_size = 8 ;
565567 state -> result_count = 0 ;
566568 state -> sent_count = 0 ;
567569 state -> result = palloc (state -> result_size * sizeof (char * ));
@@ -579,6 +581,12 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
579581 cstr = palloc (v .val .string .len + 1 * sizeof (char ));
580582 memcpy (cstr , v .val .string .val , v .val .string .len );
581583 cstr [v .val .string .len ] = '\0' ;
584+ if (state -> result_count >= state -> result_size )
585+ {
586+ state -> result_size *= 2 ;
587+ state -> result = repalloc (state -> result , state -> result_size *
588+ sizeof (char * ));
589+ }
582590 state -> result [state -> result_count ++ ] = cstr ;
583591 }
584592 }
@@ -906,7 +914,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
906914 /* Handle negative subscript */
907915 if (element < 0 )
908916 {
909- uint32 nelements = JB_ROOT_COUNT (jb );
917+ int nelements = JB_ROOT_COUNT (jb );
918+ if (nelements < 0 )
919+ nelements = JsonGetArraySize (JsonRoot (jb ));
910920
911921 if (- element > nelements )
912922 PG_RETURN_NULL ();
@@ -950,6 +960,8 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
950960 if (element < 0 )
951961 {
952962 uint32 nelements = JB_ROOT_COUNT (jb );
963+ if (nelements < 0 )
964+ nelements = JsonGetArraySize (JsonRoot (jb ));
953965
954966 if (- element > nelements )
955967 PG_RETURN_NULL ();
@@ -1685,7 +1697,8 @@ jsonb_array_length(PG_FUNCTION_ARGS)
16851697 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
16861698 errmsg ("cannot get array length of a non-array" )));
16871699
1688- PG_RETURN_INT32 (JB_ROOT_COUNT (jb ));
1700+ PG_RETURN_INT32 (JB_ROOT_COUNT (jb ) >= 0 ? JB_ROOT_COUNT (jb )
1701+ : JsonGetArraySize (JsonRoot (jb )));
16891702}
16901703
16911704/*
@@ -4437,16 +4450,19 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
44374450 Assert (r == WJB_BEGIN_ARRAY );
44384451 n = v .val .array .nElems ;
44394452
4440- if (idx < 0 )
4453+ if (v . val . array . nElems >= 0 )
44414454 {
4442- if (- idx > n )
4443- idx = n ;
4444- else
4445- idx = n + idx ;
4446- }
4455+ if (idx < 0 )
4456+ {
4457+ if (- idx > n )
4458+ idx = n ;
4459+ else
4460+ idx = n + idx ;
4461+ }
44474462
4448- if (idx >= n )
4449- PG_RETURN_JSONB_P (in );
4463+ if (idx >= n )
4464+ PG_RETURN_JSONB_P (in );
4465+ }
44504466
44514467 pushJsonbValue (& state , r , NULL );
44524468
@@ -4463,6 +4479,15 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
44634479
44644480 Assert (res != NULL );
44654481
4482+ if (idx < 0 && - idx <= res -> val .array .nElems )
4483+ {
4484+ idx = res -> val .array .nElems + idx ;
4485+ res -> val .array .nElems -- ;
4486+ memmove (& res -> val .array .elems [idx ],
4487+ & res -> val .array .elems [idx + 1 ],
4488+ sizeof (JsonValue ) * (res -> val .array .nElems - idx ));
4489+ }
4490+
44664491 PG_RETURN_JSONB_P (JsonbValueToJsonb (res ));
44674492}
44684493
@@ -4814,7 +4839,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
48144839 case WJB_BEGIN_ARRAY :
48154840 (void ) pushJsonbValue (st , r , NULL );
48164841 setPathArray (it , path_elems , path_nulls , path_len , st , level ,
4817- newval , v .val .array .nElems , op_type );
4842+ newval , v .val .array .nElems >= 0 ? v .val .array .nElems :
4843+ JsonGetArraySize ((* it )-> container ), op_type );
48184844 r = JsonbIteratorNext (it , & v , false);
48194845 Assert (r == WJB_END_ARRAY );
48204846 res = pushJsonbValue (st , r , NULL );
0 commit comments