@@ -349,6 +349,7 @@ static Datum get_path_all(FunctionCallInfo fcinfo, bool as_text);
349349static text * get_worker (text * json ,char * * tpath ,int * ipath ,int npath ,
350350bool normalize_results );
351351static Datum get_jsonb_path_all (FunctionCallInfo fcinfo ,bool as_text );
352+ static text * JsonbValueAsText (JsonbValue * v );
352353
353354/* semantic action functions for json_array_length */
354355static void alen_object_start (void * state );
@@ -761,39 +762,9 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
761762VARDATA_ANY (key ),
762763VARSIZE_ANY_EXHDR (key ));
763764
764- if (v != NULL )
765- {
766- text * result = NULL ;
767765
768- switch (v -> type )
769- {
770- case jbvNull :
771- break ;
772- case jbvBool :
773- result = cstring_to_text (v -> val .boolean ?"true" :"false" );
774- break ;
775- case jbvString :
776- result = cstring_to_text_with_len (v -> val .string .val ,v -> val .string .len );
777- break ;
778- case jbvNumeric :
779- result = cstring_to_text (DatumGetCString (DirectFunctionCall1 (numeric_out ,
780- PointerGetDatum (v -> val .numeric ))));
781- break ;
782- case jbvBinary :
783- {
784- StringInfo jtext = makeStringInfo ();
785-
786- (void )JsonbToCString (jtext ,v -> val .binary .data ,-1 );
787- result = cstring_to_text_with_len (jtext -> data ,jtext -> len );
788- }
789- break ;
790- default :
791- elog (ERROR ,"unrecognized jsonb type: %d" , (int )v -> type );
792- }
793-
794- if (result )
795- PG_RETURN_TEXT_P (result );
796- }
766+ if (v != NULL && v -> type != jbvNull )
767+ PG_RETURN_TEXT_P (JsonbValueAsText (v ));
797768
798769PG_RETURN_NULL ();
799770}
@@ -878,39 +849,9 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
878849}
879850
880851v = getIthJsonbValueFromContainer (& jb -> root ,element );
881- if (v != NULL )
882- {
883- text * result = NULL ;
884-
885- switch (v -> type )
886- {
887- case jbvNull :
888- break ;
889- case jbvBool :
890- result = cstring_to_text (v -> val .boolean ?"true" :"false" );
891- break ;
892- case jbvString :
893- result = cstring_to_text_with_len (v -> val .string .val ,v -> val .string .len );
894- break ;
895- case jbvNumeric :
896- result = cstring_to_text (DatumGetCString (DirectFunctionCall1 (numeric_out ,
897- PointerGetDatum (v -> val .numeric ))));
898- break ;
899- case jbvBinary :
900- {
901- StringInfo jtext = makeStringInfo ();
902852
903- (void )JsonbToCString (jtext ,v -> val .binary .data ,-1 );
904- result = cstring_to_text_with_len (jtext -> data ,jtext -> len );
905- }
906- break ;
907- default :
908- elog (ERROR ,"unrecognized jsonb type: %d" , (int )v -> type );
909- }
910-
911- if (result )
912- PG_RETURN_TEXT_P (result );
913- }
853+ if (v != NULL && v -> type != jbvNull )
854+ PG_RETURN_TEXT_P (JsonbValueAsText (v ));
914855
915856PG_RETURN_NULL ();
916857}
@@ -1548,6 +1489,53 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
15481489}
15491490}
15501491
1492+ /*
1493+ * Return the text representation of the given JsonbValue.
1494+ */
1495+ static text *
1496+ JsonbValueAsText (JsonbValue * v )
1497+ {
1498+ switch (v -> type )
1499+ {
1500+ case jbvNull :
1501+ return NULL ;
1502+
1503+ case jbvBool :
1504+ return v -> val .boolean ?
1505+ cstring_to_text_with_len ("true" ,4 ) :
1506+ cstring_to_text_with_len ("false" ,5 );
1507+
1508+ case jbvString :
1509+ return cstring_to_text_with_len (v -> val .string .val ,
1510+ v -> val .string .len );
1511+
1512+ case jbvNumeric :
1513+ {
1514+ Datum cstr ;
1515+
1516+ cstr = DirectFunctionCall1 (numeric_out ,
1517+ PointerGetDatum (v -> val .numeric ));
1518+
1519+ return cstring_to_text (DatumGetCString (cstr ));
1520+ }
1521+
1522+ case jbvBinary :
1523+ {
1524+ StringInfoData jtext ;
1525+
1526+ initStringInfo (& jtext );
1527+ (void )JsonbToCString (& jtext ,v -> val .binary .data ,
1528+ v -> val .binary .len );
1529+
1530+ return cstring_to_text_with_len (jtext .data ,jtext .len );
1531+ }
1532+
1533+ default :
1534+ elog (ERROR ,"unrecognized jsonb type: %d" , (int )v -> type );
1535+ return NULL ;
1536+ }
1537+ }
1538+
15511539/*
15521540 * SQL function json_array_length(json) -> int
15531541 */
@@ -1758,26 +1746,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
17581746values [1 ]= (Datum )NULL ;
17591747}
17601748else
1761- {
1762- text * sv ;
1763-
1764- if (v .type == jbvString )
1765- {
1766- /* In text mode, scalar strings should be dequoted */
1767- sv = cstring_to_text_with_len (v .val .string .val ,v .val .string .len );
1768- }
1769- else
1770- {
1771- /* Turn anything else into a json string */
1772- StringInfo jtext = makeStringInfo ();
1773- Jsonb * jb = JsonbValueToJsonb (& v );
1774-
1775- (void )JsonbToCString (jtext ,& jb -> root ,0 );
1776- sv = cstring_to_text_with_len (jtext -> data ,jtext -> len );
1777- }
1778-
1779- values [1 ]= PointerGetDatum (sv );
1780- }
1749+ values [1 ]= PointerGetDatum (JsonbValueAsText (& v ));
17811750}
17821751else
17831752{
@@ -2053,13 +2022,7 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname,
20532022/* use the tmp context so we can clean up after each tuple is done */
20542023old_cxt = MemoryContextSwitchTo (tmp_cxt );
20552024
2056- if (!as_text )
2057- {
2058- Jsonb * val = JsonbValueToJsonb (& v );
2059-
2060- values [0 ]= PointerGetDatum (val );
2061- }
2062- else
2025+ if (as_text )
20632026{
20642027if (v .type == jbvNull )
20652028{
@@ -2068,26 +2031,14 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname,
20682031values [0 ]= (Datum )NULL ;
20692032}
20702033else
2071- {
2072- text * sv ;
2073-
2074- if (v .type == jbvString )
2075- {
2076- /* in text mode scalar strings should be dequoted */
2077- sv = cstring_to_text_with_len (v .val .string .val ,v .val .string .len );
2078- }
2079- else
2080- {
2081- /* turn anything else into a json string */
2082- StringInfo jtext = makeStringInfo ();
2083- Jsonb * jb = JsonbValueToJsonb (& v );
2084-
2085- (void )JsonbToCString (jtext ,& jb -> root ,0 );
2086- sv = cstring_to_text_with_len (jtext -> data ,jtext -> len );
2087- }
2034+ values [0 ]= PointerGetDatum (JsonbValueAsText (& v ));
2035+ }
2036+ else
2037+ {
2038+ /* Not in text mode, just return the Jsonb */
2039+ Jsonb * val = JsonbValueToJsonb (& v );
20882040
2089- values [0 ]= PointerGetDatum (sv );
2090- }
2041+ values [0 ]= PointerGetDatum (val );
20912042}
20922043
20932044tuple = heap_form_tuple (ret_tdesc ,values ,nulls );
@@ -4430,7 +4381,6 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
44304381
44314382/*
44324383 * SQL function jsonb_set(jsonb, text[], jsonb, boolean)
4433- *
44344384 */
44354385Datum
44364386jsonb_set (PG_FUNCTION_ARGS )
@@ -4522,7 +4472,6 @@ jsonb_delete_path(PG_FUNCTION_ARGS)
45224472
45234473/*
45244474 * SQL function jsonb_insert(jsonb, text[], jsonb, boolean)
4525- *
45264475 */
45274476Datum
45284477jsonb_insert (PG_FUNCTION_ARGS )