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
This commit is contained in:
Alexander Korotkov 2020-07-11 03:21:00 +03:00
parent 3ec5f6b53d
commit f4ae676e31
3 changed files with 10 additions and 25 deletions

View File

@ -1728,14 +1728,6 @@ convertJsonbScalar(StringInfo buffer, JEntry *jentry, JsonbValue *scalarVal)
break;
case jbvNumeric:
/* replace numeric NaN with string "NaN" */
if (numeric_is_nan(scalarVal->val.numeric))
{
appendToBuffer(buffer, "NaN", 3);
*jentry = 3;
break;
}
numlen = VARSIZE_ANY(scalarVal->val.numeric);
padlen = padBufferToInt(buffer);

View File

@ -975,15 +975,16 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
{
char *tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
NumericGetDatum(jb->val.numeric)));
double val;
bool have_error = false;
(void) float8in_internal_opt_error(tmp,
NULL,
"double precision",
tmp,
&have_error);
val = float8in_internal_opt_error(tmp,
NULL,
"double precision",
tmp,
&have_error);
if (have_error)
if (have_error || isinf(val) || isnan(val))
RETURN_ERROR(ereport(ERROR,
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
errmsg("numeric argument of jsonpath item method .%s() is out of range for type double precision",
@ -1004,7 +1005,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
tmp,
&have_error);
if (have_error || isinf(val))
if (have_error || isinf(val) || isnan(val))
RETURN_ERROR(ereport(ERROR,
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a double precision number",

View File

@ -1500,17 +1500,9 @@ ERROR: string argument of jsonpath item method .double() is not a valid represe
select jsonb_path_query('1e1000', '$.double()');
ERROR: numeric argument of jsonpath item method .double() is out of range for type double precision
select jsonb_path_query('"nan"', '$.double()');
jsonb_path_query
------------------
"NaN"
(1 row)
ERROR: string argument of jsonpath item method .double() is not a valid representation of a double precision number
select jsonb_path_query('"NaN"', '$.double()');
jsonb_path_query
------------------
"NaN"
(1 row)
ERROR: string argument of jsonpath item method .double() is not a valid representation of a double precision number
select jsonb_path_query('"inf"', '$.double()');
ERROR: string argument of jsonpath item method .double() is not a valid representation of a double precision number
select jsonb_path_query('"-inf"', '$.double()');