@@ -466,12 +466,8 @@ Datum
466
466
jsonb_object_field (PG_FUNCTION_ARGS )
467
467
{
468
468
Jsonb * jb = PG_GETARG_JSONB (0 );
469
- char * key = text_to_cstring (PG_GETARG_TEXT_P (1 ));
470
- int klen = strlen (key );
471
- JsonbIterator * it ;
472
- JsonbValue v ;
473
- int r ;
474
- bool skipNested = false;
469
+ text * key = PG_GETARG_TEXT_PP (1 );
470
+ JsonbValue * v ;
475
471
476
472
if (JB_ROOT_IS_SCALAR (jb ))
477
473
ereport (ERROR ,
@@ -484,25 +480,11 @@ jsonb_object_field(PG_FUNCTION_ARGS)
484
480
485
481
Assert (JB_ROOT_IS_OBJECT (jb ));
486
482
487
- it = JsonbIteratorInit (& jb -> root );
488
-
489
- while ((r = JsonbIteratorNext (& it , & v , skipNested )) != WJB_DONE )
490
- {
491
- skipNested = true;
483
+ v = findJsonbValueFromContainerLen (& jb -> root , JB_FOBJECT ,
484
+ VARDATA_ANY (key ), VARSIZE_ANY_EXHDR (key ));
492
485
493
- if (r == WJB_KEY )
494
- {
495
- if (klen == v .val .string .len && strncmp (key , v .val .string .val , klen ) == 0 )
496
- {
497
- /*
498
- * The next thing the iterator fetches should be the value, no
499
- * matter what shape it is.
500
- */
501
- (void ) JsonbIteratorNext (& it , & v , skipNested );
502
- PG_RETURN_JSONB (JsonbValueToJsonb (& v ));
503
- }
504
- }
505
- }
486
+ if (v != NULL )
487
+ PG_RETURN_JSONB (JsonbValueToJsonb (v ));
506
488
507
489
PG_RETURN_NULL ();
508
490
}
@@ -527,12 +509,8 @@ Datum
527
509
jsonb_object_field_text (PG_FUNCTION_ARGS )
528
510
{
529
511
Jsonb * jb = PG_GETARG_JSONB (0 );
530
- char * key = text_to_cstring (PG_GETARG_TEXT_P (1 ));
531
- int klen = strlen (key );
532
- JsonbIterator * it ;
533
- JsonbValue v ;
534
- int r ;
535
- bool skipNested = false;
512
+ text * key = PG_GETARG_TEXT_PP (1 );
513
+ JsonbValue * v ;
536
514
537
515
if (JB_ROOT_IS_SCALAR (jb ))
538
516
ereport (ERROR ,
@@ -545,47 +523,41 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
545
523
546
524
Assert (JB_ROOT_IS_OBJECT (jb ));
547
525
548
- it = JsonbIteratorInit (& jb -> root );
526
+ v = findJsonbValueFromContainerLen (& jb -> root , JB_FOBJECT ,
527
+ VARDATA_ANY (key ), VARSIZE_ANY_EXHDR (key ));
549
528
550
- while (( r = JsonbIteratorNext ( & it , & v , skipNested )) != WJB_DONE )
529
+ if ( v != NULL )
551
530
{
552
- skipNested = true ;
531
+ text * result = NULL ;
553
532
554
- if ( r == WJB_KEY )
533
+ switch ( v -> type )
555
534
{
556
- if (klen == v .val .string .len && strncmp (key , v .val .string .val , klen ) == 0 )
557
- {
558
- text * result ;
559
-
560
- /*
561
- * The next thing the iterator fetches should be the value, no
562
- * matter what shape it is.
563
- */
564
- r = JsonbIteratorNext (& it , & v , skipNested );
565
-
566
- /*
567
- * if it's a scalar string it needs to be de-escaped,
568
- * otherwise just return the text
569
- */
570
- if (v .type == jbvString )
535
+ case jbvNull :
536
+ break ;
537
+ case jbvBool :
538
+ result = cstring_to_text (v -> val .boolean ? "true" : "false" );
539
+ break ;
540
+ case jbvString :
541
+ result = cstring_to_text_with_len (v -> val .string .val , v -> val .string .len );
542
+ break ;
543
+ case jbvNumeric :
544
+ result = cstring_to_text (DatumGetCString (DirectFunctionCall1 (numeric_out ,
545
+ PointerGetDatum (v -> val .numeric ))));
546
+ break ;
547
+ case jbvBinary :
571
548
{
572
- result = cstring_to_text_with_len (v .val .string .val , v .val .string .len );
573
- }
574
- else if (v .type == jbvNull )
575
- {
576
- PG_RETURN_NULL ();
577
- }
578
- else
579
- {
580
- StringInfo jtext = makeStringInfo ();
581
- Jsonb * tjb = JsonbValueToJsonb (& v );
549
+ StringInfo jtext = makeStringInfo ();
582
550
583
- (void ) JsonbToCString (jtext , & tjb -> root , -1 );
551
+ (void ) JsonbToCString (jtext , v -> val . binary . data , -1 );
584
552
result = cstring_to_text_with_len (jtext -> data , jtext -> len );
585
553
}
586
- PG_RETURN_TEXT_P (result );
587
- }
554
+ break ;
555
+ default :
556
+ elog (ERROR , "Wrong jsonb type: %d" , v -> type );
588
557
}
558
+
559
+ if (result )
560
+ PG_RETURN_TEXT_P (result );
589
561
}
590
562
591
563
PG_RETURN_NULL ();
@@ -611,11 +583,7 @@ jsonb_array_element(PG_FUNCTION_ARGS)
611
583
{
612
584
Jsonb * jb = PG_GETARG_JSONB (0 );
613
585
int element = PG_GETARG_INT32 (1 );
614
- JsonbIterator * it ;
615
- JsonbValue v ;
616
- int r ;
617
- bool skipNested = false;
618
- int element_number = 0 ;
586
+ JsonbValue * v ;
619
587
620
588
if (JB_ROOT_IS_SCALAR (jb ))
621
589
ereport (ERROR ,
@@ -628,18 +596,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
628
596
629
597
Assert (JB_ROOT_IS_ARRAY (jb ));
630
598
631
- it = JsonbIteratorInit (& jb -> root );
632
-
633
- while ((r = JsonbIteratorNext (& it , & v , skipNested )) != WJB_DONE )
634
- {
635
- skipNested = true;
636
-
637
- if (r == WJB_ELEM )
638
- {
639
- if (element_number ++ == element )
640
- PG_RETURN_JSONB (JsonbValueToJsonb (& v ));
641
- }
642
- }
599
+ v = getIthJsonbValueFromContainer (& jb -> root , element );
600
+ if (v != NULL )
601
+ PG_RETURN_JSONB (JsonbValueToJsonb (v ));
643
602
644
603
PG_RETURN_NULL ();
645
604
}
@@ -664,12 +623,7 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
664
623
{
665
624
Jsonb * jb = PG_GETARG_JSONB (0 );
666
625
int element = PG_GETARG_INT32 (1 );
667
- JsonbIterator * it ;
668
- JsonbValue v ;
669
- int r ;
670
- bool skipNested = false;
671
- int element_number = 0 ;
672
-
626
+ JsonbValue * v ;
673
627
674
628
if (JB_ROOT_IS_SCALAR (jb ))
675
629
ereport (ERROR ,
@@ -682,41 +636,39 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
682
636
683
637
Assert (JB_ROOT_IS_ARRAY (jb ));
684
638
685
- it = JsonbIteratorInit (& jb -> root );
686
-
687
- while ((r = JsonbIteratorNext (& it , & v , skipNested )) != WJB_DONE )
639
+ v = getIthJsonbValueFromContainer (& jb -> root , element );
640
+ if (v != NULL )
688
641
{
689
- skipNested = true ;
642
+ text * result = NULL ;
690
643
691
- if ( r == WJB_ELEM )
644
+ switch ( v -> type )
692
645
{
693
- if (element_number ++ == element )
694
- {
695
- /*
696
- * if it's a scalar string it needs to be de-escaped,
697
- * otherwise just return the text
698
- */
699
- text * result ;
700
-
701
- if (v .type == jbvString )
702
- {
703
- result = cstring_to_text_with_len (v .val .string .val , v .val .string .len );
704
- }
705
- else if (v .type == jbvNull )
706
- {
707
- PG_RETURN_NULL ();
708
- }
709
- else
646
+ case jbvNull :
647
+ break ;
648
+ case jbvBool :
649
+ result = cstring_to_text (v -> val .boolean ? "true" : "false" );
650
+ break ;
651
+ case jbvString :
652
+ result = cstring_to_text_with_len (v -> val .string .val , v -> val .string .len );
653
+ break ;
654
+ case jbvNumeric :
655
+ result = cstring_to_text (DatumGetCString (DirectFunctionCall1 (numeric_out ,
656
+ PointerGetDatum (v -> val .numeric ))));
657
+ break ;
658
+ case jbvBinary :
710
659
{
711
- StringInfo jtext = makeStringInfo ();
712
- Jsonb * tjb = JsonbValueToJsonb (& v );
660
+ StringInfo jtext = makeStringInfo ();
713
661
714
- (void ) JsonbToCString (jtext , & tjb -> root , -1 );
662
+ (void ) JsonbToCString (jtext , v -> val . binary . data , -1 );
715
663
result = cstring_to_text_with_len (jtext -> data , jtext -> len );
716
664
}
717
- PG_RETURN_TEXT_P (result );
718
- }
665
+ break ;
666
+ default :
667
+ elog (ERROR , "Wrong jsonb type: %d" , v -> type );
719
668
}
669
+
670
+ if (result )
671
+ PG_RETURN_TEXT_P (result );
720
672
}
721
673
722
674
PG_RETURN_NULL ();
0 commit comments