From fef57b0b78d3e2c1d815fdfa66593d7b39964478 Mon Sep 17 00:00:00 2001
From: Jeevan Chalke <jeevan.chalke@enterprisedb.com>
Date: Fri, 2 Feb 2024 08:30:05 +0530
Subject: [PATCH v1 2/4] Improve error message for NaN or Infinity inputs for
 jsonpath item.

Jeevan Chalke, per suggestion from Tom Lane.
---
 src/backend/utils/adt/jsonpath_exec.c        | 18 ++++++++++++++----
 src/test/regress/expected/jsonb_jsonpath.out | 24 ++++++++++++------------
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index 7f11d52..0d1d1b1 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -1049,11 +1049,16 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 											tmp,
 											(Node *) &escontext);
 
-					if (escontext.error_occurred || isinf(val) || isnan(val))
+					if (escontext.error_occurred)
 						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",
 													 jspOperationName(jsp->type)))));
+					if (isinf(val) || isnan(val))
+						RETURN_ERROR(ereport(ERROR,
+											 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
+											  errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
+													 jspOperationName(jsp->type)))));
 					res = jperOk;
 				}
 				else if (jb->type == jbvString)
@@ -1070,11 +1075,16 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 											tmp,
 											(Node *) &escontext);
 
-					if (escontext.error_occurred || isinf(val) || isnan(val))
+					if (escontext.error_occurred)
 						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",
 													 jspOperationName(jsp->type)))));
+					if (isinf(val) || isnan(val))
+						RETURN_ERROR(ereport(ERROR,
+											 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
+											  errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
+													 jspOperationName(jsp->type)))));
 
 					jb = &jbv;
 					jb->type = jbvNumeric;
@@ -1287,7 +1297,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					if (numeric_is_nan(num) || numeric_is_inf(num))
 						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 decimal or number",
+											  errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
 													 jspOperationName(jsp->type)))));
 
 					if (jsp->type == jpiDecimal)
@@ -1319,7 +1329,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					if (numeric_is_nan(num) || numeric_is_inf(num))
 						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 decimal or number",
+											  errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
 													 jspOperationName(jsp->type)))));
 
 					res = jperOk;
diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out
index eea2af3..95408ad 100644
--- a/src/test/regress/expected/jsonb_jsonpath.out
+++ b/src/test/regress/expected/jsonb_jsonpath.out
@@ -1500,13 +1500,13 @@ 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()');
-ERROR:  string argument of jsonpath item method .double() is not a valid representation of a double precision number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .double()
 select jsonb_path_query('"NaN"', '$.double()');
-ERROR:  string argument of jsonpath item method .double() is not a valid representation of a double precision number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .double()
 select jsonb_path_query('"inf"', '$.double()');
-ERROR:  string argument of jsonpath item method .double() is not a valid representation of a double precision number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .double()
 select jsonb_path_query('"-inf"', '$.double()');
-ERROR:  string argument of jsonpath item method .double() is not a valid representation of a double precision number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .double()
 select jsonb_path_query('"inf"', '$.double()', silent => true);
  jsonb_path_query 
 ------------------
@@ -2152,13 +2152,13 @@ select jsonb_path_query('1e1000', '$.decimal()');
 (1 row)
 
 select jsonb_path_query('"nan"', '$.decimal()');
-ERROR:  string argument of jsonpath item method .decimal() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .decimal()
 select jsonb_path_query('"NaN"', '$.decimal()');
-ERROR:  string argument of jsonpath item method .decimal() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .decimal()
 select jsonb_path_query('"inf"', '$.decimal()');
-ERROR:  string argument of jsonpath item method .decimal() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .decimal()
 select jsonb_path_query('"-inf"', '$.decimal()');
-ERROR:  string argument of jsonpath item method .decimal() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .decimal()
 select jsonb_path_query('"inf"', '$.decimal()', silent => true);
  jsonb_path_query 
 ------------------
@@ -2448,13 +2448,13 @@ select jsonb_path_query('1e1000', '$.number()');
 (1 row)
 
 select jsonb_path_query('"nan"', '$.number()');
-ERROR:  string argument of jsonpath item method .number() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .number()
 select jsonb_path_query('"NaN"', '$.number()');
-ERROR:  string argument of jsonpath item method .number() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .number()
 select jsonb_path_query('"inf"', '$.number()');
-ERROR:  string argument of jsonpath item method .number() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .number()
 select jsonb_path_query('"-inf"', '$.number()');
-ERROR:  string argument of jsonpath item method .number() is not a valid representation of a decimal or number
+ERROR:  NaN or Infinity is not allowed for jsonpath item method .number()
 select jsonb_path_query('"inf"', '$.number()', silent => true);
  jsonb_path_query 
 ------------------
-- 
1.8.3.1

