Oid typoutputfunc, bool use_line_feeds);
static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds);
+/* fake type category for JSON so we can distinguish it in datum_to_json */
+#define TYPCATEGORY_JSON 'j'
+/* letters appearing in numeric output that aren't valid in a JSON number */
+#define NON_NUMERIC_LETTER "NnAnIiFfTtYy"
/*
* Input.
*/
case TYPCATEGORY_NUMERIC:
outputstr = OidOutputFunctionCall(typoutputfunc, val);
/*
- * Don't call escape_json here. Numeric output should
- * be a valid JSON number and JSON numbers shouldn't
- * be quoted.
+ * Don't call escape_json here if it's a valid JSON
+ * number. Numeric output should usually be a valid
+ * JSON number and JSON numbers shouldn't be quoted.
+ * Quote cases like "Nan" and "Infinity", however.
*/
+ if (strpbrk(outputstr,NON_NUMERIC_LETTER) == NULL)
+ appendStringInfoString(result, outputstr);
+ else
+ escape_json(result, outputstr);
+ pfree(outputstr);
+ break;
+ case TYPCATEGORY_JSON:
+ /* JSON will already be escaped */
+ outputstr = OidOutputFunctionCall(typoutputfunc, val);
appendStringInfoString(result, outputstr);
pfree(outputstr);
break;
typalign, &elements, &nulls,
&nitems);
- /* can't have an array of arrays, so this is the only special case here */
if (element_type == RECORDOID)
tcategory = TYPCATEGORY_COMPOSITE;
+ else if (element_type == JSONOID)
+ tcategory = TYPCATEGORY_JSON;
else
tcategory = TypeCategory(element_type);
tcategory = TYPCATEGORY_ARRAY;
else if (tupdesc->attrs[i]->atttypid == RECORDOID)
tcategory = TYPCATEGORY_COMPOSITE;
+ else if (tupdesc->attrs[i]->atttypid == JSONOID)
+ tcategory = TYPCATEGORY_JSON;
else
tcategory = TypeCategory(tupdesc->attrs[i]->atttypid);
{"f1":[5,6,7,8,9,10]}
(1 row)
+-- non-numeric output
+SELECT row_to_json(q)
+FROM (SELECT 'NaN'::float8 AS "float8field") q;
+ row_to_json
+-----------------------
+ {"float8field":"NaN"}
+(1 row)
+
+SELECT row_to_json(q)
+FROM (SELECT 'Infinity'::float8 AS "float8field") q;
+ row_to_json
+----------------------------
+ {"float8field":"Infinity"}
+(1 row)
+
+SELECT row_to_json(q)
+FROM (SELECT '-Infinity'::float8 AS "float8field") q;
+ row_to_json
+-----------------------------
+ {"float8field":"-Infinity"}
+(1 row)
+
+-- json input
+SELECT row_to_json(q)
+FROM (SELECT '{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::json AS "jsonfield") q;
+ row_to_json
+------------------------------------------------------------------
+ {"jsonfield":{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}}
+(1 row)
+
FROM rows q;
SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),false);
+
+-- non-numeric output
+SELECT row_to_json(q)
+FROM (SELECT 'NaN'::float8 AS "float8field") q;
+
+SELECT row_to_json(q)
+FROM (SELECT 'Infinity'::float8 AS "float8field") q;
+
+SELECT row_to_json(q)
+FROM (SELECT '-Infinity'::float8 AS "float8field") q;
+
+-- json input
+SELECT row_to_json(q)
+FROM (SELECT '{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::json AS "jsonfield") q;
+