Skip to content

Commit df64650

Browse files
committed
Forbid numeric NaN in jsonpath
SQL standard doesn't define numeric Inf or NaN values. It appears even more ridiculous to support then in jsonpath assuming JSON doesn't support these values as well. This commit forbids returning NaN from .double(), which was previously allowed. NaN can't be result of inner-jsonpath computation over non-NaNs. So, we can not expect NaN in the jsonpath output. Reported-by: Tom Lane Discussion: https://postgr.es/m/203949.1591879542%40sss.pgh.pa.us Author: Alexander Korotkov Reviewed-by: Tom Lane Backpatch-through: 12
1 parent 0657181 commit df64650

File tree

3 files changed

+10
-25
lines changed

3 files changed

+10
-25
lines changed

src/backend/utils/adt/jsonb_util.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,14 +1773,6 @@ convertJsonbScalar(StringInfo buffer, JEntry *jentry, JsonbValue *scalarVal)
17731773
break;
17741774

17751775
case jbvNumeric:
1776-
/* replace numeric NaN with string "NaN" */
1777-
if (numeric_is_nan(scalarVal->val.numeric))
1778-
{
1779-
appendToBuffer(buffer, "NaN", 3);
1780-
*jentry = 3;
1781-
break;
1782-
}
1783-
17841776
numlen = VARSIZE_ANY(scalarVal->val.numeric);
17851777
padlen = padBufferToInt(buffer);
17861778

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,15 +1044,16 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
10441044
{
10451045
char *tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
10461046
NumericGetDatum(jb->val.numeric)));
1047+
double val;
10471048
bool have_error = false;
10481049

1049-
(void) float8in_internal_opt_error(tmp,
1050-
NULL,
1051-
"double precision",
1052-
tmp,
1053-
&have_error);
1050+
val = float8in_internal_opt_error(tmp,
1051+
NULL,
1052+
"double precision",
1053+
tmp,
1054+
&have_error);
10541055

1055-
if (have_error)
1056+
if (have_error || isinf(val) || isnan(val))
10561057
RETURN_ERROR(ereport(ERROR,
10571058
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
10581059
errmsg("numeric argument of jsonpath item method .%s() is out of range for type double precision",
@@ -1073,7 +1074,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
10731074
tmp,
10741075
&have_error);
10751076

1076-
if (have_error || isinf(val))
1077+
if (have_error || isinf(val) || isnan(val))
10771078
RETURN_ERROR(ereport(ERROR,
10781079
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
10791080
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a double precision number",

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,17 +1500,9 @@ ERROR: string argument of jsonpath item method .double() is not a valid represe
15001500
select jsonb_path_query('1e1000', '$.double()');
15011501
ERROR: numeric argument of jsonpath item method .double() is out of range for type double precision
15021502
select jsonb_path_query('"nan"', '$.double()');
1503-
jsonb_path_query
1504-
------------------
1505-
"NaN"
1506-
(1 row)
1507-
1503+
ERROR: string argument of jsonpath item method .double() is not a valid representation of a double precision number
15081504
select jsonb_path_query('"NaN"', '$.double()');
1509-
jsonb_path_query
1510-
------------------
1511-
"NaN"
1512-
(1 row)
1513-
1505+
ERROR: string argument of jsonpath item method .double() is not a valid representation of a double precision number
15141506
select jsonb_path_query('"inf"', '$.double()');
15151507
ERROR: string argument of jsonpath item method .double() is not a valid representation of a double precision number
15161508
select jsonb_path_query('"-inf"', '$.double()');

0 commit comments

Comments
 (0)