Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit475aedd

Browse files
committed
Improve error messages for malformed array input strings.
Make the error messages issued by array_in() uniformly follow the styleERROR: malformed array literal: "actual input string"DETAIL: specific complaint hereand rewrite many of the specific complaints to be clearer.The immediate motivation for doing this is a complaint from Josh Berkusthat json_to_record() produced an unintelligible error message whendealing with an array item, because it tries to feed the JSON-formatarray value to array_in(). Really it ought to be smart enough toperform JSON-to-Postgres array conversion, but that's a future featurenot a bug fix. In the meantime, this change is something we agreedwe could back-patch into 9.4, and it should help de-confuse things a bit.
1 parent0fd38e1 commit475aedd

File tree

3 files changed

+60
-25
lines changed

3 files changed

+60
-25
lines changed

‎src/backend/utils/adt/arrayfuncs.c

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -247,23 +247,27 @@ array_in(PG_FUNCTION_ARGS)
247247
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
248248
ndim+1,MAXDIM)));
249249

250-
for (q=p;isdigit((unsignedchar)*q)|| (*q=='-')|| (*q=='+');q++);
250+
for (q=p;isdigit((unsignedchar)*q)|| (*q=='-')|| (*q=='+');q++)
251+
/* skip */ ;
251252
if (q==p)/* no digits? */
252253
ereport(ERROR,
253254
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
254-
errmsg("missing dimension value")));
255+
errmsg("malformed array literal: \"%s\"",string),
256+
errdetail("\"[\" must introduce explicitly-specified array dimensions.")));
255257

256258
if (*q==':')
257259
{
258260
/* [m:n] format */
259261
*q='\0';
260262
lBound[ndim]=atoi(p);
261263
p=q+1;
262-
for (q=p;isdigit((unsignedchar)*q)|| (*q=='-')|| (*q=='+');q++);
264+
for (q=p;isdigit((unsignedchar)*q)|| (*q=='-')|| (*q=='+');q++)
265+
/* skip */ ;
263266
if (q==p)/* no digits? */
264267
ereport(ERROR,
265268
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
266-
errmsg("missing dimension value")));
269+
errmsg("malformed array literal: \"%s\"",string),
270+
errdetail("Missing array dimension value.")));
267271
}
268272
else
269273
{
@@ -273,7 +277,9 @@ array_in(PG_FUNCTION_ARGS)
273277
if (*q!=']')
274278
ereport(ERROR,
275279
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
276-
errmsg("missing \"]\" in array dimensions")));
280+
errmsg("malformed array literal: \"%s\"",string),
281+
errdetail("Missing \"%s\" after array dimensions.",
282+
"]")));
277283

278284
*q='\0';
279285
ub=atoi(p);
@@ -293,7 +299,8 @@ array_in(PG_FUNCTION_ARGS)
293299
if (*p!='{')
294300
ereport(ERROR,
295301
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
296-
errmsg("array value must start with \"{\" or dimension information")));
302+
errmsg("malformed array literal: \"%s\"",string),
303+
errdetail("Array value must start with \"{\" or dimension information.")));
297304
ndim=ArrayCount(p,dim,typdelim);
298305
for (i=0;i<ndim;i++)
299306
lBound[i]=1;
@@ -307,7 +314,9 @@ array_in(PG_FUNCTION_ARGS)
307314
if (strncmp(p,ASSGN,strlen(ASSGN))!=0)
308315
ereport(ERROR,
309316
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
310-
errmsg("missing assignment operator")));
317+
errmsg("malformed array literal: \"%s\"",string),
318+
errdetail("Missing \"%s\" after array dimensions.",
319+
ASSGN)));
311320
p+=strlen(ASSGN);
312321
while (array_isspace(*p))
313322
p++;
@@ -319,18 +328,21 @@ array_in(PG_FUNCTION_ARGS)
319328
if (*p!='{')
320329
ereport(ERROR,
321330
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
322-
errmsg("array value must start with \"{\" or dimension information")));
331+
errmsg("malformed array literal: \"%s\"",string),
332+
errdetail("Array contents must start with \"{\".")));
323333
ndim_braces=ArrayCount(p,dim_braces,typdelim);
324334
if (ndim_braces!=ndim)
325335
ereport(ERROR,
326336
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
327-
errmsg("array dimensions incompatible with array literal")));
337+
errmsg("malformed array literal: \"%s\"",string),
338+
errdetail("Specified array dimensions do not match array contents.")));
328339
for (i=0;i<ndim;++i)
329340
{
330341
if (dim[i]!=dim_braces[i])
331342
ereport(ERROR,
332343
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
333-
errmsg("array dimensions incompatible with array literal")));
344+
errmsg("malformed array literal: \"%s\"",string),
345+
errdetail("Specified array dimensions do not match array contents.")));
334346
}
335347
}
336348

@@ -460,7 +472,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
460472
/* Signal a premature end of the string */
461473
ereport(ERROR,
462474
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
463-
errmsg("malformed array literal: \"%s\"",str)));
475+
errmsg("malformed array literal: \"%s\"",str),
476+
errdetail("Unexpected end of input.")));
464477
break;
465478
case'\\':
466479

@@ -475,7 +488,9 @@ ArrayCount(const char *str, int *dim, char typdelim)
475488
parse_state!=ARRAY_ELEM_DELIMITED)
476489
ereport(ERROR,
477490
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
478-
errmsg("malformed array literal: \"%s\"",str)));
491+
errmsg("malformed array literal: \"%s\"",str),
492+
errdetail("Unexpected \"%c\" character.",
493+
'\\')));
479494
if (parse_state!=ARRAY_QUOTED_ELEM_STARTED)
480495
parse_state=ARRAY_ELEM_STARTED;
481496
/* skip the escaped character */
@@ -484,7 +499,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
484499
else
485500
ereport(ERROR,
486501
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
487-
errmsg("malformed array literal: \"%s\"",str)));
502+
errmsg("malformed array literal: \"%s\"",str),
503+
errdetail("Unexpected end of input.")));
488504
break;
489505
case'\"':
490506

@@ -498,7 +514,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
498514
parse_state!=ARRAY_ELEM_DELIMITED)
499515
ereport(ERROR,
500516
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
501-
errmsg("malformed array literal: \"%s\"",str)));
517+
errmsg("malformed array literal: \"%s\"",str),
518+
errdetail("Unexpected array element.")));
502519
in_quotes= !in_quotes;
503520
if (in_quotes)
504521
parse_state=ARRAY_QUOTED_ELEM_STARTED;
@@ -518,7 +535,9 @@ ArrayCount(const char *str, int *dim, char typdelim)
518535
parse_state!=ARRAY_LEVEL_DELIMITED)
519536
ereport(ERROR,
520537
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
521-
errmsg("malformed array literal: \"%s\"",str)));
538+
errmsg("malformed array literal: \"%s\"",str),
539+
errdetail("Unexpected \"%c\" character.",
540+
'{')));
522541
parse_state=ARRAY_LEVEL_STARTED;
523542
if (nest_level >=MAXDIM)
524543
ereport(ERROR,
@@ -546,21 +565,25 @@ ArrayCount(const char *str, int *dim, char typdelim)
546565
!(nest_level==1&&parse_state==ARRAY_LEVEL_STARTED))
547566
ereport(ERROR,
548567
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
549-
errmsg("malformed array literal: \"%s\"",str)));
568+
errmsg("malformed array literal: \"%s\"",str),
569+
errdetail("Unexpected \"%c\" character.",
570+
'}')));
550571
parse_state=ARRAY_LEVEL_COMPLETED;
551572
if (nest_level==0)
552573
ereport(ERROR,
553574
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
554-
errmsg("malformed array literal: \"%s\"",str)));
575+
errmsg("malformed array literal: \"%s\"",str),
576+
errdetail("Unmatched \"%c\" character.",'}')));
555577
nest_level--;
556578

557579
if (nelems_last[nest_level]!=0&&
558580
nelems[nest_level]!=nelems_last[nest_level])
559581
ereport(ERROR,
560582
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
561-
errmsg("multidimensional arrays must have "
562-
"array expressions with matching "
563-
"dimensions")));
583+
errmsg("malformed array literal: \"%s\"",str),
584+
errdetail("Multidimensional arrays must have "
585+
"sub-arrays with matching "
586+
"dimensions.")));
564587
nelems_last[nest_level]=nelems[nest_level];
565588
nelems[nest_level]=1;
566589
if (nest_level==0)
@@ -591,7 +614,9 @@ ArrayCount(const char *str, int *dim, char typdelim)
591614
parse_state!=ARRAY_LEVEL_COMPLETED)
592615
ereport(ERROR,
593616
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
594-
errmsg("malformed array literal: \"%s\"",str)));
617+
errmsg("malformed array literal: \"%s\"",str),
618+
errdetail("Unexpected \"%c\" character.",
619+
typdelim)));
595620
if (parse_state==ARRAY_LEVEL_COMPLETED)
596621
parse_state=ARRAY_LEVEL_DELIMITED;
597622
else
@@ -612,7 +637,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
612637
parse_state!=ARRAY_ELEM_DELIMITED)
613638
ereport(ERROR,
614639
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
615-
errmsg("malformed array literal: \"%s\"",str)));
640+
errmsg("malformed array literal: \"%s\"",str),
641+
errdetail("Unexpected array element.")));
616642
parse_state=ARRAY_ELEM_STARTED;
617643
}
618644
}
@@ -631,7 +657,8 @@ ArrayCount(const char *str, int *dim, char typdelim)
631657
if (!array_isspace(*ptr++))
632658
ereport(ERROR,
633659
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
634-
errmsg("malformed array literal: \"%s\"",str)));
660+
errmsg("malformed array literal: \"%s\"",str),
661+
errdetail("Junk after closing right brace.")));
635662
}
636663

637664
/* special case for an empty array */
@@ -718,7 +745,8 @@ ReadArrayStr(char *arrayStr,
718745
* character.
719746
*
720747
* The error checking in this routine is mostly pro-forma, since we expect
721-
* that ArrayCount() already validated the string.
748+
* that ArrayCount() already validated the string. So we don't bother
749+
* with errdetail messages.
722750
*/
723751
srcptr=arrayStr;
724752
while (!eoArray)

‎src/pl/plperl/expected/plperl_array.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ ERROR: number of array dimensions (7) exceeds the maximum allowed (6)
6565
LINE 1: select plperl_sum_array('{{{{{{{1,2},{3,4}},{{5,6},{7,8}}},{...
6666
^
6767
select plperl_sum_array('{{{1,2,3}, {4,5,6,7}}, {{7,8,9}, {10, 11, 12}}}');
68-
ERROR:multidimensional arrays must have array expressions with matching dimensions
68+
ERROR:malformed array literal: "{{{1,2,3}, {4,5,6,7}}, {{7,8,9}, {10, 11, 12}}}"
6969
LINE 1: select plperl_sum_array('{{{1,2,3}, {4,5,6,7}}, {{7,8,9}, {1...
7070
^
71+
DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions.
7172
CREATE OR REPLACE FUNCTION plperl_concat(TEXT[]) RETURNS TEXT AS $$
7273
my $array_arg = shift;
7374
my $result = "";

‎src/test/regress/expected/arrays.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,26 +1065,32 @@ select '{{1,{2}},{2,3}}'::text[];
10651065
ERROR: malformed array literal: "{{1,{2}},{2,3}}"
10661066
LINE 1: select '{{1,{2}},{2,3}}'::text[];
10671067
^
1068+
DETAIL: Unexpected "{" character.
10681069
select '{{},{}}'::text[];
10691070
ERROR: malformed array literal: "{{},{}}"
10701071
LINE 1: select '{{},{}}'::text[];
10711072
^
1073+
DETAIL: Unexpected "}" character.
10721074
select E'{{1,2},\\{2,3}}'::text[];
10731075
ERROR: malformed array literal: "{{1,2},\{2,3}}"
10741076
LINE 1: select E'{{1,2},\\{2,3}}'::text[];
10751077
^
1078+
DETAIL: Unexpected "\" character.
10761079
select '{{"1 2" x},{3}}'::text[];
10771080
ERROR: malformed array literal: "{{"1 2" x},{3}}"
10781081
LINE 1: select '{{"1 2" x},{3}}'::text[];
10791082
^
1083+
DETAIL: Unexpected array element.
10801084
select '{}}'::text[];
10811085
ERROR: malformed array literal: "{}}"
10821086
LINE 1: select '{}}'::text[];
10831087
^
1088+
DETAIL: Junk after closing right brace.
10841089
select '{ }}'::text[];
10851090
ERROR: malformed array literal: "{ }}"
10861091
LINE 1: select '{ }}'::text[];
10871092
^
1093+
DETAIL: Junk after closing right brace.
10881094
select array[];
10891095
ERROR: cannot determine type of empty array
10901096
LINE 1: select array[];

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp