Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Forbid numeric NaN in jsonpath
authorAlexander Korotkov <akorotkov@postgresql.org>
Sat, 11 Jul 2020 00:21:00 +0000 (03:21 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Sat, 11 Jul 2020 00:21:48 +0000 (03:21 +0300)
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

src/backend/utils/adt/jsonb_util.c
src/backend/utils/adt/jsonpath_exec.c
src/test/regress/expected/jsonb_jsonpath.out

index 04b70c805b44a220a60a1f9363cb0b08702d29f0..4eeffa1424346d029ba71699a81747913a232405 100644 (file)
@@ -1773,14 +1773,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);
 
index 25ec3dcd8029d09cfc00e43aefbeecaa58acd52d..f146767bfc3a0b261b52140af7be89f1c2e18aae 100644 (file)
@@ -1044,15 +1044,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",
@@ -1073,7 +1074,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",
index f8a5deb2b9955bdf88af780e57595e26f71d7a70..57332111b427b8f6b03a4a877847100520ffe960 100644 (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()');