Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit83fcaff

Browse files
committed
Fix a couple of cases of JSON output.
First, as noted by Itagaki Takahiro, a datum of type JSON doesn'tneed to be escaped. Second, ensure that numeric output not inthe form of a legal JSON number is quoted and escaped.
1 parent5223f96 commit83fcaff

File tree

3 files changed

+66
-4
lines changed

3 files changed

+66
-4
lines changed

‎src/backend/utils/adt/json.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ static void array_dim_to_json(StringInfo result, int dim, int ndims,int * dims,
8484
Oidtypoutputfunc,booluse_line_feeds);
8585
staticvoidarray_to_json_internal(Datumarray,StringInforesult,booluse_line_feeds);
8686

87+
/* fake type category for JSON so we can distinguish it in datum_to_json */
88+
#defineTYPCATEGORY_JSON 'j'
89+
/* letters appearing in numeric output that aren't valid in a JSON number */
90+
#defineNON_NUMERIC_LETTER "NnAnIiFfTtYy"
8791
/*
8892
* Input.
8993
*/
@@ -707,10 +711,20 @@ datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory,
707711
caseTYPCATEGORY_NUMERIC:
708712
outputstr=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+
caseTYPCATEGORY_JSON:
726+
/* JSON will already be escaped */
727+
outputstr=OidOutputFunctionCall(typoutputfunc,val);
714728
appendStringInfoString(result,outputstr);
715729
pfree(outputstr);
716730
break;
@@ -806,9 +820,10 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
806820
typalign,&elements,&nulls,
807821
&nitems);
808822

809-
/* can't have an array of arrays, so this is the only special case here */
810823
if (element_type==RECORDOID)
811824
tcategory=TYPCATEGORY_COMPOSITE;
825+
elseif (element_type==JSONOID)
826+
tcategory=TYPCATEGORY_JSON;
812827
else
813828
tcategory=TypeCategory(element_type);
814829

@@ -876,6 +891,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
876891
tcategory=TYPCATEGORY_ARRAY;
877892
elseif (tupdesc->attrs[i]->atttypid==RECORDOID)
878893
tcategory=TYPCATEGORY_COMPOSITE;
894+
elseif (tupdesc->attrs[i]->atttypid==JSONOID)
895+
tcategory=TYPCATEGORY_JSON;
879896
else
880897
tcategory=TypeCategory(tupdesc->attrs[i]->atttypid);
881898

‎src/test/regress/expected/json.out

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,3 +367,33 @@ SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),
367367
{"f1":[5,6,7,8,9,10]}
368368
(1 row)
369369

370+
-- non-numeric output
371+
SELECT row_to_json(q)
372+
FROM (SELECT 'NaN'::float8 AS "float8field") q;
373+
row_to_json
374+
-----------------------
375+
{"float8field":"NaN"}
376+
(1 row)
377+
378+
SELECT row_to_json(q)
379+
FROM (SELECT 'Infinity'::float8 AS "float8field") q;
380+
row_to_json
381+
----------------------------
382+
{"float8field":"Infinity"}
383+
(1 row)
384+
385+
SELECT row_to_json(q)
386+
FROM (SELECT '-Infinity'::float8 AS "float8field") q;
387+
row_to_json
388+
-----------------------------
389+
{"float8field":"-Infinity"}
390+
(1 row)
391+
392+
-- json input
393+
SELECT row_to_json(q)
394+
FROM (SELECT '{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::json AS "jsonfield") q;
395+
row_to_json
396+
------------------------------------------------------------------
397+
{"jsonfield":{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}}
398+
(1 row)
399+

‎src/test/regress/sql/json.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,18 @@ SELECT row_to_json(q,true)
9797
FROM rows q;
9898

9999
SELECT row_to_json(row((select array_agg(x)as dfrom generate_series(5,10) x)),false);
100+
101+
-- non-numeric output
102+
SELECT row_to_json(q)
103+
FROM (SELECT'NaN'::float8AS"float8field") q;
104+
105+
SELECT row_to_json(q)
106+
FROM (SELECT'Infinity'::float8AS"float8field") q;
107+
108+
SELECT row_to_json(q)
109+
FROM (SELECT'-Infinity'::float8AS"float8field") q;
110+
111+
-- json input
112+
SELECT row_to_json(q)
113+
FROM (SELECT'{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::jsonAS"jsonfield") q;
114+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp