@@ -24,16 +24,16 @@ typedef struct
24
24
#define LTPRS_WAITNAME 0
25
25
#define LTPRS_WAITDELIM 1
26
26
27
- static void finish_nodeitem (nodeitem * lptr , const char * ptr ,
28
- bool is_lquery , int pos );
27
+ static bool finish_nodeitem (nodeitem * lptr , const char * ptr ,
28
+ bool is_lquery , int pos , struct Node * escontext );
29
29
30
30
31
31
/*
32
32
* expects a null terminated string
33
33
* returns an ltree
34
34
*/
35
35
static ltree *
36
- parse_ltree (const char * buf )
36
+ parse_ltree (const char * buf , struct Node * escontext )
37
37
{
38
38
const char * ptr ;
39
39
nodeitem * list ,
@@ -46,7 +46,7 @@ parse_ltree(const char *buf)
46
46
int charlen ;
47
47
int pos = 1 ; /* character position for error messages */
48
48
49
- #define UNCHAR ereport(ERROR, \
49
+ #define UNCHAR ereturn(escontext, NULL, \
50
50
errcode(ERRCODE_SYNTAX_ERROR), \
51
51
errmsg("ltree syntax error at character %d", \
52
52
pos))
@@ -61,7 +61,7 @@ parse_ltree(const char *buf)
61
61
}
62
62
63
63
if (num + 1 > LTREE_MAX_LEVELS )
64
- ereport ( ERROR ,
64
+ ereturn ( escontext , NULL ,
65
65
(errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
66
66
errmsg ("number of ltree labels (%d) exceeds the maximum allowed (%d)" ,
67
67
num + 1 , LTREE_MAX_LEVELS )));
@@ -86,7 +86,8 @@ parse_ltree(const char *buf)
86
86
case LTPRS_WAITDELIM :
87
87
if (t_iseq (ptr , '.' ))
88
88
{
89
- finish_nodeitem (lptr , ptr , false, pos );
89
+ if (!finish_nodeitem (lptr , ptr , false, pos , escontext ))
90
+ return NULL ;
90
91
totallen += MAXALIGN (lptr -> len + LEVEL_HDRSIZE );
91
92
lptr ++ ;
92
93
state = LTPRS_WAITNAME ;
@@ -105,12 +106,13 @@ parse_ltree(const char *buf)
105
106
106
107
if (state == LTPRS_WAITDELIM )
107
108
{
108
- finish_nodeitem (lptr , ptr , false, pos );
109
+ if (!finish_nodeitem (lptr , ptr , false, pos , escontext ))
110
+ return NULL ;
109
111
totallen += MAXALIGN (lptr -> len + LEVEL_HDRSIZE );
110
112
lptr ++ ;
111
113
}
112
114
else if (!(state == LTPRS_WAITNAME && lptr == list ))
113
- ereport ( ERROR ,
115
+ ereturn ( escontext , NULL ,
114
116
(errcode (ERRCODE_SYNTAX_ERROR ),
115
117
errmsg ("ltree syntax error" ),
116
118
errdetail ("Unexpected end of input." )));
@@ -172,8 +174,12 @@ Datum
172
174
ltree_in (PG_FUNCTION_ARGS )
173
175
{
174
176
char * buf = (char * ) PG_GETARG_POINTER (0 );
177
+ ltree * res ;
175
178
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 );
177
183
}
178
184
179
185
PG_FUNCTION_INFO_V1 (ltree_out );
@@ -232,7 +238,7 @@ ltree_recv(PG_FUNCTION_ARGS)
232
238
elog (ERROR , "unsupported ltree version number %d" , version );
233
239
234
240
str = pq_getmsgtext (buf , buf -> len - buf -> cursor , & nbytes );
235
- res = parse_ltree (str );
241
+ res = parse_ltree (str , NULL );
236
242
pfree (str );
237
243
238
244
PG_RETURN_POINTER (res );
@@ -259,7 +265,7 @@ ltree_recv(PG_FUNCTION_ARGS)
259
265
* returns an lquery
260
266
*/
261
267
static lquery *
262
- parse_lquery (const char * buf )
268
+ parse_lquery (const char * buf , struct Node * escontext )
263
269
{
264
270
const char * ptr ;
265
271
int num = 0 ,
@@ -277,7 +283,7 @@ parse_lquery(const char *buf)
277
283
int charlen ;
278
284
int pos = 1 ; /* character position for error messages */
279
285
280
- #define UNCHAR ereport(ERROR, \
286
+ #define UNCHAR ereturn(escontext, NULL, \
281
287
errcode(ERRCODE_SYNTAX_ERROR), \
282
288
errmsg("lquery syntax error at character %d", \
283
289
pos))
@@ -297,7 +303,7 @@ parse_lquery(const char *buf)
297
303
298
304
num ++ ;
299
305
if (num > LQUERY_MAX_LEVELS )
300
- ereport ( ERROR ,
306
+ ereturn ( escontext , NULL ,
301
307
(errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
302
308
errmsg ("number of lquery items (%d) exceeds the maximum allowed (%d)" ,
303
309
num , LQUERY_MAX_LEVELS )));
@@ -361,18 +367,21 @@ parse_lquery(const char *buf)
361
367
}
362
368
else if (t_iseq (ptr , '|' ))
363
369
{
364
- finish_nodeitem (lptr , ptr , true, pos );
370
+ if (!finish_nodeitem (lptr , ptr , true, pos , escontext ))
371
+ return NULL ;
365
372
state = LQPRS_WAITVAR ;
366
373
}
367
374
else if (t_iseq (ptr , '{' ))
368
375
{
369
- finish_nodeitem (lptr , ptr , true, pos );
376
+ if (!finish_nodeitem (lptr , ptr , true, pos , escontext ))
377
+ return NULL ;
370
378
curqlevel -> flag |= LQL_COUNT ;
371
379
state = LQPRS_WAITFNUM ;
372
380
}
373
381
else if (t_iseq (ptr , '.' ))
374
382
{
375
- finish_nodeitem (lptr , ptr , true, pos );
383
+ if (!finish_nodeitem (lptr , ptr , true, pos , escontext ))
384
+ return NULL ;
376
385
state = LQPRS_WAITLEVEL ;
377
386
curqlevel = NEXTLEV (curqlevel );
378
387
}
@@ -407,7 +416,7 @@ parse_lquery(const char *buf)
407
416
int low = atoi (ptr );
408
417
409
418
if (low < 0 || low > LTREE_MAX_LEVELS )
410
- ereport ( ERROR ,
419
+ ereturn ( escontext , NULL ,
411
420
(errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
412
421
errmsg ("lquery syntax error" ),
413
422
errdetail ("Low limit (%d) exceeds the maximum allowed (%d), at character %d." ,
@@ -425,13 +434,13 @@ parse_lquery(const char *buf)
425
434
int high = atoi (ptr );
426
435
427
436
if (high < 0 || high > LTREE_MAX_LEVELS )
428
- ereport ( ERROR ,
437
+ ereturn ( escontext , NULL ,
429
438
(errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
430
439
errmsg ("lquery syntax error" ),
431
440
errdetail ("High limit (%d) exceeds the maximum allowed (%d), at character %d." ,
432
441
high , LTREE_MAX_LEVELS , pos )));
433
442
else if (curqlevel -> low > high )
434
- ereport ( ERROR ,
443
+ ereturn ( escontext , NULL ,
435
444
(errcode (ERRCODE_SYNTAX_ERROR ),
436
445
errmsg ("lquery syntax error" ),
437
446
errdetail ("Low limit (%d) is greater than high limit (%d), at character %d." ,
@@ -485,11 +494,14 @@ parse_lquery(const char *buf)
485
494
}
486
495
487
496
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
+ }
489
501
else if (state == LQPRS_WAITOPEN )
490
502
curqlevel -> high = LTREE_MAX_LEVELS ;
491
503
else if (state != LQPRS_WAITEND )
492
- ereport ( ERROR ,
504
+ ereturn ( escontext , NULL ,
493
505
(errcode (ERRCODE_SYNTAX_ERROR ),
494
506
errmsg ("lquery syntax error" ),
495
507
errdetail ("Unexpected end of input." )));
@@ -569,8 +581,9 @@ parse_lquery(const char *buf)
569
581
* Close out parsing an ltree or lquery nodeitem:
570
582
* compute the correct length, and complain if it's not OK
571
583
*/
572
- static void
573
- finish_nodeitem (nodeitem * lptr , const char * ptr , bool is_lquery , int pos )
584
+ static bool
585
+ finish_nodeitem (nodeitem * lptr , const char * ptr , bool is_lquery , int pos ,
586
+ struct Node * escontext )
574
587
{
575
588
if (is_lquery )
576
589
{
@@ -591,18 +604,19 @@ finish_nodeitem(nodeitem *lptr, const char *ptr, bool is_lquery, int pos)
591
604
592
605
/* Complain if it's empty or too long */
593
606
if (lptr -> len == 0 )
594
- ereport ( ERROR ,
607
+ ereturn ( escontext , false ,
595
608
(errcode (ERRCODE_SYNTAX_ERROR ),
596
609
is_lquery ?
597
610
errmsg ("lquery syntax error at character %d" , pos ) :
598
611
errmsg ("ltree syntax error at character %d" , pos ),
599
612
errdetail ("Empty labels are not allowed." )));
600
613
if (lptr -> wlen > LTREE_LABEL_MAX_CHARS )
601
- ereport ( ERROR ,
614
+ ereturn ( escontext , false ,
602
615
(errcode (ERRCODE_NAME_TOO_LONG ),
603
616
errmsg ("label string is too long" ),
604
617
errdetail ("Label length is %d, must be at most %d, at character %d." ,
605
618
lptr -> wlen , LTREE_LABEL_MAX_CHARS , pos )));
619
+ return true;
606
620
}
607
621
608
622
/*
@@ -730,8 +744,12 @@ Datum
730
744
lquery_in (PG_FUNCTION_ARGS )
731
745
{
732
746
char * buf = (char * ) PG_GETARG_POINTER (0 );
747
+ lquery * res ;
748
+
749
+ if ((res = parse_lquery (buf , fcinfo -> context )) == NULL )
750
+ PG_RETURN_NULL ();
733
751
734
- PG_RETURN_POINTER (parse_lquery ( buf ) );
752
+ PG_RETURN_POINTER (res );
735
753
}
736
754
737
755
PG_FUNCTION_INFO_V1 (lquery_out );
@@ -790,7 +808,7 @@ lquery_recv(PG_FUNCTION_ARGS)
790
808
elog (ERROR , "unsupported lquery version number %d" , version );
791
809
792
810
str = pq_getmsgtext (buf , buf -> len - buf -> cursor , & nbytes );
793
- res = parse_lquery (str );
811
+ res = parse_lquery (str , NULL );
794
812
pfree (str );
795
813
796
814
PG_RETURN_POINTER (res );
0 commit comments