@@ -513,6 +513,8 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
513
513
state = palloc (sizeof (OkeysState ));
514
514
515
515
state -> result_size = JB_ROOT_COUNT (jb );
516
+ if (state -> result_size < 0 )
517
+ state -> result_size = 8 ;
516
518
state -> result_count = 0 ;
517
519
state -> sent_count = 0 ;
518
520
state -> result = palloc (state -> result_size * sizeof (char * ));
@@ -530,6 +532,12 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
530
532
cstr = palloc (v .val .string .len + 1 * sizeof (char ));
531
533
memcpy (cstr , v .val .string .val , v .val .string .len );
532
534
cstr [v .val .string .len ] = '\0' ;
535
+ if (state -> result_count >= state -> result_size )
536
+ {
537
+ state -> result_size *= 2 ;
538
+ state -> result = repalloc (state -> result , state -> result_size *
539
+ sizeof (char * ));
540
+ }
533
541
state -> result [state -> result_count ++ ] = cstr ;
534
542
}
535
543
}
@@ -806,7 +814,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
806
814
/* Handle negative subscript */
807
815
if (element < 0 )
808
816
{
809
- uint32 nelements = JB_ROOT_COUNT (jb );
817
+ int nelements = JB_ROOT_COUNT (jb );
818
+ if (nelements < 0 )
819
+ nelements = JsonGetArraySize (JsonRoot (jb ));
810
820
811
821
if (- element > nelements )
812
822
PG_RETURN_NULL ();
@@ -850,6 +860,8 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
850
860
if (element < 0 )
851
861
{
852
862
uint32 nelements = JB_ROOT_COUNT (jb );
863
+ if (nelements < 0 )
864
+ nelements = JsonGetArraySize (JsonRoot (jb ));
853
865
854
866
if (- element > nelements )
855
867
PG_RETURN_NULL ();
@@ -1576,7 +1588,8 @@ jsonb_array_length(PG_FUNCTION_ARGS)
1576
1588
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1577
1589
errmsg ("cannot get array length of a non-array" )));
1578
1590
1579
- PG_RETURN_INT32 (JB_ROOT_COUNT (jb ));
1591
+ PG_RETURN_INT32 (JB_ROOT_COUNT (jb ) >= 0 ? JB_ROOT_COUNT (jb )
1592
+ : JsonGetArraySize (JsonRoot (jb )));
1580
1593
}
1581
1594
1582
1595
/*
@@ -4211,16 +4224,19 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
4211
4224
Assert (r == WJB_BEGIN_ARRAY );
4212
4225
n = v .val .array .nElems ;
4213
4226
4214
- if (idx < 0 )
4227
+ if (v . val . array . nElems >= 0 )
4215
4228
{
4216
- if (- idx > n )
4217
- idx = n ;
4218
- else
4219
- idx = n + idx ;
4220
- }
4229
+ if (idx < 0 )
4230
+ {
4231
+ if (- idx > n )
4232
+ idx = n ;
4233
+ else
4234
+ idx = n + idx ;
4235
+ }
4221
4236
4222
- if (idx >= n )
4223
- PG_RETURN_JSONB (in );
4237
+ if (idx >= n )
4238
+ PG_RETURN_JSONB (in );
4239
+ }
4224
4240
4225
4241
pushJsonbValue (& state , r , NULL );
4226
4242
@@ -4237,6 +4253,15 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
4237
4253
4238
4254
Assert (res != NULL );
4239
4255
4256
+ if (idx < 0 && - idx <= res -> val .array .nElems )
4257
+ {
4258
+ idx = res -> val .array .nElems + idx ;
4259
+ res -> val .array .nElems -- ;
4260
+ memmove (& res -> val .array .elems [idx ],
4261
+ & res -> val .array .elems [idx + 1 ],
4262
+ sizeof (JsonValue ) * (res -> val .array .nElems - idx ));
4263
+ }
4264
+
4240
4265
PG_RETURN_JSONB (JsonbValueToJsonb (res ));
4241
4266
}
4242
4267
@@ -4525,7 +4550,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
4525
4550
case WJB_BEGIN_ARRAY :
4526
4551
(void ) pushJsonbValue (st , r , NULL );
4527
4552
setPathArray (it , path_elems , path_nulls , path_len , st , level ,
4528
- newval , v .val .array .nElems , op_type );
4553
+ newval , v .val .array .nElems >= 0 ? v .val .array .nElems :
4554
+ JsonGetArraySize ((* it )-> container ), op_type );
4529
4555
r = JsonbIteratorNext (it , & v , false);
4530
4556
Assert (r == WJB_END_ARRAY );
4531
4557
res = pushJsonbValue (st , r , NULL );
0 commit comments