Skip to content

Commit 92d2ab7

Browse files
committed
Rationalize and improve error messages for some jsonpath items
This is a followup to commit 66ea94e. Error mssages concerning incorrect formats for date-time types are unified and parameterized, instead of using a fully separate error message for each type. Similarly, error messages regarding numeric and string arguments to certain items are standardized, and instead of saying that the argument is out of range simply say that it is invalid. The actual invalid arguments to these itesm are now shown in the error message. Error messages relating to numeric inputs of Nan or Infinity are made more informative. Jeevan Chalke and Kyotaro Horiguchi, with some input from Tom Lane. Discussion: https://postgr.es/m/[email protected]
1 parent ef5e2e9 commit 92d2ab7

File tree

2 files changed

+95
-81
lines changed

2 files changed

+95
-81
lines changed

src/backend/utils/adt/jsonpath_exec.c

+50-36
Original file line numberDiff line numberDiff line change
@@ -1051,10 +1051,15 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
10511051
tmp,
10521052
(Node *) &escontext);
10531053

1054-
if (escontext.error_occurred || isinf(val) || isnan(val))
1054+
if (escontext.error_occurred)
1055+
RETURN_ERROR(ereport(ERROR,
1056+
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1057+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type double precision",
1058+
tmp, jspOperationName(jsp->type)))));
1059+
if (isinf(val) || isnan(val))
10551060
RETURN_ERROR(ereport(ERROR,
10561061
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1057-
errmsg("numeric argument of jsonpath item method .%s() is out of range for type double precision",
1062+
errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
10581063
jspOperationName(jsp->type)))));
10591064
res = jperOk;
10601065
}
@@ -1072,10 +1077,15 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
10721077
tmp,
10731078
(Node *) &escontext);
10741079

1075-
if (escontext.error_occurred || isinf(val) || isnan(val))
1080+
if (escontext.error_occurred)
10761081
RETURN_ERROR(ereport(ERROR,
10771082
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1078-
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a double precision number",
1083+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type double precision",
1084+
tmp, jspOperationName(jsp->type)))));
1085+
if (isinf(val) || isnan(val))
1086+
RETURN_ERROR(ereport(ERROR,
1087+
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1088+
errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
10791089
jspOperationName(jsp->type)))));
10801090

10811091
jb = &jbv;
@@ -1158,7 +1168,9 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
11581168
if (have_error)
11591169
RETURN_ERROR(ereport(ERROR,
11601170
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1161-
errmsg("numeric argument of jsonpath item method .%s() is out of range for type bigint",
1171+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type bigint",
1172+
DatumGetCString(DirectFunctionCall1(numeric_out,
1173+
NumericGetDatum(jb->val.numeric))),
11621174
jspOperationName(jsp->type)))));
11631175

11641176
datum = Int64GetDatum(val);
@@ -1180,8 +1192,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
11801192
if (!noerr || escontext.error_occurred)
11811193
RETURN_ERROR(ereport(ERROR,
11821194
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1183-
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a big integer",
1184-
jspOperationName(jsp->type)))));
1195+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type bigint",
1196+
tmp, jspOperationName(jsp->type)))));
11851197
res = jperOk;
11861198
}
11871199

@@ -1232,8 +1244,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
12321244
if (!noerr || escontext.error_occurred)
12331245
RETURN_ERROR(ereport(ERROR,
12341246
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1235-
errmsg("numeric argument of jsonpath item method .%s() is out of range for type boolean",
1236-
jspOperationName(jsp->type)))));
1247+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type boolean",
1248+
tmp, jspOperationName(jsp->type)))));
12371249

12381250
ival = DatumGetInt32(datum);
12391251
if (ival == 0)
@@ -1252,8 +1264,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
12521264
if (!parse_bool(tmp, &bval))
12531265
RETURN_ERROR(ereport(ERROR,
12541266
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1255-
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a boolean",
1256-
jspOperationName(jsp->type)))));
1267+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type boolean",
1268+
tmp, jspOperationName(jsp->type)))));
12571269

12581270
res = jperOk;
12591271
}
@@ -1289,7 +1301,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
12891301
if (numeric_is_nan(num) || numeric_is_inf(num))
12901302
RETURN_ERROR(ereport(ERROR,
12911303
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1292-
errmsg("numeric argument of jsonpath item method .%s() is out of range for type decimal or number",
1304+
errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
12931305
jspOperationName(jsp->type)))));
12941306

12951307
if (jsp->type == jpiDecimal)
@@ -1314,14 +1326,14 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
13141326
if (!noerr || escontext.error_occurred)
13151327
RETURN_ERROR(ereport(ERROR,
13161328
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1317-
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a decimal or number",
1318-
jspOperationName(jsp->type)))));
1329+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type numeric",
1330+
numstr, jspOperationName(jsp->type)))));
13191331

13201332
num = DatumGetNumeric(datum);
13211333
if (numeric_is_nan(num) || numeric_is_inf(num))
13221334
RETURN_ERROR(ereport(ERROR,
13231335
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1324-
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a decimal or number",
1336+
errmsg("NaN or Infinity is not allowed for jsonpath item method .%s()",
13251337
jspOperationName(jsp->type)))));
13261338

13271339
res = jperOk;
@@ -1403,8 +1415,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
14031415
if (!noerr || escontext.error_occurred)
14041416
RETURN_ERROR(ereport(ERROR,
14051417
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1406-
errmsg("string argument of jsonpath item method .%s() is not a valid representation of a decimal or number",
1407-
jspOperationName(jsp->type)))));
1418+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type numeric",
1419+
numstr, jspOperationName(jsp->type)))));
14081420

14091421
num = DatumGetNumeric(numdatum);
14101422
pfree(arrtypmod);
@@ -1436,7 +1448,9 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
14361448
if (have_error)
14371449
RETURN_ERROR(ereport(ERROR,
14381450
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1439-
errmsg("numeric argument of jsonpath item method .%s() is out of range for type integer",
1451+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type integer",
1452+
DatumGetCString(DirectFunctionCall1(numeric_out,
1453+
NumericGetDatum(jb->val.numeric))),
14401454
jspOperationName(jsp->type)))));
14411455

14421456
datum = Int32GetDatum(val);
@@ -1458,8 +1472,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
14581472
if (!noerr || escontext.error_occurred)
14591473
RETURN_ERROR(ereport(ERROR,
14601474
(errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1461-
errmsg("string argument of jsonpath item method .%s() is not a valid representation of an integer",
1462-
jspOperationName(jsp->type)))));
1475+
errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type integer",
1476+
tmp, jspOperationName(jsp->type)))));
14631477
res = jperOk;
14641478
}
14651479

@@ -2373,8 +2387,8 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
23732387
if (jsp->type == jpiDatetime)
23742388
RETURN_ERROR(ereport(ERROR,
23752389
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2376-
errmsg("datetime format is not recognized: \"%s\"",
2377-
text_to_cstring(datetime)),
2390+
errmsg("%s format is not recognized: \"%s\"",
2391+
"datetime", text_to_cstring(datetime)),
23782392
errhint("Use a datetime template argument to specify the input data format."))));
23792393
else
23802394
RETURN_ERROR(ereport(ERROR,
@@ -2406,8 +2420,8 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
24062420
case TIMETZOID:
24072421
RETURN_ERROR(ereport(ERROR,
24082422
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2409-
errmsg("date format is not recognized: \"%s\"",
2410-
text_to_cstring(datetime)))));
2423+
errmsg("%s format is not recognized: \"%s\"",
2424+
"date", text_to_cstring(datetime)))));
24112425
break;
24122426
case TIMESTAMPOID:
24132427
value = DirectFunctionCall1(timestamp_date,
@@ -2434,8 +2448,8 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
24342448
case DATEOID:
24352449
RETURN_ERROR(ereport(ERROR,
24362450
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2437-
errmsg("time format is not recognized: \"%s\"",
2438-
text_to_cstring(datetime)))));
2451+
errmsg("%s format is not recognized: \"%s\"",
2452+
"time", text_to_cstring(datetime)))));
24392453
break;
24402454
case TIMEOID: /* Nothing to do for TIME */
24412455
break;
@@ -2487,8 +2501,8 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
24872501
case TIMESTAMPOID:
24882502
RETURN_ERROR(ereport(ERROR,
24892503
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2490-
errmsg("time_tz format is not recognized: \"%s\"",
2491-
text_to_cstring(datetime)))));
2504+
errmsg("%s format is not recognized: \"%s\"",
2505+
"time_tz", text_to_cstring(datetime)))));
24922506
break;
24932507
case TIMEOID:
24942508
checkTimezoneIsUsedForCast(cxt->useTz,
@@ -2538,8 +2552,8 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
25382552
case TIMETZOID:
25392553
RETURN_ERROR(ereport(ERROR,
25402554
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2541-
errmsg("timestamp format is not recognized: \"%s\"",
2542-
text_to_cstring(datetime)))));
2555+
errmsg("%s format is not recognized: \"%s\"",
2556+
"timestamp", text_to_cstring(datetime)))));
25432557
break;
25442558
case TIMESTAMPOID: /* Nothing to do for TIMESTAMP */
25452559
break;
@@ -2565,10 +2579,10 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
25652579
result = DatumGetTimestamp(value);
25662580
AdjustTimestampForTypmod(&result, time_precision,
25672581
(Node *) &escontext);
2568-
if (escontext.error_occurred)
2582+
if (escontext.error_occurred) /* should not happen */
25692583
RETURN_ERROR(ereport(ERROR,
25702584
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2571-
errmsg("numeric argument of jsonpath item method .%s() is out of range for type integer",
2585+
errmsg("time precision of jsonpath item method .%s() is invalid",
25722586
jspOperationName(jsp->type)))));
25732587
value = TimestampGetDatum(result);
25742588

@@ -2594,8 +2608,8 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
25942608
case TIMETZOID:
25952609
RETURN_ERROR(ereport(ERROR,
25962610
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2597-
errmsg("timestamp_tz format is not recognized: \"%s\"",
2598-
text_to_cstring(datetime)))));
2611+
errmsg("%s format is not recognized: \"%s\"",
2612+
"timestamp_tz", text_to_cstring(datetime)))));
25992613
break;
26002614
case TIMESTAMPOID:
26012615
checkTimezoneIsUsedForCast(cxt->useTz,
@@ -2621,10 +2635,10 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
26212635
result = DatumGetTimestampTz(value);
26222636
AdjustTimestampForTypmod(&result, time_precision,
26232637
(Node *) &escontext);
2624-
if (escontext.error_occurred)
2638+
if (escontext.error_occurred) /* should not happen */
26252639
RETURN_ERROR(ereport(ERROR,
26262640
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2627-
errmsg("numeric argument of jsonpath item method .%s() is out of range for type integer",
2641+
errmsg("time precision of jsonpath item method .%s() is invalid",
26282642
jspOperationName(jsp->type)))));
26292643
value = TimestampTzGetDatum(result);
26302644

0 commit comments

Comments
 (0)