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

Commit7a05425

Browse files
committed
Convert contrib/ltree's input functions to report errors softly
Reviewed by Tom Lane and Amul SulDiscussion:https://postgr.es/m/49e598c2-cfe8-0928-b6fb-d0cc51aab626@dunslane.net
1 parent3b76622 commit7a05425

File tree

4 files changed

+137
-50
lines changed

4 files changed

+137
-50
lines changed

‎contrib/ltree/expected/ltree.out

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8084,3 +8084,28 @@ SELECT count(*) FROM _ltreetest WHERE t ? '{23.*.1,23.*.2}' ;
80848084
15
80858085
(1 row)
80868086

8087+
-- test non-error-throwing input
8088+
SELECT str as "value", typ as "type",
8089+
pg_input_is_valid(str,typ) as ok,
8090+
pg_input_error_message(str,typ) as errmsg
8091+
FROM (VALUES ('.2.3', 'ltree'),
8092+
('1.2.', 'ltree'),
8093+
('1.2.3','ltree'),
8094+
('@.2.3','lquery'),
8095+
(' 2.3', 'lquery'),
8096+
('1.2.3','lquery'),
8097+
('$tree & aWdf@*','ltxtquery'),
8098+
('!tree & aWdf@*','ltxtquery'))
8099+
AS a(str,typ);
8100+
value | type | ok | errmsg
8101+
----------------+-----------+----+------------------------------------
8102+
.2.3 | ltree | f | ltree syntax error at character 1
8103+
1.2. | ltree | f | ltree syntax error
8104+
1.2.3 | ltree | t |
8105+
@.2.3 | lquery | f | lquery syntax error at character 1
8106+
2.3 | lquery | f | lquery syntax error at character 1
8107+
1.2.3 | lquery | t |
8108+
$tree & aWdf@* | ltxtquery | f | operand syntax error
8109+
!tree & aWdf@* | ltxtquery | t |
8110+
(8 rows)
8111+

‎contrib/ltree/ltree_io.c

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ typedef struct
2424
#defineLTPRS_WAITNAME0
2525
#defineLTPRS_WAITDELIM 1
2626

27-
staticvoidfinish_nodeitem(nodeitem*lptr,constchar*ptr,
28-
boolis_lquery,intpos);
27+
staticboolfinish_nodeitem(nodeitem*lptr,constchar*ptr,
28+
boolis_lquery,intpos,structNode*escontext);
2929

3030

3131
/*
3232
* expects a null terminated string
3333
* returns an ltree
3434
*/
3535
staticltree*
36-
parse_ltree(constchar*buf)
36+
parse_ltree(constchar*buf,structNode*escontext)
3737
{
3838
constchar*ptr;
3939
nodeitem*list,
@@ -46,7 +46,7 @@ parse_ltree(const char *buf)
4646
intcharlen;
4747
intpos=1;/* character position for error messages */
4848

49-
#defineUNCHARereport(ERROR,\
49+
#defineUNCHARereturn(escontext, NULL,\
5050
errcode(ERRCODE_SYNTAX_ERROR), \
5151
errmsg("ltree syntax error at character %d", \
5252
pos))
@@ -61,7 +61,7 @@ parse_ltree(const char *buf)
6161
}
6262

6363
if (num+1>LTREE_MAX_LEVELS)
64-
ereport(ERROR,
64+
ereturn(escontext,NULL,
6565
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
6666
errmsg("number of ltree labels (%d) exceeds the maximum allowed (%d)",
6767
num+1,LTREE_MAX_LEVELS)));
@@ -86,7 +86,8 @@ parse_ltree(const char *buf)
8686
caseLTPRS_WAITDELIM:
8787
if (t_iseq(ptr,'.'))
8888
{
89-
finish_nodeitem(lptr,ptr, false,pos);
89+
if (!finish_nodeitem(lptr,ptr, false,pos,escontext))
90+
returnNULL;
9091
totallen+=MAXALIGN(lptr->len+LEVEL_HDRSIZE);
9192
lptr++;
9293
state=LTPRS_WAITNAME;
@@ -105,12 +106,13 @@ parse_ltree(const char *buf)
105106

106107
if (state==LTPRS_WAITDELIM)
107108
{
108-
finish_nodeitem(lptr,ptr, false,pos);
109+
if (!finish_nodeitem(lptr,ptr, false,pos,escontext))
110+
returnNULL;
109111
totallen+=MAXALIGN(lptr->len+LEVEL_HDRSIZE);
110112
lptr++;
111113
}
112114
elseif (!(state==LTPRS_WAITNAME&&lptr==list))
113-
ereport(ERROR,
115+
ereturn(escontext,NULL,
114116
(errcode(ERRCODE_SYNTAX_ERROR),
115117
errmsg("ltree syntax error"),
116118
errdetail("Unexpected end of input.")));
@@ -172,8 +174,12 @@ Datum
172174
ltree_in(PG_FUNCTION_ARGS)
173175
{
174176
char*buf= (char*)PG_GETARG_POINTER(0);
177+
ltree*res;
175178

176-
PG_RETURN_POINTER(parse_ltree(buf));
179+
if ((res=parse_ltree(buf,fcinfo->context))==NULL)
180+
PG_RETURN_NULL();
181+
182+
PG_RETURN_POINTER(res);
177183
}
178184

179185
PG_FUNCTION_INFO_V1(ltree_out);
@@ -232,7 +238,7 @@ ltree_recv(PG_FUNCTION_ARGS)
232238
elog(ERROR,"unsupported ltree version number %d",version);
233239

234240
str=pq_getmsgtext(buf,buf->len-buf->cursor,&nbytes);
235-
res=parse_ltree(str);
241+
res=parse_ltree(str,NULL);
236242
pfree(str);
237243

238244
PG_RETURN_POINTER(res);
@@ -259,7 +265,7 @@ ltree_recv(PG_FUNCTION_ARGS)
259265
* returns an lquery
260266
*/
261267
staticlquery*
262-
parse_lquery(constchar*buf)
268+
parse_lquery(constchar*buf,structNode*escontext)
263269
{
264270
constchar*ptr;
265271
intnum=0,
@@ -277,7 +283,7 @@ parse_lquery(const char *buf)
277283
intcharlen;
278284
intpos=1;/* character position for error messages */
279285

280-
#defineUNCHARereport(ERROR,\
286+
#defineUNCHARereturn(escontext, NULL,\
281287
errcode(ERRCODE_SYNTAX_ERROR), \
282288
errmsg("lquery syntax error at character %d", \
283289
pos))
@@ -297,7 +303,7 @@ parse_lquery(const char *buf)
297303

298304
num++;
299305
if (num>LQUERY_MAX_LEVELS)
300-
ereport(ERROR,
306+
ereturn(escontext,NULL,
301307
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
302308
errmsg("number of lquery items (%d) exceeds the maximum allowed (%d)",
303309
num,LQUERY_MAX_LEVELS)));
@@ -361,18 +367,21 @@ parse_lquery(const char *buf)
361367
}
362368
elseif (t_iseq(ptr,'|'))
363369
{
364-
finish_nodeitem(lptr,ptr, true,pos);
370+
if (!finish_nodeitem(lptr,ptr, true,pos,escontext))
371+
returnNULL;
365372
state=LQPRS_WAITVAR;
366373
}
367374
elseif (t_iseq(ptr,'{'))
368375
{
369-
finish_nodeitem(lptr,ptr, true,pos);
376+
if (!finish_nodeitem(lptr,ptr, true,pos,escontext))
377+
returnNULL;
370378
curqlevel->flag |=LQL_COUNT;
371379
state=LQPRS_WAITFNUM;
372380
}
373381
elseif (t_iseq(ptr,'.'))
374382
{
375-
finish_nodeitem(lptr,ptr, true,pos);
383+
if (!finish_nodeitem(lptr,ptr, true,pos,escontext))
384+
returnNULL;
376385
state=LQPRS_WAITLEVEL;
377386
curqlevel=NEXTLEV(curqlevel);
378387
}
@@ -407,7 +416,7 @@ parse_lquery(const char *buf)
407416
intlow=atoi(ptr);
408417

409418
if (low<0||low>LTREE_MAX_LEVELS)
410-
ereport(ERROR,
419+
ereturn(escontext,NULL,
411420
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
412421
errmsg("lquery syntax error"),
413422
errdetail("Low limit (%d) exceeds the maximum allowed (%d), at character %d.",
@@ -425,13 +434,13 @@ parse_lquery(const char *buf)
425434
inthigh=atoi(ptr);
426435

427436
if (high<0||high>LTREE_MAX_LEVELS)
428-
ereport(ERROR,
437+
ereturn(escontext,NULL,
429438
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
430439
errmsg("lquery syntax error"),
431440
errdetail("High limit (%d) exceeds the maximum allowed (%d), at character %d.",
432441
high,LTREE_MAX_LEVELS,pos)));
433442
elseif (curqlevel->low>high)
434-
ereport(ERROR,
443+
ereturn(escontext,NULL,
435444
(errcode(ERRCODE_SYNTAX_ERROR),
436445
errmsg("lquery syntax error"),
437446
errdetail("Low limit (%d) is greater than high limit (%d), at character %d.",
@@ -485,11 +494,14 @@ parse_lquery(const char *buf)
485494
}
486495

487496
if (state==LQPRS_WAITDELIM)
488-
finish_nodeitem(lptr,ptr, true,pos);
497+
{
498+
if (!finish_nodeitem(lptr,ptr, true,pos,escontext))
499+
return false;
500+
}
489501
elseif (state==LQPRS_WAITOPEN)
490502
curqlevel->high=LTREE_MAX_LEVELS;
491503
elseif (state!=LQPRS_WAITEND)
492-
ereport(ERROR,
504+
ereturn(escontext,NULL,
493505
(errcode(ERRCODE_SYNTAX_ERROR),
494506
errmsg("lquery syntax error"),
495507
errdetail("Unexpected end of input.")));
@@ -569,8 +581,9 @@ parse_lquery(const char *buf)
569581
* Close out parsing an ltree or lquery nodeitem:
570582
* compute the correct length, and complain if it's not OK
571583
*/
572-
staticvoid
573-
finish_nodeitem(nodeitem*lptr,constchar*ptr,boolis_lquery,intpos)
584+
staticbool
585+
finish_nodeitem(nodeitem*lptr,constchar*ptr,boolis_lquery,intpos,
586+
structNode*escontext)
574587
{
575588
if (is_lquery)
576589
{
@@ -591,18 +604,19 @@ finish_nodeitem(nodeitem *lptr, const char *ptr, bool is_lquery, int pos)
591604

592605
/* Complain if it's empty or too long */
593606
if (lptr->len==0)
594-
ereport(ERROR,
607+
ereturn(escontext, false,
595608
(errcode(ERRCODE_SYNTAX_ERROR),
596609
is_lquery ?
597610
errmsg("lquery syntax error at character %d",pos) :
598611
errmsg("ltree syntax error at character %d",pos),
599612
errdetail("Empty labels are not allowed.")));
600613
if (lptr->wlen>LTREE_LABEL_MAX_CHARS)
601-
ereport(ERROR,
614+
ereturn(escontext, false,
602615
(errcode(ERRCODE_NAME_TOO_LONG),
603616
errmsg("label string is too long"),
604617
errdetail("Label length is %d, must be at most %d, at character %d.",
605618
lptr->wlen,LTREE_LABEL_MAX_CHARS,pos)));
619+
return true;
606620
}
607621

608622
/*
@@ -730,8 +744,12 @@ Datum
730744
lquery_in(PG_FUNCTION_ARGS)
731745
{
732746
char*buf= (char*)PG_GETARG_POINTER(0);
747+
lquery*res;
748+
749+
if ((res=parse_lquery(buf,fcinfo->context))==NULL)
750+
PG_RETURN_NULL();
733751

734-
PG_RETURN_POINTER(parse_lquery(buf));
752+
PG_RETURN_POINTER(res);
735753
}
736754

737755
PG_FUNCTION_INFO_V1(lquery_out);
@@ -790,7 +808,7 @@ lquery_recv(PG_FUNCTION_ARGS)
790808
elog(ERROR,"unsupported lquery version number %d",version);
791809

792810
str=pq_getmsgtext(buf,buf->len-buf->cursor,&nbytes);
793-
res=parse_lquery(str);
811+
res=parse_lquery(str,NULL);
794812
pfree(str);
795813

796814
PG_RETURN_POINTER(res);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp