1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-22 21:53:06 +03:00

Fix a couple of cases of JSON output.

First, as noted by Itagaki Takahiro, a datum of type JSON doesn't
need to be escaped. Second, ensure that numeric output not in
the form of a legal JSON number is quoted and escaped.
This commit is contained in:
Andrew Dunstan
2012-02-20 15:01:03 -05:00
parent 5223f96d92
commit 83fcaffea2
3 changed files with 66 additions and 4 deletions

View File

@@ -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);