@@ -335,6 +335,85 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
335
335
return res ;
336
336
}
337
337
338
+ static JsonbValue *
339
+ jsonbFindKeyInObject (const JsonbContainer * container , const JsonbValue * key )
340
+ {
341
+ return getIthJsonbValueFromContainer (container , key -> val .string .val ,
342
+ key -> val .string .len , NULL );
343
+ }
344
+
345
+ typedef struct JsonbArrayIterator
346
+ {
347
+ const JsonbContainer * container ;
348
+ char * base_addr ;
349
+ int index ;
350
+ int count ;
351
+ uint32 offset ;
352
+ } JsonbArrayIterator ;
353
+
354
+ static void
355
+ JsonbArrayIteratorInit (JsonbArrayIterator * it , const JsonbContainer * container )
356
+ {
357
+ it -> container = container ;
358
+ it -> index = 0 ;
359
+ it -> count = (container -> header & JB_CMASK );
360
+ it -> offset = 0 ;
361
+ it -> base_addr = (char * ) (container -> children + it -> count );
362
+ }
363
+
364
+ static bool
365
+ JsonbArrayIteratorNext (JsonbArrayIterator * it , JsonbValue * result )
366
+ {
367
+ if (it -> index >= it -> count )
368
+ return false;
369
+
370
+ fillJsonbValue (it -> container , it -> index , it -> base_addr , it -> offset , result );
371
+
372
+ JBE_ADVANCE_OFFSET (it -> offset , it -> container -> children [it -> index ]);
373
+
374
+ it -> index ++ ;
375
+
376
+ return true;
377
+ }
378
+
379
+ static JsonbValue *
380
+ JsonbArrayIteratorGetIth (JsonbArrayIterator * it , uint32 i )
381
+ {
382
+ JsonbValue * result ;
383
+
384
+ if (i >= it -> count )
385
+ return NULL ;
386
+
387
+ result = palloc (sizeof (JsonbValue ));
388
+
389
+ fillJsonbValue (it -> container , i , it -> base_addr ,
390
+ getJsonbOffset (it -> container , i ),
391
+ result );
392
+
393
+ return result ;
394
+ }
395
+
396
+ static JsonbValue *
397
+ jsonbFindValueInArray (const JsonbContainer * container , const JsonbValue * key )
398
+ {
399
+ JsonbArrayIterator it ;
400
+ JsonbValue * result = palloc (sizeof (JsonbValue ));
401
+
402
+ JsonbArrayIteratorInit (& it , container );
403
+
404
+ while (JsonbArrayIteratorNext (& it , result ))
405
+ {
406
+ if (key -> type == result -> type )
407
+ {
408
+ if (equalsJsonbScalarValue (key , result ))
409
+ return result ;
410
+ }
411
+ }
412
+
413
+ pfree (result );
414
+ return NULL ;
415
+ }
416
+
338
417
/*
339
418
* Find value in object (i.e. the "value" part of some key/value pair in an
340
419
* object), or find a matching element if we're looking through an array. Do
@@ -362,10 +441,9 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
362
441
* return NULL. Otherwise, return palloc()'d copy of value.
363
442
*/
364
443
JsonbValue *
365
- findJsonbValueFromContainer (JsonbContainer * container , uint32 flags ,
444
+ findJsonbValueFromContainer (const JsonbContainer * container , uint32 flags ,
366
445
JsonbValue * key )
367
446
{
368
- JEntry * children = container -> children ;
369
447
int count = JsonContainerSize (container );
370
448
371
449
Assert ((flags & ~(JB_FARRAY | JB_FOBJECT )) == 0 );
@@ -375,27 +453,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
375
453
return NULL ;
376
454
377
455
if ((flags & JB_FARRAY ) && JsonContainerIsArray (container ))
378
- {
379
- JsonbValue * result = palloc (sizeof (JsonbValue ));
380
- char * base_addr = (char * ) (children + count );
381
- uint32 offset = 0 ;
382
- int i ;
383
-
384
- for (i = 0 ; i < count ; i ++ )
385
- {
386
- fillJsonbValue (container , i , base_addr , offset , result );
387
-
388
- if (key -> type == result -> type )
389
- {
390
- if (equalsJsonbScalarValue (key , result ))
391
- return result ;
392
- }
393
-
394
- JBE_ADVANCE_OFFSET (offset , children [i ]);
395
- }
396
-
397
- pfree (result );
398
- }
456
+ return jsonbFindValueInArray (container , key );
399
457
else if ((flags & JB_FOBJECT ) && JsonContainerIsObject (container ))
400
458
{
401
459
/* Object key passed by caller must be a string */
@@ -488,26 +546,14 @@ getKeyJsonValueFromContainer(const JsonbContainer *container,
488
546
JsonbValue *
489
547
getIthJsonbValueFromContainer (JsonbContainer * container , uint32 i )
490
548
{
491
- JsonbValue * result ;
492
- char * base_addr ;
493
- uint32 nelements ;
549
+ JsonbArrayIterator it ;
494
550
495
551
if (!JsonContainerIsArray (container ))
496
552
elog (ERROR , "not a jsonb array" );
497
553
498
- nelements = JsonContainerSize (container );
499
- base_addr = (char * ) & container -> children [nelements ];
500
-
501
- if (i >= nelements )
502
- return NULL ;
503
-
504
- result = palloc (sizeof (JsonbValue ));
505
-
506
- fillJsonbValue (container , i , base_addr ,
507
- getJsonbOffset (container , i ),
508
- result );
554
+ JsonbArrayIteratorInit (& it , container );
509
555
510
- return result ;
556
+ return JsonbArrayIteratorGetIth ( & it , i ) ;
511
557
}
512
558
513
559
/*
@@ -638,7 +684,7 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
638
684
* Do the actual pushing, with only scalar or pseudo-scalar-array values
639
685
* accepted.
640
686
*/
641
- static JsonbValue *
687
+ JsonbValue *
642
688
pushJsonbValueScalar (JsonbParseState * * pstate , JsonbIteratorToken seq ,
643
689
const JsonbValue * scalarVal )
644
690
{
0 commit comments