Skip to content

Commit e07e2a4

Browse files
committed
Improve error messages in ltree_in and lquery_in.
Ensure that the type name is mentioned in all cases (bare "syntax error" isn't that helpful). Avoid using the term "level", since that's not used in the documentation. Phrase error position reports as "at character N" not "in position N"; the latter seems ambiguous, and it's certainly not how we say it elsewhere. For the same reason, make the character position values be 1-based not 0-based. Provide a position in more cases. (I continued to leave that out of messages complaining about end-of-input, where it seemed pointless, as well as messages complaining about overall input complexity, where fingering any one part of the input would be arbitrary.) Discussion: https://postgr.es/m/[email protected]
1 parent 02a5786 commit e07e2a4

File tree

4 files changed

+63
-52
lines changed

4 files changed

+63
-52
lines changed

contrib/ltree/expected/ltree.out

+9-4
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ SELECT nlevel(('1' || repeat('.1', 65534))::ltree);
464464
(1 row)
465465

466466
SELECT nlevel(('1' || repeat('.1', 65535))::ltree);
467-
ERROR: number of ltree levels (65536) exceeds the maximum allowed (65535)
467+
ERROR: number of ltree labels (65536) exceeds the maximum allowed (65535)
468468
SELECT nlevel(('1' || repeat('.1', 65534))::ltree || '1');
469469
ERROR: number of ltree levels (65536) exceeds the maximum allowed (65535)
470470
SELECT ('1' || repeat('.1', 65534))::lquery IS NULL;
@@ -474,7 +474,7 @@ SELECT ('1' || repeat('.1', 65534))::lquery IS NULL;
474474
(1 row)
475475

476476
SELECT ('1' || repeat('.1', 65535))::lquery IS NULL;
477-
ERROR: number of lquery levels (65536) exceeds the maximum allowed (65535)
477+
ERROR: number of lquery items (65536) exceeds the maximum allowed (65535)
478478
SELECT '*{65535}'::lquery;
479479
lquery
480480
----------
@@ -485,7 +485,7 @@ SELECT '*{65536}'::lquery;
485485
ERROR: lquery syntax error
486486
LINE 1: SELECT '*{65536}'::lquery;
487487
^
488-
DETAIL: Low limit (65536) exceeds the maximum allowed (65535).
488+
DETAIL: Low limit (65536) exceeds the maximum allowed (65535), at character 3.
489489
SELECT '*{,65534}'::lquery;
490490
lquery
491491
-----------
@@ -502,7 +502,12 @@ SELECT '*{,65536}'::lquery;
502502
ERROR: lquery syntax error
503503
LINE 1: SELECT '*{,65536}'::lquery;
504504
^
505-
DETAIL: High limit (65536) exceeds the maximum allowed (65535).
505+
DETAIL: High limit (65536) exceeds the maximum allowed (65535), at character 4.
506+
SELECT '*{4,3}'::lquery;
507+
ERROR: lquery syntax error
508+
LINE 1: SELECT '*{4,3}'::lquery;
509+
^
510+
DETAIL: Low limit (4) is greater than high limit (3), at character 5.
506511
SELECT '1.2'::ltree < '2.2'::ltree;
507512
?column?
508513
----------

contrib/ltree/ltree_io.c

+52-47
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ PG_FUNCTION_INFO_V1(lquery_in);
1717
PG_FUNCTION_INFO_V1(lquery_out);
1818

1919

20-
#define UNCHAR ereport(ERROR, \
21-
(errcode(ERRCODE_SYNTAX_ERROR), \
22-
errmsg("syntax error at position %d", \
23-
pos)));
24-
25-
2620
typedef struct
2721
{
2822
char *start;
@@ -47,7 +41,12 @@ ltree_in(PG_FUNCTION_ARGS)
4741
ltree *result;
4842
ltree_level *curlevel;
4943
int charlen;
50-
int pos = 0;
44+
int pos = 1; /* character position for error messages */
45+
46+
#define UNCHAR ereport(ERROR, \
47+
errcode(ERRCODE_SYNTAX_ERROR), \
48+
errmsg("ltree syntax error at character %d", \
49+
pos))
5150

5251
ptr = buf;
5352
while (*ptr)
@@ -61,7 +60,7 @@ ltree_in(PG_FUNCTION_ARGS)
6160
if (num + 1 > LTREE_MAX_LEVELS)
6261
ereport(ERROR,
6362
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
64-
errmsg("number of ltree levels (%d) exceeds the maximum allowed (%d)",
63+
errmsg("number of ltree labels (%d) exceeds the maximum allowed (%d)",
6564
num + 1, LTREE_MAX_LEVELS)));
6665
list = lptr = (nodeitem *) palloc(sizeof(nodeitem) * (num + 1));
6766
ptr = buf;
@@ -88,10 +87,10 @@ ltree_in(PG_FUNCTION_ARGS)
8887
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
8988
ereport(ERROR,
9089
(errcode(ERRCODE_NAME_TOO_LONG),
91-
errmsg("name of level is too long"),
92-
errdetail("Name length is %d, must "
93-
"be < 256, in position %d.",
94-
lptr->wlen, pos)));
90+
errmsg("label string is too long"),
91+
errdetail("Label length is %d, must be at most %d, at character %d.",
92+
lptr->wlen, LTREE_LABEL_MAX_CHARS,
93+
pos)));
9594

9695
totallen += MAXALIGN(lptr->len + LEVEL_HDRSIZE);
9796
lptr++;
@@ -115,19 +114,18 @@ ltree_in(PG_FUNCTION_ARGS)
115114
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
116115
ereport(ERROR,
117116
(errcode(ERRCODE_NAME_TOO_LONG),
118-
errmsg("name of level is too long"),
119-
errdetail("Name length is %d, must "
120-
"be < 256, in position %d.",
121-
lptr->wlen, pos)));
117+
errmsg("label string is too long"),
118+
errdetail("Label length is %d, must be at most %d, at character %d.",
119+
lptr->wlen, LTREE_LABEL_MAX_CHARS, pos)));
122120

123121
totallen += MAXALIGN(lptr->len + LEVEL_HDRSIZE);
124122
lptr++;
125123
}
126124
else if (!(state == LTPRS_WAITNAME && lptr == list))
127125
ereport(ERROR,
128126
(errcode(ERRCODE_SYNTAX_ERROR),
129-
errmsg("syntax error"),
130-
errdetail("Unexpected end of line.")));
127+
errmsg("ltree syntax error"),
128+
errdetail("Unexpected end of input.")));
131129

132130
result = (ltree *) palloc0(LTREE_HDRSIZE + totallen);
133131
SET_VARSIZE(result, LTREE_HDRSIZE + totallen);
@@ -144,6 +142,8 @@ ltree_in(PG_FUNCTION_ARGS)
144142

145143
pfree(list);
146144
PG_RETURN_POINTER(result);
145+
146+
#undef UNCHAR
147147
}
148148

149149
Datum
@@ -208,7 +208,12 @@ lquery_in(PG_FUNCTION_ARGS)
208208
bool hasnot = false;
209209
bool wasbad = false;
210210
int charlen;
211-
int pos = 0;
211+
int pos = 1; /* character position for error messages */
212+
213+
#define UNCHAR ereport(ERROR, \
214+
errcode(ERRCODE_SYNTAX_ERROR), \
215+
errmsg("lquery syntax error at character %d", \
216+
pos))
212217

213218
ptr = buf;
214219
while (*ptr)
@@ -230,7 +235,7 @@ lquery_in(PG_FUNCTION_ARGS)
230235
if (num > LQUERY_MAX_LEVELS)
231236
ereport(ERROR,
232237
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
233-
errmsg("number of lquery levels (%d) exceeds the maximum allowed (%d)",
238+
errmsg("number of lquery items (%d) exceeds the maximum allowed (%d)",
234239
num, LQUERY_MAX_LEVELS)));
235240
curqlevel = tmpql = (lquery_level *) palloc0(ITEMSIZE * num);
236241
ptr = buf;
@@ -305,10 +310,10 @@ lquery_in(PG_FUNCTION_ARGS)
305310
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
306311
ereport(ERROR,
307312
(errcode(ERRCODE_NAME_TOO_LONG),
308-
errmsg("name of level is too long"),
309-
errdetail("Name length is %d, must "
310-
"be < 256, in position %d.",
311-
lptr->wlen, pos)));
313+
errmsg("label string is too long"),
314+
errdetail("Label length is %d, must be at most %d, at character %d.",
315+
lptr->wlen, LTREE_LABEL_MAX_CHARS,
316+
pos)));
312317

313318
state = LQPRS_WAITVAR;
314319
}
@@ -321,10 +326,10 @@ lquery_in(PG_FUNCTION_ARGS)
321326
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
322327
ereport(ERROR,
323328
(errcode(ERRCODE_NAME_TOO_LONG),
324-
errmsg("name of level is too long"),
325-
errdetail("Name length is %d, must "
326-
"be < 256, in position %d.",
327-
lptr->wlen, pos)));
329+
errmsg("label string is too long"),
330+
errdetail("Label length is %d, must be at most %d, at character %d.",
331+
lptr->wlen, LTREE_LABEL_MAX_CHARS,
332+
pos)));
328333

329334
state = LQPRS_WAITLEVEL;
330335
curqlevel = NEXTLEV(curqlevel);
@@ -361,10 +366,10 @@ lquery_in(PG_FUNCTION_ARGS)
361366

362367
if (low < 0 || low > LTREE_MAX_LEVELS)
363368
ereport(ERROR,
364-
(errcode(ERRCODE_SYNTAX_ERROR),
369+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
365370
errmsg("lquery syntax error"),
366-
errdetail("Low limit (%d) exceeds the maximum allowed (%d).",
367-
low, LTREE_MAX_LEVELS)));
371+
errdetail("Low limit (%d) exceeds the maximum allowed (%d), at character %d.",
372+
low, LTREE_MAX_LEVELS, pos)));
368373

369374
curqlevel->low = (uint16) low;
370375
state = LQPRS_WAITND;
@@ -379,11 +384,17 @@ lquery_in(PG_FUNCTION_ARGS)
379384
int high = atoi(ptr);
380385

381386
if (high < 0 || high > LTREE_MAX_LEVELS)
387+
ereport(ERROR,
388+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
389+
errmsg("lquery syntax error"),
390+
errdetail("High limit (%d) exceeds the maximum allowed (%d), at character %d.",
391+
high, LTREE_MAX_LEVELS, pos)));
392+
else if (curqlevel->low > high)
382393
ereport(ERROR,
383394
(errcode(ERRCODE_SYNTAX_ERROR),
384395
errmsg("lquery syntax error"),
385-
errdetail("High limit (%d) exceeds the maximum allowed (%d).",
386-
high, LTREE_MAX_LEVELS)));
396+
errdetail("Low limit (%d) is greater than high limit (%d), at character %d.",
397+
curqlevel->low, high, pos)));
387398

388399
curqlevel->high = (uint16) high;
389400
state = LQPRS_WAITCLOSE;
@@ -441,7 +452,7 @@ lquery_in(PG_FUNCTION_ARGS)
441452
ereport(ERROR,
442453
(errcode(ERRCODE_SYNTAX_ERROR),
443454
errmsg("lquery syntax error"),
444-
errdetail("Unexpected end of line.")));
455+
errdetail("Unexpected end of input.")));
445456

446457
lptr->len = ptr - lptr->start -
447458
((lptr->flag & LVAR_SUBLEXEME) ? 1 : 0) -
@@ -451,23 +462,22 @@ lquery_in(PG_FUNCTION_ARGS)
451462
ereport(ERROR,
452463
(errcode(ERRCODE_SYNTAX_ERROR),
453464
errmsg("lquery syntax error"),
454-
errdetail("Unexpected end of line.")));
465+
errdetail("Unexpected end of input.")));
455466

456467
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
457468
ereport(ERROR,
458469
(errcode(ERRCODE_NAME_TOO_LONG),
459-
errmsg("name of level is too long"),
460-
errdetail("Name length is %d, must "
461-
"be < 256, in position %d.",
462-
lptr->wlen, pos)));
470+
errmsg("label string is too long"),
471+
errdetail("Label length is %d, must be at most %d, at character %d.",
472+
lptr->wlen, LTREE_LABEL_MAX_CHARS, pos)));
463473
}
464474
else if (state == LQPRS_WAITOPEN)
465475
curqlevel->high = LTREE_MAX_LEVELS;
466476
else if (state != LQPRS_WAITEND)
467477
ereport(ERROR,
468478
(errcode(ERRCODE_SYNTAX_ERROR),
469479
errmsg("lquery syntax error"),
470-
errdetail("Unexpected end of line.")));
480+
errdetail("Unexpected end of input.")));
471481

472482
curqlevel = tmpql;
473483
totallen = LQUERY_HDRSIZE;
@@ -483,13 +493,6 @@ lquery_in(PG_FUNCTION_ARGS)
483493
lptr++;
484494
}
485495
}
486-
else if (curqlevel->low > curqlevel->high)
487-
ereport(ERROR,
488-
(errcode(ERRCODE_SYNTAX_ERROR),
489-
errmsg("lquery syntax error"),
490-
errdetail("Low limit (%d) is greater than upper (%d).",
491-
curqlevel->low, curqlevel->high)));
492-
493496
curqlevel = NEXTLEV(curqlevel);
494497
}
495498

@@ -543,6 +546,8 @@ lquery_in(PG_FUNCTION_ARGS)
543546

544547
pfree(tmpql);
545548
PG_RETURN_POINTER(result);
549+
550+
#undef UNCHAR
546551
}
547552

548553
Datum

contrib/ltree/sql/ltree.sql

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ SELECT '*{65536}'::lquery;
100100
SELECT '*{,65534}'::lquery;
101101
SELECT '*{,65535}'::lquery;
102102
SELECT '*{,65536}'::lquery;
103+
SELECT '*{4,3}'::lquery;
103104

104105
SELECT '1.2'::ltree < '2.2'::ltree;
105106
SELECT '1.2'::ltree <= '2.2'::ltree;

contrib/ltree_plpython/expected/ltree_plpython.out

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ $$;
3838
-- because it will try to parse the Python list as an ltree input
3939
-- string.
4040
SELECT test2();
41-
ERROR: syntax error at position 0
41+
ERROR: ltree syntax error at character 1
4242
CONTEXT: while creating return value
4343
PL/Python function "test2"

0 commit comments

Comments
 (0)