diff options
Diffstat (limited to 'src/backend/utils/adt/json.c')
-rw-r--r-- | src/backend/utils/adt/json.c | 25 |
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); |