aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/json.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/json.c')
-rw-r--r--src/backend/utils/adt/json.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 60addf2871f..feda0e00357 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -84,6 +84,10 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims,int * dims,
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.
*/
@@ -707,10 +711,20 @@ datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory,
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;
@@ -806,9 +820,10 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
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);
@@ -876,6 +891,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
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);