Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 20aea2e

Browse files
committed
Alter plpgsql's lexer so that yylineno and yymore are not used. This
avoids 'input buffer overflow' failure on long literals, improves performance, gives the right answer for line position in functions containing multiline literals, suppresses annoying compiler warnings, and generally is so much better I wonder why we didn't do it before.
1 parent ea7896b commit 20aea2e

File tree

4 files changed

+132
-88
lines changed

4 files changed

+132
-88
lines changed

src/pl/plpgsql/src/gram.y

+25-26
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* procedural language
55
*
66
* IDENTIFICATION
7-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.42 2003/04/27 22:21:22 tgl Exp $
7+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.43 2003/05/05 16:46:27 tgl Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -334,7 +334,7 @@ decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval
334334
/* Composite type --- treat as rowtype */
335335
PLpgSQL_row *row;
336336

337-
row = build_rowtype($3->typrelid);
337+
row = plpgsql_build_rowtype($3->typrelid);
338338
row->dtype = PLPGSQL_DTYPE_ROW;
339339
row->refname = $1.name;
340340
row->lineno = $1.lineno;
@@ -486,7 +486,7 @@ decl_cursor_arglist : decl_cursor_arg
486486

487487
new->dtype = PLPGSQL_DTYPE_ROW;
488488
new->refname = strdup("*internal*");
489-
new->lineno = yylineno;
489+
new->lineno = plpgsql_scanner_lineno();
490490
new->rowtypeclass = InvalidOid;
491491
/*
492492
* We make temporary fieldnames/varnos arrays that
@@ -553,7 +553,7 @@ decl_aliasitem : T_WORD
553553
nsi = plpgsql_ns_lookup(name, NULL);
554554
if (nsi == NULL)
555555
{
556-
plpgsql_error_lineno = yylineno;
556+
plpgsql_error_lineno = plpgsql_scanner_lineno();
557557
elog(ERROR, "function has no parameter %s", name);
558558
}
559559

@@ -578,7 +578,7 @@ decl_varname : T_WORD
578578
plpgsql_convert_ident(yytext, &name, 1);
579579
/* name should be malloc'd for use as varname */
580580
$$.name = strdup(name);
581-
$$.lineno = yylineno;
581+
$$.lineno = plpgsql_scanner_lineno();
582582
pfree(name);
583583
}
584584
;
@@ -625,7 +625,7 @@ decl_defval : ';'
625625
PLpgSQL_dstring ds;
626626
PLpgSQL_expr *expr;
627627

628-
lno = yylineno;
628+
lno = plpgsql_scanner_lineno();
629629
expr = malloc(sizeof(PLpgSQL_expr));
630630
plpgsql_dstring_init(&ds);
631631
plpgsql_dstring_append(&ds, "SELECT ");
@@ -1034,7 +1034,7 @@ fori_varname : T_VARIABLE
10341034
plpgsql_convert_ident(yytext, &name, 1);
10351035
/* name should be malloc'd for use as varname */
10361036
$$.name = strdup(name);
1037-
$$.lineno = yylineno;
1037+
$$.lineno = plpgsql_scanner_lineno();
10381038
pfree(name);
10391039
}
10401040
| T_WORD
@@ -1044,7 +1044,7 @@ fori_varname : T_VARIABLE
10441044
plpgsql_convert_ident(yytext, &name, 1);
10451045
/* name should be malloc'd for use as varname */
10461046
$$.name = strdup(name);
1047-
$$.lineno = yylineno;
1047+
$$.lineno = plpgsql_scanner_lineno();
10481048
pfree(name);
10491049
}
10501050
;
@@ -1405,7 +1405,7 @@ stmt_open : K_OPEN lno cursor_varptr
14051405

14061406
if (tok != '(')
14071407
{
1408-
plpgsql_error_lineno = yylineno;
1408+
plpgsql_error_lineno = plpgsql_scanner_lineno();
14091409
elog(ERROR, "cursor %s has arguments",
14101410
$3->refname);
14111411
}
@@ -1427,7 +1427,7 @@ stmt_open : K_OPEN lno cursor_varptr
14271427

14281428
if (strncmp(cp, "SELECT", 6) != 0)
14291429
{
1430-
plpgsql_error_lineno = yylineno;
1430+
plpgsql_error_lineno = plpgsql_scanner_lineno();
14311431
elog(ERROR, "expected 'SELECT (', got '%s' (internal error)",
14321432
new->argquery->query);
14331433
}
@@ -1436,7 +1436,7 @@ stmt_open : K_OPEN lno cursor_varptr
14361436
cp++;
14371437
if (*cp != '(')
14381438
{
1439-
plpgsql_error_lineno = yylineno;
1439+
plpgsql_error_lineno = plpgsql_scanner_lineno();
14401440
elog(ERROR, "expected 'SELECT (', got '%s' (internal error)",
14411441
new->argquery->query);
14421442
}
@@ -1454,13 +1454,13 @@ stmt_open : K_OPEN lno cursor_varptr
14541454

14551455
if (tok == '(')
14561456
{
1457-
plpgsql_error_lineno = yylineno;
1457+
plpgsql_error_lineno = plpgsql_scanner_lineno();
14581458
elog(ERROR, "cursor %s has no arguments", $3->refname);
14591459
}
14601460

14611461
if (tok != ';')
14621462
{
1463-
plpgsql_error_lineno = yylineno;
1463+
plpgsql_error_lineno = plpgsql_scanner_lineno();
14641464
elog(ERROR, "syntax error at \"%s\"", yytext);
14651465
}
14661466
}
@@ -1502,7 +1502,7 @@ cursor_varptr : T_VARIABLE
15021502

15031503
if (((PLpgSQL_var *) yylval.variable)->datatype->typoid != REFCURSOROID)
15041504
{
1505-
plpgsql_error_lineno = yylineno;
1505+
plpgsql_error_lineno = plpgsql_scanner_lineno();
15061506
elog(ERROR, "%s must be of type cursor or refcursor",
15071507
((PLpgSQL_var *) yylval.variable)->refname);
15081508
}
@@ -1517,7 +1517,7 @@ cursor_variable : T_VARIABLE
15171517

15181518
if (((PLpgSQL_var *) yylval.variable)->datatype->typoid != REFCURSOROID)
15191519
{
1520-
plpgsql_error_lineno = yylineno;
1520+
plpgsql_error_lineno = plpgsql_scanner_lineno();
15211521
elog(ERROR, "%s must be of type refcursor",
15221522
((PLpgSQL_var *) yylval.variable)->refname);
15231523
}
@@ -1583,8 +1583,7 @@ opt_lblname : T_WORD
15831583

15841584
lno :
15851585
{
1586-
plpgsql_error_lineno = yylineno;
1587-
$$ = yylineno;
1586+
$$ = plpgsql_error_lineno = plpgsql_scanner_lineno();
15881587
}
15891588
;
15901589

@@ -1618,7 +1617,7 @@ read_sql_construct(int until,
16181617
char buf[32];
16191618
PLpgSQL_expr *expr;
16201619

1621-
lno = yylineno;
1620+
lno = plpgsql_scanner_lineno();
16221621
plpgsql_dstring_init(&ds);
16231622
plpgsql_dstring_append(&ds, (char *) sqlstart);
16241623

@@ -1690,7 +1689,7 @@ read_datatype(int tok)
16901689
bool needspace = false;
16911690
int parenlevel = 0;
16921691

1693-
lno = yylineno;
1692+
lno = plpgsql_scanner_lineno();
16941693

16951694
/* Often there will be a lookahead token, but if not, get one */
16961695
if (tok == YYEMPTY)
@@ -1769,14 +1768,14 @@ make_select_stmt(void)
17691768
break;
17701769
if (tok == 0)
17711770
{
1772-
plpgsql_error_lineno = yylineno;
1771+
plpgsql_error_lineno = plpgsql_scanner_lineno();
17731772
elog(ERROR, "unexpected end of file");
17741773
}
17751774
if (tok == K_INTO)
17761775
{
17771776
if (have_into)
17781777
{
1779-
plpgsql_error_lineno = yylineno;
1778+
plpgsql_error_lineno = plpgsql_scanner_lineno();
17801779
elog(ERROR, "INTO specified more than once");
17811780
}
17821781
tok = yylex();
@@ -1814,7 +1813,7 @@ make_select_stmt(void)
18141813
break;
18151814

18161815
default:
1817-
plpgsql_error_lineno = yylineno;
1816+
plpgsql_error_lineno = plpgsql_scanner_lineno();
18181817
elog(ERROR, "plpgsql: %s is not a variable",
18191818
yytext);
18201819
}
@@ -1824,7 +1823,7 @@ make_select_stmt(void)
18241823
row = malloc(sizeof(PLpgSQL_row));
18251824
row->dtype = PLPGSQL_DTYPE_ROW;
18261825
row->refname = strdup("*internal*");
1827-
row->lineno = yylineno;
1826+
row->lineno = plpgsql_scanner_lineno();
18281827
row->rowtypeclass = InvalidOid;
18291828
row->nfields = nfields;
18301829
row->fieldnames = malloc(sizeof(char *) * nfields);
@@ -1945,7 +1944,7 @@ make_fetch_stmt(void)
19451944
break;
19461945

19471946
default:
1948-
plpgsql_error_lineno = yylineno;
1947+
plpgsql_error_lineno = plpgsql_scanner_lineno();
19491948
elog(ERROR, "plpgsql: %s is not a variable",
19501949
yytext);
19511950
}
@@ -1955,7 +1954,7 @@ make_fetch_stmt(void)
19551954
row = malloc(sizeof(PLpgSQL_row));
19561955
row->dtype = PLPGSQL_DTYPE_ROW;
19571956
row->refname = strdup("*internal*");
1958-
row->lineno = yylineno;
1957+
row->lineno = plpgsql_scanner_lineno();
19591958
row->rowtypeclass = InvalidOid;
19601959
row->nfields = nfields;
19611960
row->fieldnames = malloc(sizeof(char *) * nfields);
@@ -2028,7 +2027,7 @@ check_assignable(PLpgSQL_datum *datum)
20282027
case PLPGSQL_DTYPE_VAR:
20292028
if (((PLpgSQL_var *) datum)->isconst)
20302029
{
2031-
plpgsql_error_lineno = yylineno;
2030+
plpgsql_error_lineno = plpgsql_scanner_lineno();
20322031
elog(ERROR, "%s is declared CONSTANT",
20332032
((PLpgSQL_var *) datum)->refname);
20342033
}

src/pl/plpgsql/src/pl_comp.c

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.57 2003/04/27 22:21:22 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.58 2003/05/05 16:46:27 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -141,7 +141,8 @@ plpgsql_compile(Oid fn_oid, int functype)
141141
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
142142
proc_source = DatumGetCString(DirectFunctionCall1(textout,
143143
PointerGetDatum(&procStruct->prosrc)));
144-
plpgsql_setinput(proc_source, functype);
144+
plpgsql_scanner_init(proc_source, functype);
145+
pfree(proc_source);
145146

146147
plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname));
147148
plpgsql_error_lineno = 0;
@@ -258,7 +259,7 @@ plpgsql_compile(Oid fn_oid, int functype)
258259
* For tuple type parameters, we set up a record of
259260
* that type
260261
*/
261-
row = build_rowtype(typeStruct->typrelid);
262+
row = plpgsql_build_rowtype(typeStruct->typrelid);
262263

263264
row->refname = strdup(buf);
264265

@@ -496,6 +497,8 @@ plpgsql_compile(Oid fn_oid, int functype)
496497
if (parse_rc != 0)
497498
elog(ERROR, "plpgsql: parser returned %d ???", parse_rc);
498499

500+
plpgsql_scanner_finish();
501+
499502
/*
500503
* If that was successful, complete the functions info.
501504
*/
@@ -1200,7 +1203,7 @@ plpgsql_parse_wordrowtype(char *word)
12001203
/*
12011204
* Build and return the complete row definition
12021205
*/
1203-
plpgsql_yylval.row = build_rowtype(classOid);
1206+
plpgsql_yylval.row = plpgsql_build_rowtype(classOid);
12041207

12051208
pfree(cp[0]);
12061209
pfree(cp[1]);
@@ -1241,7 +1244,7 @@ plpgsql_parse_dblwordrowtype(char *word)
12411244
/*
12421245
* Build and return the complete row definition
12431246
*/
1244-
plpgsql_yylval.row = build_rowtype(classOid);
1247+
plpgsql_yylval.row = plpgsql_build_rowtype(classOid);
12451248

12461249
pfree(cp);
12471250

@@ -1252,7 +1255,7 @@ plpgsql_parse_dblwordrowtype(char *word)
12521255
* Build a rowtype data structure given the pg_class OID.
12531256
*/
12541257
PLpgSQL_row *
1255-
build_rowtype(Oid classOid)
1258+
plpgsql_build_rowtype(Oid classOid)
12561259
{
12571260
PLpgSQL_row *row;
12581261
HeapTuple classtup;
@@ -1494,6 +1497,6 @@ plpgsql_add_initdatums(int **varnos)
14941497
void
14951498
plpgsql_yyerror(const char *s)
14961499
{
1497-
plpgsql_error_lineno = plpgsql_yylineno;
1500+
plpgsql_error_lineno = plpgsql_scanner_lineno();
14981501
elog(ERROR, "%s at or near \"%s\"", s, plpgsql_yytext);
14991502
}

src/pl/plpgsql/src/plpgsql.h

+6-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.35 2003/04/27 22:21:22 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.36 2003/05/05 16:46:28 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -573,13 +573,10 @@ extern PLpgSQL_datum **plpgsql_Datums;
573573
extern int plpgsql_error_lineno;
574574
extern char *plpgsql_error_funcname;
575575

576-
/* linkage to the real yytext and yylineno variables */
576+
/* linkage to the real yytext variable */
577577
extern char *plpgsql_base_yytext;
578578

579579
#define plpgsql_yytext plpgsql_base_yytext
580-
extern int plpgsql_base_yylineno;
581-
582-
#define plpgsql_yylineno plpgsql_base_yylineno
583580

584581
extern PLpgSQL_function *plpgsql_curr_compile;
585582

@@ -601,7 +598,7 @@ extern int plpgsql_parse_tripwordtype(char *word);
601598
extern int plpgsql_parse_wordrowtype(char *word);
602599
extern int plpgsql_parse_dblwordrowtype(char *word);
603600
extern PLpgSQL_type *plpgsql_parse_datatype(char *string);
604-
extern PLpgSQL_row *build_rowtype(Oid classOid);
601+
extern PLpgSQL_row *plpgsql_build_rowtype(Oid classOid);
605602
extern void plpgsql_adddatum(PLpgSQL_datum * new);
606603
extern int plpgsql_add_initdatums(int **varnos);
607604
extern void plpgsql_yyerror(const char *s);
@@ -660,6 +657,8 @@ extern int plpgsql_yyparse(void);
660657
extern int plpgsql_base_yylex(void);
661658
extern int plpgsql_yylex(void);
662659
extern void plpgsql_push_back_token(int token);
663-
extern void plpgsql_setinput(char *s, int functype);
660+
extern int plpgsql_scanner_lineno(void);
661+
extern void plpgsql_scanner_init(const char *str, int functype);
662+
extern void plpgsql_scanner_finish(void);
664663

665664
#endif /* PLPGSQL_H */

0 commit comments

Comments
 (0)