@@ -466,12 +466,8 @@ Datum
466466jsonb_object_field (PG_FUNCTION_ARGS )
467467{
468468 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 ;
475471
476472 if (JB_ROOT_IS_SCALAR (jb ))
477473 ereport (ERROR ,
@@ -484,25 +480,11 @@ jsonb_object_field(PG_FUNCTION_ARGS)
484480
485481 Assert (JB_ROOT_IS_OBJECT (jb ));
486482
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 ));
492485
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 ));
506488
507489 PG_RETURN_NULL ();
508490}
@@ -527,12 +509,8 @@ Datum
527509jsonb_object_field_text (PG_FUNCTION_ARGS )
528510{
529511 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 ;
536514
537515 if (JB_ROOT_IS_SCALAR (jb ))
538516 ereport (ERROR ,
@@ -545,47 +523,41 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
545523
546524 Assert (JB_ROOT_IS_OBJECT (jb ));
547525
548- it = JsonbIteratorInit (& jb -> root );
526+ v = findJsonbValueFromContainerLen (& jb -> root , JB_FOBJECT ,
527+ VARDATA_ANY (key ), VARSIZE_ANY_EXHDR (key ));
549528
550- while (( r = JsonbIteratorNext ( & it , & v , skipNested )) != WJB_DONE )
529+ if ( v != NULL )
551530 {
552- skipNested = true ;
531+ text * result = NULL ;
553532
554- if ( r == WJB_KEY )
533+ switch ( v -> type )
555534 {
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 :
571548 {
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 ();
582550
583- (void ) JsonbToCString (jtext , & tjb -> root , -1 );
551+ (void ) JsonbToCString (jtext , v -> val . binary . data , -1 );
584552 result = cstring_to_text_with_len (jtext -> data , jtext -> len );
585553 }
586- PG_RETURN_TEXT_P (result );
587- }
554+ break ;
555+ default :
556+ elog (ERROR , "Wrong jsonb type: %d" , v -> type );
588557 }
558+
559+ if (result )
560+ PG_RETURN_TEXT_P (result );
589561 }
590562
591563 PG_RETURN_NULL ();
@@ -611,11 +583,7 @@ jsonb_array_element(PG_FUNCTION_ARGS)
611583{
612584 Jsonb * jb = PG_GETARG_JSONB (0 );
613585 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 ;
619587
620588 if (JB_ROOT_IS_SCALAR (jb ))
621589 ereport (ERROR ,
@@ -628,18 +596,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
628596
629597 Assert (JB_ROOT_IS_ARRAY (jb ));
630598
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 ));
643602
644603 PG_RETURN_NULL ();
645604}
@@ -664,12 +623,7 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
664623{
665624 Jsonb * jb = PG_GETARG_JSONB (0 );
666625 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 ;
673627
674628 if (JB_ROOT_IS_SCALAR (jb ))
675629 ereport (ERROR ,
@@ -682,41 +636,39 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
682636
683637 Assert (JB_ROOT_IS_ARRAY (jb ));
684638
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 )
688641 {
689- skipNested = true ;
642+ text * result = NULL ;
690643
691- if ( r == WJB_ELEM )
644+ switch ( v -> type )
692645 {
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 :
710659 {
711- StringInfo jtext = makeStringInfo ();
712- Jsonb * tjb = JsonbValueToJsonb (& v );
660+ StringInfo jtext = makeStringInfo ();
713661
714- (void ) JsonbToCString (jtext , & tjb -> root , -1 );
662+ (void ) JsonbToCString (jtext , v -> val . binary . data , -1 );
715663 result = cstring_to_text_with_len (jtext -> data , jtext -> len );
716664 }
717- PG_RETURN_TEXT_P (result );
718- }
665+ break ;
666+ default :
667+ elog (ERROR , "Wrong jsonb type: %d" , v -> type );
719668 }
669+
670+ if (result )
671+ PG_RETURN_TEXT_P (result );
720672 }
721673
722674 PG_RETURN_NULL ();
0 commit comments