@@ -84,6 +84,10 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims,int * dims,
8484Oid typoutputfunc ,bool use_line_feeds );
8585static void array_to_json_internal (Datum array ,StringInfo result ,bool use_line_feeds );
8686
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"
8791/*
8892 * Input.
8993 */
@@ -707,10 +711,20 @@ datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory,
707711case TYPCATEGORY_NUMERIC :
708712outputstr = OidOutputFunctionCall (typoutputfunc ,val );
709713/*
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.
713718 */
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 );
714728appendStringInfoString (result ,outputstr );
715729pfree (outputstr );
716730break ;
@@ -806,9 +820,10 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
806820typalign ,& elements ,& nulls ,
807821& nitems );
808822
809- /* can't have an array of arrays, so this is the only special case here */
810823if (element_type == RECORDOID )
811824tcategory = TYPCATEGORY_COMPOSITE ;
825+ else if (element_type == JSONOID )
826+ tcategory = TYPCATEGORY_JSON ;
812827else
813828tcategory = TypeCategory (element_type );
814829
@@ -876,6 +891,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
876891tcategory = TYPCATEGORY_ARRAY ;
877892else if (tupdesc -> attrs [i ]-> atttypid == RECORDOID )
878893tcategory = TYPCATEGORY_COMPOSITE ;
894+ else if (tupdesc -> attrs [i ]-> atttypid == JSONOID )
895+ tcategory = TYPCATEGORY_JSON ;
879896else
880897tcategory = TypeCategory (tupdesc -> attrs [i ]-> atttypid );
881898