@@ -567,6 +567,8 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
567
567
state = palloc (sizeof (OkeysState ));
568
568
569
569
state -> result_size = JB_ROOT_COUNT (jb );
570
+ if (state -> result_size < 0 )
571
+ state -> result_size = 8 ;
570
572
state -> result_count = 0 ;
571
573
state -> sent_count = 0 ;
572
574
state -> result = palloc (state -> result_size * sizeof (char * ));
@@ -584,6 +586,12 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
584
586
cstr = palloc (v .val .string .len + 1 * sizeof (char ));
585
587
memcpy (cstr , v .val .string .val , v .val .string .len );
586
588
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
+ }
587
595
state -> result [state -> result_count ++ ] = cstr ;
588
596
}
589
597
}
@@ -900,7 +908,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
900
908
/* Handle negative subscript */
901
909
if (element < 0 )
902
910
{
903
- uint32 nelements = JB_ROOT_COUNT (jb );
911
+ int nelements = JB_ROOT_COUNT (jb );
912
+ if (nelements < 0 )
913
+ nelements = JsonGetArraySize (JsonRoot (jb ));
904
914
905
915
if (- element > nelements )
906
916
PG_RETURN_NULL ();
@@ -944,6 +954,8 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
944
954
if (element < 0 )
945
955
{
946
956
uint32 nelements = JB_ROOT_COUNT (jb );
957
+ if (nelements < 0 )
958
+ nelements = JsonGetArraySize (JsonRoot (jb ));
947
959
948
960
if (- element > nelements )
949
961
PG_RETURN_NULL ();
@@ -1827,7 +1839,8 @@ jsonb_array_length(PG_FUNCTION_ARGS)
1827
1839
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1828
1840
errmsg ("cannot get array length of a non-array" )));
1829
1841
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 )));
1831
1844
}
1832
1845
1833
1846
/*
@@ -4536,16 +4549,19 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
4536
4549
Assert (r == WJB_BEGIN_ARRAY );
4537
4550
n = v .val .array .nElems ;
4538
4551
4539
- if (idx < 0 )
4552
+ if (v . val . array . nElems >= 0 )
4540
4553
{
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
+ }
4546
4561
4547
- if (idx >= n )
4548
- PG_RETURN_JSONB_P (in );
4562
+ if (idx >= n )
4563
+ PG_RETURN_JSONB_P (in );
4564
+ }
4549
4565
4550
4566
pushJsonbValue (& state , r , NULL );
4551
4567
@@ -4562,6 +4578,15 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
4562
4578
4563
4579
Assert (res != NULL );
4564
4580
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
+
4565
4590
PG_RETURN_JSONB_P (JsonbValueToJsonb (res ));
4566
4591
}
4567
4592
@@ -4946,7 +4971,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
4946
4971
4947
4972
(void ) pushJsonbValue (st , r , NULL );
4948
4973
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 );
4950
4976
r = JsonbIteratorNext (it , & v , false);
4951
4977
Assert (r == WJB_END_ARRAY );
4952
4978
res = pushJsonbValue (st , r , NULL );
0 commit comments