@@ -84,6 +84,10 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims,int * dims,
84
84
Oid typoutputfunc , bool use_line_feeds );
85
85
static void array_to_json_internal (Datum array , StringInfo result , bool use_line_feeds );
86
86
87
+ /* fake type category for JSON so we can distinguish it in datum_to_json */
88
+ #define TYPCATEGORY_JSON 'j'
89
+ /* letters appearing in numeric output that aren't valid in a JSON number */
90
+ #define NON_NUMERIC_LETTER "NnAnIiFfTtYy"
87
91
/*
88
92
* Input.
89
93
*/
@@ -707,10 +711,20 @@ datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory,
707
711
case TYPCATEGORY_NUMERIC :
708
712
outputstr = OidOutputFunctionCall (typoutputfunc , val );
709
713
/*
710
- * Don't call escape_json here. Numeric output should
711
- * be a valid JSON number and JSON numbers shouldn't
712
- * be quoted.
714
+ * Don't call escape_json here if it's a valid JSON
715
+ * number. Numeric output should usually be a valid
716
+ * JSON number and JSON numbers shouldn't be quoted.
717
+ * Quote cases like "Nan" and "Infinity", however.
713
718
*/
719
+ if (strpbrk (outputstr ,NON_NUMERIC_LETTER ) == NULL )
720
+ appendStringInfoString (result , outputstr );
721
+ else
722
+ escape_json (result , outputstr );
723
+ pfree (outputstr );
724
+ break ;
725
+ case TYPCATEGORY_JSON :
726
+ /* JSON will already be escaped */
727
+ outputstr = OidOutputFunctionCall (typoutputfunc , val );
714
728
appendStringInfoString (result , outputstr );
715
729
pfree (outputstr );
716
730
break ;
@@ -806,9 +820,10 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
806
820
typalign , & elements , & nulls ,
807
821
& nitems );
808
822
809
- /* can't have an array of arrays, so this is the only special case here */
810
823
if (element_type == RECORDOID )
811
824
tcategory = TYPCATEGORY_COMPOSITE ;
825
+ else if (element_type == JSONOID )
826
+ tcategory = TYPCATEGORY_JSON ;
812
827
else
813
828
tcategory = TypeCategory (element_type );
814
829
@@ -876,6 +891,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
876
891
tcategory = TYPCATEGORY_ARRAY ;
877
892
else if (tupdesc -> attrs [i ]-> atttypid == RECORDOID )
878
893
tcategory = TYPCATEGORY_COMPOSITE ;
894
+ else if (tupdesc -> attrs [i ]-> atttypid == JSONOID )
895
+ tcategory = TYPCATEGORY_JSON ;
879
896
else
880
897
tcategory = TypeCategory (tupdesc -> attrs [i ]-> atttypid );
881
898
0 commit comments