aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-12-02 18:23:16 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-12-02 18:23:27 -0500
commit475aedd1ef0c0f9fc9d675dd2286380d14804975 (patch)
treeb237c4f2504714f8dc8ee3fca32754ef0a106abc /src/backend/utils/adt/arrayfuncs.c
parent0fd38e13706e6bd4b2a4ce4e0570d0aa4ad65345 (diff)
downloadpostgresql-475aedd1ef0c0f9fc9d675dd2286380d14804975.tar.gz
postgresql-475aedd1ef0c0f9fc9d675dd2286380d14804975.zip
Improve error messages for malformed array input strings.
Make the error messages issued by array_in() uniformly follow the style ERROR: malformed array literal: "actual input string" DETAIL: specific complaint here and rewrite many of the specific complaints to be clearer. The immediate motivation for doing this is a complaint from Josh Berkus that json_to_record() produced an unintelligible error message when dealing with an array item, because it tries to feed the JSON-format array value to array_in(). Really it ought to be smart enough to perform JSON-to-Postgres array conversion, but that's a future feature not a bug fix. In the meantime, this change is something we agreed we could back-patch into 9.4, and it should help de-confuse things a bit.
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c76
1 files changed, 52 insertions, 24 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 743351b95e0..933c6b035c6 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -247,11 +247,13 @@ array_in(PG_FUNCTION_ARGS)
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
ndim + 1, MAXDIM)));
- for (q = p; isdigit((unsigned char) *q) || (*q == '-') || (*q == '+'); q++);
+ for (q = p; isdigit((unsigned char) *q) || (*q == '-') || (*q == '+'); q++)
+ /* skip */ ;
if (q == p) /* no digits? */
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("missing dimension value")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("\"[\" must introduce explicitly-specified array dimensions.")));
if (*q == ':')
{
@@ -259,11 +261,13 @@ array_in(PG_FUNCTION_ARGS)
*q = '\0';
lBound[ndim] = atoi(p);
p = q + 1;
- for (q = p; isdigit((unsigned char) *q) || (*q == '-') || (*q == '+'); q++);
+ for (q = p; isdigit((unsigned char) *q) || (*q == '-') || (*q == '+'); q++)
+ /* skip */ ;
if (q == p) /* no digits? */
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("missing dimension value")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("Missing array dimension value.")));
}
else
{
@@ -273,7 +277,9 @@ array_in(PG_FUNCTION_ARGS)
if (*q != ']')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("missing \"]\" in array dimensions")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("Missing \"%s\" after array dimensions.",
+ "]")));
*q = '\0';
ub = atoi(p);
@@ -293,7 +299,8 @@ array_in(PG_FUNCTION_ARGS)
if (*p != '{')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("array value must start with \"{\" or dimension information")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("Array value must start with \"{\" or dimension information.")));
ndim = ArrayCount(p, dim, typdelim);
for (i = 0; i < ndim; i++)
lBound[i] = 1;
@@ -307,7 +314,9 @@ array_in(PG_FUNCTION_ARGS)
if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("missing assignment operator")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("Missing \"%s\" after array dimensions.",
+ ASSGN)));
p += strlen(ASSGN);
while (array_isspace(*p))
p++;
@@ -319,18 +328,21 @@ array_in(PG_FUNCTION_ARGS)
if (*p != '{')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("array value must start with \"{\" or dimension information")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("Array contents must start with \"{\".")));
ndim_braces = ArrayCount(p, dim_braces, typdelim);
if (ndim_braces != ndim)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("array dimensions incompatible with array literal")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("Specified array dimensions do not match array contents.")));
for (i = 0; i < ndim; ++i)
{
if (dim[i] != dim_braces[i])
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("array dimensions incompatible with array literal")));
+ errmsg("malformed array literal: \"%s\"", string),
+ errdetail("Specified array dimensions do not match array contents.")));
}
}
@@ -460,7 +472,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
/* Signal a premature end of the string */
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected end of input.")));
break;
case '\\':
@@ -475,7 +488,9 @@ ArrayCount(const char *str, int *dim, char typdelim)
parse_state != ARRAY_ELEM_DELIMITED)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected \"%c\" character.",
+ '\\')));
if (parse_state != ARRAY_QUOTED_ELEM_STARTED)
parse_state = ARRAY_ELEM_STARTED;
/* skip the escaped character */
@@ -484,7 +499,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected end of input.")));
break;
case '\"':
@@ -498,7 +514,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
parse_state != ARRAY_ELEM_DELIMITED)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected array element.")));
in_quotes = !in_quotes;
if (in_quotes)
parse_state = ARRAY_QUOTED_ELEM_STARTED;
@@ -518,7 +535,9 @@ ArrayCount(const char *str, int *dim, char typdelim)
parse_state != ARRAY_LEVEL_DELIMITED)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected \"%c\" character.",
+ '{')));
parse_state = ARRAY_LEVEL_STARTED;
if (nest_level >= MAXDIM)
ereport(ERROR,
@@ -546,21 +565,25 @@ ArrayCount(const char *str, int *dim, char typdelim)
!(nest_level == 1 && parse_state == ARRAY_LEVEL_STARTED))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected \"%c\" character.",
+ '}')));
parse_state = ARRAY_LEVEL_COMPLETED;
if (nest_level == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unmatched \"%c\" character.", '}')));
nest_level--;
if (nelems_last[nest_level] != 0 &&
nelems[nest_level] != nelems_last[nest_level])
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("multidimensional arrays must have "
- "array expressions with matching "
- "dimensions")));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Multidimensional arrays must have "
+ "sub-arrays with matching "
+ "dimensions.")));
nelems_last[nest_level] = nelems[nest_level];
nelems[nest_level] = 1;
if (nest_level == 0)
@@ -591,7 +614,9 @@ ArrayCount(const char *str, int *dim, char typdelim)
parse_state != ARRAY_LEVEL_COMPLETED)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected \"%c\" character.",
+ typdelim)));
if (parse_state == ARRAY_LEVEL_COMPLETED)
parse_state = ARRAY_LEVEL_DELIMITED;
else
@@ -612,7 +637,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
parse_state != ARRAY_ELEM_DELIMITED)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Unexpected array element.")));
parse_state = ARRAY_ELEM_STARTED;
}
}
@@ -631,7 +657,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
if (!array_isspace(*ptr++))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("malformed array literal: \"%s\"", str)));
+ errmsg("malformed array literal: \"%s\"", str),
+ errdetail("Junk after closing right brace.")));
}
/* special case for an empty array */
@@ -718,7 +745,8 @@ ReadArrayStr(char *arrayStr,
* character.
*
* The error checking in this routine is mostly pro-forma, since we expect
- * that ArrayCount() already validated the string.
+ * that ArrayCount() already validated the string. So we don't bother
+ * with errdetail messages.
*/
srcptr = arrayStr;
while (!eoArray)