From 29ceacc3f93720d3ebb7e7e999f8b7fe9622389c Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 23 Apr 2019 17:43:09 +0300 Subject: [PATCH] Improve error reporting in jsonpath This commit contains multiple improvements to error reporting in jsonpath including but not limited to getting rid of following things: * definition of error messages in macros, * errdetail() when valueable information could fit to errmsg(), * word "singleton" which is not properly explained anywhere, * line breaks in error messages. Reported-by: Tom Lane Discussion: https://postgr.es/m/14890.1555523005%40sss.pgh.pa.us Author: Alexander Korotkov Reviewed-by: Tom Lane --- src/backend/utils/adt/jsonpath_exec.c | 120 +++++---------- src/backend/utils/adt/jsonpath_gram.y | 6 +- src/backend/utils/adt/jsonpath_scan.l | 23 ++- src/test/regress/expected/jsonb_jsonpath.out | 137 ++++++------------ src/test/regress/expected/jsonpath.out | 61 +++----- .../regress/expected/jsonpath_encoding.out | 18 +-- .../regress/expected/jsonpath_encoding_1.out | 12 +- 7 files changed, 130 insertions(+), 247 deletions(-) diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index 0a263ad8b3..2789ed2371 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -77,16 +77,6 @@ #include "utils/varlena.h" -/* Standard error message for SQL/JSON errors */ -#define ERRMSG_JSON_ARRAY_NOT_FOUND "SQL/JSON array not found" -#define ERRMSG_JSON_OBJECT_NOT_FOUND "SQL/JSON object not found" -#define ERRMSG_JSON_MEMBER_NOT_FOUND "SQL/JSON member not found" -#define ERRMSG_JSON_NUMBER_NOT_FOUND "SQL/JSON number not found" -#define ERRMSG_JSON_SCALAR_REQUIRED "SQL/JSON scalar required" -#define ERRMSG_SINGLETON_JSON_ITEM_REQUIRED "singleton SQL/JSON item required" -#define ERRMSG_NON_NUMERIC_JSON_ITEM "non-numeric SQL/JSON item" -#define ERRMSG_INVALID_JSON_SUBSCRIPT "invalid SQL/JSON subscript" - /* * Represents "base object" and it's "id" for .keyvalue() evaluation. */ @@ -349,8 +339,7 @@ jsonb_path_match(PG_FUNCTION_ARGS) if (!silent) ereport(ERROR, (errcode(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED), - errmsg(ERRMSG_SINGLETON_JSON_ITEM_REQUIRED), - errdetail("expression should return a singleton boolean"))); + errmsg("single boolean result is expected"))); PG_RETURN_NULL(); } @@ -498,8 +487,8 @@ executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb containing jsonpath variables " - "is not an object"))); + errmsg("\"vars\" argument is not an object"), + errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object."))); } cxt.vars = vars; @@ -608,24 +597,16 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, } else if (!jspIgnoreStructuralErrors(cxt)) { - StringInfoData keybuf; - char *keystr; - Assert(found); if (!jspThrowErrors(cxt)) return jperError; - initStringInfo(&keybuf); - - keystr = pnstrdup(key.val.string.val, key.val.string.len); - escape_json(&keybuf, keystr); - ereport(ERROR, (errcode(ERRCODE_JSON_MEMBER_NOT_FOUND), \ - errmsg(ERRMSG_JSON_MEMBER_NOT_FOUND), - errdetail("JSON object does not contain key %s", - keybuf.data))); + errmsg("JSON object does not contain key \"%s\"", + pnstrdup(key.val.string.val, + key.val.string.len)))); } } else if (unwrap && JsonbType(jb) == jbvArray) @@ -635,9 +616,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, Assert(found); RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_JSON_MEMBER_NOT_FOUND), - errmsg(ERRMSG_JSON_MEMBER_NOT_FOUND), - errdetail("jsonpath member accessor can " - "only be applied to an object")))); + errmsg("jsonpath member accessor can only be applied to an object")))); } break; @@ -666,9 +645,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, else if (!jspIgnoreStructuralErrors(cxt)) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_JSON_ARRAY_NOT_FOUND), - errmsg(ERRMSG_JSON_ARRAY_NOT_FOUND), - errdetail("jsonpath wildcard array accessor " - "can only be applied to an array")))); + errmsg("jsonpath wildcard array accessor can only be applied to an array")))); break; case jpiIndexArray: @@ -716,9 +693,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, index_to >= size)) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_INVALID_JSON_SUBSCRIPT), - errmsg(ERRMSG_INVALID_JSON_SUBSCRIPT), - errdetail("jsonpath array subscript is " - "out of bounds")))); + errmsg("jsonpath array subscript is out of bounds")))); if (index_from < 0) index_from = 0; @@ -775,9 +750,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, { RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_JSON_ARRAY_NOT_FOUND), - errmsg(ERRMSG_JSON_ARRAY_NOT_FOUND), - errdetail("jsonpath array accessor can " - "only be applied to an array")))); + errmsg("jsonpath array accessor can only be applied to an array")))); } break; @@ -789,8 +762,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, bool hasNext = jspGetNext(jsp, &elem); if (cxt->innermostArraySize < 0) - elog(ERROR, "evaluating jsonpath LAST outside of " - "array subscript"); + elog(ERROR, "evaluating jsonpath LAST outside of array subscript"); if (!hasNext && !found) { @@ -832,9 +804,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, Assert(found); RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_JSON_OBJECT_NOT_FOUND), - errmsg(ERRMSG_JSON_OBJECT_NOT_FOUND), - errdetail("jsonpath wildcard member accessor " - "can only be applied to an object")))); + errmsg("jsonpath wildcard member accessor can only be applied to an object")))); } break; @@ -964,10 +934,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, if (!jspIgnoreStructuralErrors(cxt)) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_JSON_ARRAY_NOT_FOUND), - errmsg(ERRMSG_JSON_ARRAY_NOT_FOUND), - errdetail("jsonpath item method .%s() " - "can only be applied to an array", - jspOperationName(jsp->type))))); + errmsg("jsonpath item method .%s() can only be applied to an array", + jspOperationName(jsp->type))))); break; } @@ -1020,11 +988,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, if (have_error) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_NON_NUMERIC_JSON_ITEM), - errmsg(ERRMSG_NON_NUMERIC_JSON_ITEM), - errdetail("jsonpath item method .%s() " - "can only be applied to " - "a numeric value", - jspOperationName(jsp->type))))); + errmsg("jsonpath item method .%s() can only be applied to a numeric value", + jspOperationName(jsp->type))))); res = jperOk; } else if (jb->type == jbvString) @@ -1044,10 +1009,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, if (have_error || isinf(val)) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_NON_NUMERIC_JSON_ITEM), - errmsg(ERRMSG_NON_NUMERIC_JSON_ITEM), - errdetail("jsonpath item method .%s() can " - "only be applied to a numeric value", - jspOperationName(jsp->type))))); + errmsg("jsonpath item method .%s() can only be applied to a numeric value", + jspOperationName(jsp->type))))); jb = &jbv; jb->type = jbvNumeric; @@ -1059,11 +1022,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, if (res == jperNotFound) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_NON_NUMERIC_JSON_ITEM), - errmsg(ERRMSG_NON_NUMERIC_JSON_ITEM), - errdetail("jsonpath item method .%s() " - "can only be applied to a " - "string or numeric value", - jspOperationName(jsp->type))))); + errmsg("jsonpath item method .%s() can only be applied to a string or numeric value", + jspOperationName(jsp->type))))); res = executeNextItem(cxt, jsp, NULL, jb, found, true); } @@ -1546,19 +1506,15 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, !(lval = getScalar(JsonValueListHead(&lseq), jbvNumeric))) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED), - errmsg(ERRMSG_SINGLETON_JSON_ITEM_REQUIRED), - errdetail("left operand of binary jsonpath operator %s " - "is not a singleton numeric value", - jspOperationName(jsp->type))))); + errmsg("left operand of jsonpath operator %s is not a single numeric value", + jspOperationName(jsp->type))))); if (JsonValueListLength(&rseq) != 1 || !(rval = getScalar(JsonValueListHead(&rseq), jbvNumeric))) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED), - errmsg(ERRMSG_SINGLETON_JSON_ITEM_REQUIRED), - errdetail("right operand of binary jsonpath operator %s " - "is not a singleton numeric value", - jspOperationName(jsp->type))))); + errmsg("right operand of jsonpath operator %s is not a single numeric value", + jspOperationName(jsp->type))))); if (jspThrowErrors(cxt)) { @@ -1625,10 +1581,8 @@ executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_JSON_NUMBER_NOT_FOUND), - errmsg(ERRMSG_JSON_NUMBER_NOT_FOUND), - errdetail("operand of unary jsonpath operator %s " - "is not a numeric value", - jspOperationName(jsp->type))))); + errmsg("operand of unary jsonpath operator %s is not a numeric value", + jspOperationName(jsp->type))))); } if (func) @@ -1738,10 +1692,8 @@ executeNumericItemMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, if (!(jb = getScalar(jb, jbvNumeric))) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_NON_NUMERIC_JSON_ITEM), - errmsg(ERRMSG_NON_NUMERIC_JSON_ITEM), - errdetail("jsonpath item method .%s() can only " - "be applied to a numeric value", - jspOperationName(jsp->type))))); + errmsg("jsonpath item method .%s() can only be applied to a numeric value", + jspOperationName(jsp->type))))); datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric)); @@ -1799,10 +1751,8 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, if (JsonbType(jb) != jbvObject || jb->type != jbvBinary) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_JSON_OBJECT_NOT_FOUND), - errmsg(ERRMSG_JSON_OBJECT_NOT_FOUND), - errdetail("jsonpath item method .%s() " - "can only be applied to an object", - jspOperationName(jsp->type))))); + errmsg("jsonpath item method .%s() can only be applied to an object", + jspOperationName(jsp->type))))); jbc = jb->val.binary.data; @@ -1984,7 +1934,7 @@ getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("cannot find jsonpath variable '%s'", + errmsg("cannot find jsonpath variable \"%s\"", pnstrdup(varName, varNameLength)))); } @@ -2144,9 +2094,7 @@ getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, !(jbv = getScalar(JsonValueListHead(&found), jbvNumeric))) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_INVALID_JSON_SUBSCRIPT), - errmsg(ERRMSG_INVALID_JSON_SUBSCRIPT), - errdetail("jsonpath array subscript is not a " - "singleton numeric value")))); + errmsg("jsonpath array subscript is not a single numeric value")))); numeric_index = DirectFunctionCall2(numeric_trunc, NumericGetDatum(jbv->val.numeric), @@ -2158,9 +2106,7 @@ getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, if (have_error) RETURN_ERROR(ereport(ERROR, (errcode(ERRCODE_INVALID_JSON_SUBSCRIPT), - errmsg(ERRMSG_INVALID_JSON_SUBSCRIPT), - errdetail("jsonpath array subscript is " - "out of integer range")))); + errmsg("jsonpath array subscript is out of integer range")))); return jperOk; } diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y index 1534b038dd..22c2089f78 100644 --- a/src/backend/utils/adt/jsonpath_gram.y +++ b/src/backend/utils/adt/jsonpath_gram.y @@ -511,7 +511,11 @@ makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern, cflags |= REG_EXPANDED; break; default: - yyerror(NULL, "unrecognized flag of LIKE_REGEX predicate"); + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid input syntax for type %s", "jsonpath"), + errdetail("unrecognized flag character \"%c\" in LIKE_REGEX predicate", + flags->val[i]))); break; } } diff --git a/src/backend/utils/adt/jsonpath_scan.l b/src/backend/utils/adt/jsonpath_scan.l index 72bb5e3937..6ab7c5c9c6 100644 --- a/src/backend/utils/adt/jsonpath_scan.l +++ b/src/backend/utils/adt/jsonpath_scan.l @@ -142,9 +142,9 @@ hex_fail \\x{hex_dig}{0,1} {hex_char} { parseHexChar(yytext); } -{unicode}*{unicodefail} { yyerror(NULL, "Unicode sequence is invalid"); } +{unicode}*{unicodefail} { yyerror(NULL, "invalid unicode sequence"); } -{hex_fail} { yyerror(NULL, "Hex character sequence is invalid"); } +{hex_fail} { yyerror(NULL, "invalid hex character sequence"); } {unicode}+\\ { /* throw back the \\, and treat as unicode */ @@ -152,11 +152,11 @@ hex_fail \\x{hex_dig}{0,1} parseUnicode(yytext, yyleng); } -\\. { yyerror(NULL, "Escape sequence is invalid"); } +\\. { yyerror(NULL, "escape sequence is invalid"); } -\\ { yyerror(NULL, "Unexpected end after backslash"); } +\\ { yyerror(NULL, "unexpected end after backslash"); } -<> { yyerror(NULL, "Unexpected end of quoted string"); } +<> { yyerror(NULL, "unexpected end of quoted string"); } \" { yylval->str = scanstring; @@ -186,7 +186,7 @@ hex_fail \\x{hex_dig}{0,1} \* { } -<> { yyerror(NULL, "Unexpected end of comment"); } +<> { yyerror(NULL, "unexpected end of comment"); } \&\& { return AND_P; } @@ -261,7 +261,7 @@ hex_fail \\x{hex_dig}{0,1} return INT_P; } -({realfail1}|{realfail2}) { yyerror(NULL, "Floating point number is invalid"); } +({realfail1}|{realfail2}) { yyerror(NULL, "invalid floating point number"); } {any}+ { addstring(true, yytext, yyleng); @@ -295,17 +295,16 @@ jsonpath_yyerror(JsonPathParseResult **result, const char *message) { ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("bad jsonpath representation"), /* translator: %s is typically "syntax error" */ - errdetail("%s at end of input", message))); + errmsg("%s at end of jsonpath input", _(message)))); } else { ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("bad jsonpath representation"), /* translator: first %s is typically "syntax error" */ - errdetail("%s at or near \"%s\"", message, yytext))); + errmsg("%s at or near \"%s\" of jsonpath input", + _(message), yytext))); } } @@ -495,7 +494,7 @@ hexval(char c) return c - 'a' + 0xA; if (c >= 'A' && c <= 'F') return c - 'A' + 0xA; - elog(ERROR, "invalid hexadecimal digit"); + jsonpath_yyerror(NULL, "invalid hexadecimal digit"); return 0; /* not reached */ } diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out index 49a857bca6..2b63da3f24 100644 --- a/src/test/regress/expected/jsonb_jsonpath.out +++ b/src/test/regress/expected/jsonb_jsonpath.out @@ -119,8 +119,7 @@ select jsonb '[1]' @? 'strict $[1]'; (1 row) select jsonb_path_query('[1]', 'strict $[1]'); -ERROR: invalid SQL/JSON subscript -DETAIL: jsonpath array subscript is out of bounds +ERROR: jsonpath array subscript is out of bounds select jsonb_path_query('[1]', 'strict $[1]', silent => true); jsonb_path_query ------------------ @@ -139,11 +138,9 @@ select jsonb '[1]' @? 'strict $[10000000000000000]'; (1 row) select jsonb_path_query('[1]', 'lax $[10000000000000000]'); -ERROR: invalid SQL/JSON subscript -DETAIL: jsonpath array subscript is out of integer range +ERROR: jsonpath array subscript is out of integer range select jsonb_path_query('[1]', 'strict $[10000000000000000]'); -ERROR: invalid SQL/JSON subscript -DETAIL: jsonpath array subscript is out of integer range +ERROR: jsonpath array subscript is out of integer range select jsonb '[1]' @? '$[0]'; ?column? ---------- @@ -241,8 +238,7 @@ select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => true (1 row) select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => false); -ERROR: SQL/JSON member not found -DETAIL: jsonpath member accessor can only be applied to an object +ERROR: jsonpath member accessor can only be applied to an object select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => true); jsonb_path_exists ------------------- @@ -255,11 +251,9 @@ select jsonb_path_query('1', 'lax $.a'); (0 rows) select jsonb_path_query('1', 'strict $.a'); -ERROR: SQL/JSON member not found -DETAIL: jsonpath member accessor can only be applied to an object +ERROR: jsonpath member accessor can only be applied to an object select jsonb_path_query('1', 'strict $.*'); -ERROR: SQL/JSON object not found -DETAIL: jsonpath wildcard member accessor can only be applied to an object +ERROR: jsonpath wildcard member accessor can only be applied to an object select jsonb_path_query('1', 'strict $.a', silent => true); jsonb_path_query ------------------ @@ -276,8 +270,7 @@ select jsonb_path_query('[]', 'lax $.a'); (0 rows) select jsonb_path_query('[]', 'strict $.a'); -ERROR: SQL/JSON member not found -DETAIL: jsonpath member accessor can only be applied to an object +ERROR: jsonpath member accessor can only be applied to an object select jsonb_path_query('[]', 'strict $.a', silent => true); jsonb_path_query ------------------ @@ -289,25 +282,20 @@ select jsonb_path_query('{}', 'lax $.a'); (0 rows) select jsonb_path_query('{}', 'strict $.a'); -ERROR: SQL/JSON member not found -DETAIL: JSON object does not contain key "a" +ERROR: JSON object does not contain key "a" select jsonb_path_query('{}', 'strict $.a', silent => true); jsonb_path_query ------------------ (0 rows) select jsonb_path_query('1', 'strict $[1]'); -ERROR: SQL/JSON array not found -DETAIL: jsonpath array accessor can only be applied to an array +ERROR: jsonpath array accessor can only be applied to an array select jsonb_path_query('1', 'strict $[*]'); -ERROR: SQL/JSON array not found -DETAIL: jsonpath wildcard array accessor can only be applied to an array +ERROR: jsonpath wildcard array accessor can only be applied to an array select jsonb_path_query('[]', 'strict $[1]'); -ERROR: invalid SQL/JSON subscript -DETAIL: jsonpath array subscript is out of bounds +ERROR: jsonpath array subscript is out of bounds select jsonb_path_query('[]', 'strict $["a"]'); -ERROR: invalid SQL/JSON subscript -DETAIL: jsonpath array subscript is not a singleton numeric value +ERROR: jsonpath array subscript is not a single numeric value select jsonb_path_query('1', 'strict $[1]', silent => true); jsonb_path_query ------------------ @@ -437,8 +425,7 @@ select jsonb_path_query('[1,2,3]', 'lax $[*]'); (3 rows) select jsonb_path_query('[1,2,3]', 'strict $[*].a'); -ERROR: SQL/JSON member not found -DETAIL: jsonpath member accessor can only be applied to an object +ERROR: jsonpath member accessor can only be applied to an object select jsonb_path_query('[1,2,3]', 'strict $[*].a', silent => true); jsonb_path_query ------------------ @@ -455,8 +442,7 @@ select jsonb_path_query('[]', '$[last ? (exists(last))]'); (0 rows) select jsonb_path_query('[]', 'strict $[last]'); -ERROR: invalid SQL/JSON subscript -DETAIL: jsonpath array subscript is out of bounds +ERROR: jsonpath array subscript is out of bounds select jsonb_path_query('[]', 'strict $[last]', silent => true); jsonb_path_query ------------------ @@ -487,8 +473,7 @@ select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "number")]'); (1 row) select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]'); -ERROR: invalid SQL/JSON subscript -DETAIL: jsonpath array subscript is not a singleton numeric value +ERROR: jsonpath array subscript is not a single numeric value select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]', silent => true); jsonb_path_query ------------------ @@ -501,11 +486,13 @@ select * from jsonb_path_query('{"a": 10}', '$'); (1 row) select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)'); -ERROR: cannot find jsonpath variable 'value' +ERROR: cannot find jsonpath variable "value" select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1'); -ERROR: jsonb containing jsonpath variables is not an object +ERROR: "vars" argument is not an object +DETAIL: Jsonpath parameters should be encoded as key-value pairs of "vars" object. select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '[{"value" : 13}]'); -ERROR: jsonb containing jsonpath variables is not an object +ERROR: "vars" argument is not an object +DETAIL: Jsonpath parameters should be encoded as key-value pairs of "vars" object. select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 13}'); jsonb_path_query ------------------ @@ -1067,17 +1054,13 @@ ERROR: division by zero select jsonb_path_query('0', '-(3 + 1 % $)'); ERROR: division by zero select jsonb_path_query('1', '$ + "2"'); -ERROR: singleton SQL/JSON item required -DETAIL: right operand of binary jsonpath operator + is not a singleton numeric value +ERROR: right operand of jsonpath operator + is not a single numeric value select jsonb_path_query('[1, 2]', '3 * $'); -ERROR: singleton SQL/JSON item required -DETAIL: right operand of binary jsonpath operator * is not a singleton numeric value +ERROR: right operand of jsonpath operator * is not a single numeric value select jsonb_path_query('"a"', '-$'); -ERROR: SQL/JSON number not found -DETAIL: operand of unary jsonpath operator - is not a numeric value +ERROR: operand of unary jsonpath operator - is not a numeric value select jsonb_path_query('[1,"2",3]', '+$'); -ERROR: SQL/JSON number not found -DETAIL: operand of unary jsonpath operator + is not a numeric value +ERROR: operand of unary jsonpath operator + is not a numeric value select jsonb_path_query('1', '$ + "2"', silent => true); jsonb_path_query ------------------ @@ -1146,8 +1129,7 @@ select jsonb_path_query('{"a": [2, 3, 4]}', 'lax -$.a'); -- should fail select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3'); -ERROR: singleton SQL/JSON item required -DETAIL: left operand of binary jsonpath operator * is not a singleton numeric value +ERROR: left operand of jsonpath operator * is not a single numeric value select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true); jsonb_path_query ------------------ @@ -1346,8 +1328,7 @@ select jsonb_path_query('[1, 2, 3]', 'strict ($[*].a > 3).type()'); (1 row) select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()'); -ERROR: SQL/JSON array not found -DETAIL: jsonpath item method .size() can only be applied to an array +ERROR: jsonpath item method .size() can only be applied to an array select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()', silent => true); jsonb_path_query ------------------ @@ -1418,8 +1399,7 @@ select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs().type()'); (5 rows) select jsonb_path_query('[{},1]', '$[*].keyvalue()'); -ERROR: SQL/JSON object not found -DETAIL: jsonpath item method .keyvalue() can only be applied to an object +ERROR: jsonpath item method .keyvalue() can only be applied to an object select jsonb_path_query('[{},1]', '$[*].keyvalue()', silent => true); jsonb_path_query ------------------ @@ -1447,8 +1427,7 @@ select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', '$[*].ke (3 rows) select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue()'); -ERROR: SQL/JSON object not found -DETAIL: jsonpath item method .keyvalue() can only be applied to an object +ERROR: jsonpath item method .keyvalue() can only be applied to an object select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'lax $.keyvalue()'); jsonb_path_query ----------------------------------------------- @@ -1458,8 +1437,7 @@ select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'lax $.k (3 rows) select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue().a'); -ERROR: SQL/JSON object not found -DETAIL: jsonpath item method .keyvalue() can only be applied to an object +ERROR: jsonpath item method .keyvalue() can only be applied to an object select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue()'; ?column? ---------- @@ -1473,11 +1451,9 @@ select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue().key'; (1 row) select jsonb_path_query('null', '$.double()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .double() can only be applied to a string or numeric value +ERROR: jsonpath item method .double() can only be applied to a string or numeric value select jsonb_path_query('true', '$.double()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .double() can only be applied to a string or numeric value +ERROR: jsonpath item method .double() can only be applied to a string or numeric value select jsonb_path_query('null', '$.double()', silent => true); jsonb_path_query ------------------ @@ -1494,11 +1470,9 @@ select jsonb_path_query('[]', '$.double()'); (0 rows) select jsonb_path_query('[]', 'strict $.double()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .double() can only be applied to a string or numeric value +ERROR: jsonpath item method .double() can only be applied to a string or numeric value select jsonb_path_query('{}', '$.double()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .double() can only be applied to a string or numeric value +ERROR: jsonpath item method .double() can only be applied to a string or numeric value select jsonb_path_query('[]', 'strict $.double()', silent => true); jsonb_path_query ------------------ @@ -1522,8 +1496,7 @@ select jsonb_path_query('"1.23"', '$.double()'); (1 row) select jsonb_path_query('"1.23aaa"', '$.double()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .double() can only be applied to a numeric value +ERROR: jsonpath item method .double() can only be applied to a numeric value select jsonb_path_query('"nan"', '$.double()'); jsonb_path_query ------------------ @@ -1537,11 +1510,9 @@ select jsonb_path_query('"NaN"', '$.double()'); (1 row) select jsonb_path_query('"inf"', '$.double()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .double() can only be applied to a numeric value +ERROR: jsonpath item method .double() can only be applied to a numeric value select jsonb_path_query('"-inf"', '$.double()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .double() can only be applied to a numeric value +ERROR: jsonpath item method .double() can only be applied to a numeric value select jsonb_path_query('"inf"', '$.double()', silent => true); jsonb_path_query ------------------ @@ -1553,14 +1524,11 @@ select jsonb_path_query('"-inf"', '$.double()', silent => true); (0 rows) select jsonb_path_query('{}', '$.abs()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .abs() can only be applied to a numeric value +ERROR: jsonpath item method .abs() can only be applied to a numeric value select jsonb_path_query('true', '$.floor()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .floor() can only be applied to a numeric value +ERROR: jsonpath item method .floor() can only be applied to a numeric value select jsonb_path_query('"1.2"', '$.ceiling()'); -ERROR: non-numeric SQL/JSON item -DETAIL: jsonpath item method .ceiling() can only be applied to a numeric value +ERROR: jsonpath item method .ceiling() can only be applied to a numeric value select jsonb_path_query('{}', '$.abs()', silent => true); jsonb_path_query ------------------ @@ -1668,8 +1636,7 @@ SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)'); (0 rows) SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); -ERROR: SQL/JSON member not found -DETAIL: JSON object does not contain key "a" +ERROR: JSON object does not contain key "a" SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a'); jsonb_path_query_array ------------------------ @@ -1701,8 +1668,7 @@ SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*]. (1 row) SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); -ERROR: SQL/JSON member not found -DETAIL: JSON object does not contain key "a" +ERROR: JSON object does not contain key "a" SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a', silent => true); jsonb_path_query_first ------------------------ @@ -1794,23 +1760,17 @@ SELECT jsonb_path_match('1', '$', silent => true); (1 row) SELECT jsonb_path_match('1', '$', silent => false); -ERROR: singleton SQL/JSON item required -DETAIL: expression should return a singleton boolean +ERROR: single boolean result is expected SELECT jsonb_path_match('"a"', '$', silent => false); -ERROR: singleton SQL/JSON item required -DETAIL: expression should return a singleton boolean +ERROR: single boolean result is expected SELECT jsonb_path_match('{}', '$', silent => false); -ERROR: singleton SQL/JSON item required -DETAIL: expression should return a singleton boolean +ERROR: single boolean result is expected SELECT jsonb_path_match('[true]', '$', silent => false); -ERROR: singleton SQL/JSON item required -DETAIL: expression should return a singleton boolean +ERROR: single boolean result is expected SELECT jsonb_path_match('{}', 'lax $.a', silent => false); -ERROR: singleton SQL/JSON item required -DETAIL: expression should return a singleton boolean +ERROR: single boolean result is expected SELECT jsonb_path_match('{}', 'strict $.a', silent => false); -ERROR: SQL/JSON member not found -DETAIL: JSON object does not contain key "a" +ERROR: JSON object does not contain key "a" SELECT jsonb_path_match('{}', 'strict $.a', silent => true); jsonb_path_match ------------------ @@ -1818,8 +1778,7 @@ SELECT jsonb_path_match('{}', 'strict $.a', silent => true); (1 row) SELECT jsonb_path_match('[true, true]', '$[*]', silent => false); -ERROR: singleton SQL/JSON item required -DETAIL: expression should return a singleton boolean +ERROR: single boolean result is expected SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1'; ?column? ---------- diff --git a/src/test/regress/expected/jsonpath.out b/src/test/regress/expected/jsonpath.out index a99643f902..c7bd26887c 100644 --- a/src/test/regress/expected/jsonpath.out +++ b/src/test/regress/expected/jsonpath.out @@ -454,10 +454,10 @@ select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath; (1 row) select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; -ERROR: bad jsonpath representation +ERROR: invalid input syntax for type jsonpath LINE 1: select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; ^ -DETAIL: unrecognized flag of LIKE_REGEX predicate at or near """ +DETAIL: unrecognized flag character "a" in LIKE_REGEX predicate select '$ < 1'::jsonpath; jsonpath ---------- @@ -547,20 +547,17 @@ select '$ ? (@.a < +1)'::jsonpath; (1 row) select '$ ? (@.a < .1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < .1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < -.1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < +.1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1)'::jsonpath; jsonpath ----------------- @@ -616,20 +613,17 @@ select '$ ? (@.a < +1e1)'::jsonpath; (1 row) select '$ ? (@.a < .1e1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < .1e1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1e1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < -.1e1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1e1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < +.1e1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1e1)'::jsonpath; jsonpath --------------- @@ -685,20 +679,17 @@ select '$ ? (@.a < +1e-1)'::jsonpath; (1 row) select '$ ? (@.a < .1e-1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < .1e-1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1e-1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < -.1e-1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1e-1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < +.1e-1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1e-1)'::jsonpath; jsonpath ------------------ @@ -754,20 +745,17 @@ select '$ ? (@.a < +1e+1)'::jsonpath; (1 row) select '$ ? (@.a < .1e+1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < .1e+1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1e+1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < -.1e+1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1e+1)'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '$ ? (@.a < +.1e+1)'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1e+1)'::jsonpath; jsonpath --------------- @@ -811,10 +799,9 @@ select '0'::jsonpath; (1 row) select '00'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected IDENT_P at end of jsonpath input LINE 1: select '00'::jsonpath; ^ -DETAIL: syntax error, unexpected IDENT_P at end of input select '0.0'::jsonpath; jsonpath ---------- @@ -870,10 +857,9 @@ select '0.0010e+2'::jsonpath; (1 row) select '1e'::jsonpath; -ERROR: bad jsonpath representation +ERROR: invalid floating point number at or near "1e" of jsonpath input LINE 1: select '1e'::jsonpath; ^ -DETAIL: Floating point number is invalid at or near "1e" select '1.e'::jsonpath; jsonpath ---------- @@ -881,10 +867,9 @@ select '1.e'::jsonpath; (1 row) select '1.2e'::jsonpath; -ERROR: bad jsonpath representation +ERROR: invalid floating point number at or near "1.2e" of jsonpath input LINE 1: select '1.2e'::jsonpath; ^ -DETAIL: Floating point number is invalid at or near "1.2e" select '1.2.e'::jsonpath; jsonpath ---------- @@ -940,22 +925,18 @@ select '(1.2).e3'::jsonpath; (1 row) select '1..e'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '1..e'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '1..e3'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input LINE 1: select '1..e3'::jsonpath; ^ -DETAIL: syntax error, unexpected '.' at or near "." select '(1.).e'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected ')' at or near ")" of jsonpath input LINE 1: select '(1.).e'::jsonpath; ^ -DETAIL: syntax error, unexpected ')' at or near ")" select '(1.).e3'::jsonpath; -ERROR: bad jsonpath representation +ERROR: syntax error, unexpected ')' at or near ")" of jsonpath input LINE 1: select '(1.).e3'::jsonpath; ^ -DETAIL: syntax error, unexpected ')' at or near ")" diff --git a/src/test/regress/expected/jsonpath_encoding.out b/src/test/regress/expected/jsonpath_encoding.out index 6d828d1724..8db6e47dbb 100644 --- a/src/test/regress/expected/jsonpath_encoding.out +++ b/src/test/regress/expected/jsonpath_encoding.out @@ -2,20 +2,17 @@ -- checks for double-quoted values -- basic unicode input SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid unicode sequence at or near "\u" of jsonpath input LINE 1: SELECT '"\u"'::jsonpath; ^ -DETAIL: Unicode sequence is invalid at or near "\u" SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid unicode sequence at or near "\u00" of jsonpath input LINE 1: SELECT '"\u00"'::jsonpath; ^ -DETAIL: Unicode sequence is invalid at or near "\u00" SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit -ERROR: bad jsonpath representation +ERROR: invalid unicode sequence at or near "\u000" of jsonpath input LINE 1: SELECT '"\u000g"'::jsonpath; ^ -DETAIL: Unicode sequence is invalid at or near "\u000" SELECT '"\u0000"'::jsonpath; -- OK, legal escape ERROR: unsupported Unicode escape sequence LINE 1: SELECT '"\u0000"'::jsonpath; @@ -165,20 +162,17 @@ DETAIL: \u0000 cannot be converted to text. -- checks for quoted key names -- basic unicode input SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid unicode sequence at or near "\u" of jsonpath input LINE 1: SELECT '$."\u"'::jsonpath; ^ -DETAIL: Unicode sequence is invalid at or near "\u" SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid unicode sequence at or near "\u00" of jsonpath input LINE 1: SELECT '$."\u00"'::jsonpath; ^ -DETAIL: Unicode sequence is invalid at or near "\u00" SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit -ERROR: bad jsonpath representation +ERROR: invalid unicode sequence at or near "\u000" of jsonpath input LINE 1: SELECT '$."\u000g"'::jsonpath; ^ -DETAIL: Unicode sequence is invalid at or near "\u000" SELECT '$."\u0000"'::jsonpath; -- OK, legal escape ERROR: unsupported Unicode escape sequence LINE 1: SELECT '$."\u0000"'::jsonpath; diff --git a/src/test/regress/expected/jsonpath_encoding_1.out b/src/test/regress/expected/jsonpath_encoding_1.out index 04179a8df7..a3a44e182a 100644 --- a/src/test/regress/expected/jsonpath_encoding_1.out +++ b/src/test/regress/expected/jsonpath_encoding_1.out @@ -2,17 +2,17 @@ -- checks for double-quoted values -- basic unicode input SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid input syntax for type jsonpath LINE 1: SELECT '"\u"'::jsonpath; ^ DETAIL: Unicode sequence is invalid at or near "\u" SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid input syntax for type jsonpath LINE 1: SELECT '"\u00"'::jsonpath; ^ DETAIL: Unicode sequence is invalid at or near "\u00" SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit -ERROR: bad jsonpath representation +ERROR: invalid input syntax for type jsonpath LINE 1: SELECT '"\u000g"'::jsonpath; ^ DETAIL: Unicode sequence is invalid at or near "\u000" @@ -156,17 +156,17 @@ DETAIL: \u0000 cannot be converted to text. -- checks for quoted key names -- basic unicode input SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid input syntax for type jsonpath LINE 1: SELECT '$."\u"'::jsonpath; ^ DETAIL: Unicode sequence is invalid at or near "\u" SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape -ERROR: bad jsonpath representation +ERROR: invalid input syntax for type jsonpath LINE 1: SELECT '$."\u00"'::jsonpath; ^ DETAIL: Unicode sequence is invalid at or near "\u00" SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit -ERROR: bad jsonpath representation +ERROR: invalid input syntax for type jsonpath LINE 1: SELECT '$."\u000g"'::jsonpath; ^ DETAIL: Unicode sequence is invalid at or near "\u000" -- 2.39.5