@@ -562,6 +562,8 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
562
562
state = palloc (sizeof (OkeysState ));
563
563
564
564
state -> result_size = JB_ROOT_COUNT (jb );
565
+ if (state -> result_size < 0 )
566
+ state -> result_size = 8 ;
565
567
state -> result_count = 0 ;
566
568
state -> sent_count = 0 ;
567
569
state -> result = palloc (state -> result_size * sizeof (char * ));
@@ -579,6 +581,12 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
579
581
cstr = palloc (v .val .string .len + 1 * sizeof (char ));
580
582
memcpy (cstr , v .val .string .val , v .val .string .len );
581
583
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
+ }
582
590
state -> result [state -> result_count ++ ] = cstr ;
583
591
}
584
592
}
@@ -906,7 +914,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
906
914
/* Handle negative subscript */
907
915
if (element < 0 )
908
916
{
909
- uint32 nelements = JB_ROOT_COUNT (jb );
917
+ int nelements = JB_ROOT_COUNT (jb );
918
+ if (nelements < 0 )
919
+ nelements = JsonGetArraySize (JsonRoot (jb ));
910
920
911
921
if (- element > nelements )
912
922
PG_RETURN_NULL ();
@@ -950,6 +960,8 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
950
960
if (element < 0 )
951
961
{
952
962
uint32 nelements = JB_ROOT_COUNT (jb );
963
+ if (nelements < 0 )
964
+ nelements = JsonGetArraySize (JsonRoot (jb ));
953
965
954
966
if (- element > nelements )
955
967
PG_RETURN_NULL ();
@@ -1685,7 +1697,8 @@ jsonb_array_length(PG_FUNCTION_ARGS)
1685
1697
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1686
1698
errmsg ("cannot get array length of a non-array" )));
1687
1699
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 )));
1689
1702
}
1690
1703
1691
1704
/*
@@ -4437,16 +4450,19 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
4437
4450
Assert (r == WJB_BEGIN_ARRAY );
4438
4451
n = v .val .array .nElems ;
4439
4452
4440
- if (idx < 0 )
4453
+ if (v . val . array . nElems >= 0 )
4441
4454
{
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
+ }
4447
4462
4448
- if (idx >= n )
4449
- PG_RETURN_JSONB_P (in );
4463
+ if (idx >= n )
4464
+ PG_RETURN_JSONB_P (in );
4465
+ }
4450
4466
4451
4467
pushJsonbValue (& state , r , NULL );
4452
4468
@@ -4463,6 +4479,15 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
4463
4479
4464
4480
Assert (res != NULL );
4465
4481
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
+
4466
4491
PG_RETURN_JSONB_P (JsonbValueToJsonb (res ));
4467
4492
}
4468
4493
@@ -4814,7 +4839,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
4814
4839
case WJB_BEGIN_ARRAY :
4815
4840
(void ) pushJsonbValue (st , r , NULL );
4816
4841
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 );
4818
4844
r = JsonbIteratorNext (it , & v , false);
4819
4845
Assert (r == WJB_END_ARRAY );
4820
4846
res = pushJsonbValue (st , r , NULL );
0 commit comments