Skip to content

Commit 2f1c24c

Browse files
committed
Change plpgsql compiler so that all elogs are trapped and a suitable
NOTICE added about error location (same method already used by plpgsql executor). Add checking of pg_proc row xmin/cmin to ensure that plpgsql functions will be recompiled after they've been modified by CREATE OR REPLACE FUNCTION.
1 parent c781600 commit 2f1c24c

File tree

6 files changed

+145
-110
lines changed

6 files changed

+145
-110
lines changed

src/pl/plpgsql/src/gram.y

Lines changed: 27 additions & 26 deletions
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.26 2001/10/09 04:15:38 tgl Exp $
7+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.27 2001/10/09 15:59:56 tgl Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -507,10 +507,16 @@ decl_aliasitem : T_WORD
507507
plpgsql_ns_setlocal(false);
508508
name = plpgsql_tolower(yytext);
509509
if (name[0] != '$')
510+
{
511+
plpgsql_error_lineno = yylineno;
510512
elog(ERROR, "can only alias positional parameters");
513+
}
511514
nsi = plpgsql_ns_lookup(name, NULL);
512515
if (nsi == NULL)
516+
{
517+
plpgsql_error_lineno = yylineno;
513518
elog(ERROR, "function has no parameter %s", name);
519+
}
514520

515521
plpgsql_ns_setlocal(true);
516522

@@ -585,14 +591,12 @@ decl_defval : ';'
585591
{
586592
case 0:
587593
plpgsql_error_lineno = lno;
588-
plpgsql_comperrinfo();
589594
elog(ERROR, "unexpected end of file");
590595
case K_NULL:
591596
if (yylex() != ';')
592597
{
593598
plpgsql_error_lineno = lno;
594-
plpgsql_comperrinfo();
595-
elog(ERROR, "expectec ; after NULL");
599+
elog(ERROR, "expected ; after NULL");
596600
}
597601
free(expr);
598602
plpgsql_dstring_free(&ds);
@@ -607,7 +611,6 @@ decl_defval : ';'
607611
if (tok == 0)
608612
{
609613
plpgsql_error_lineno = lno;
610-
plpgsql_comperrinfo();
611614
elog(ERROR, "unterminated default value");
612615
}
613616
if (plpgsql_SpaceScanned)
@@ -793,7 +796,7 @@ getdiag_target : T_VARIABLE
793796
{
794797
if (yylval.var->isconst)
795798
{
796-
plpgsql_comperrinfo();
799+
plpgsql_error_lineno = yylineno;
797800
elog(ERROR, "%s is declared CONSTANT; can not receive diagnostics", yylval.var->refname);
798801
}
799802
$$ = yylval.var->varno;
@@ -809,7 +812,7 @@ assign_var : T_VARIABLE
809812
{
810813
if (yylval.var->isconst)
811814
{
812-
plpgsql_comperrinfo();
815+
plpgsql_error_lineno = yylineno;
813816
elog(ERROR, "%s is declared CONSTANT", yylval.var->refname);
814817
}
815818
$$ = yylval.var->varno;
@@ -1045,7 +1048,6 @@ fori_lower :
10451048
if (tok == 0)
10461049
{
10471050
plpgsql_error_lineno = lno;
1048-
plpgsql_comperrinfo();
10491051
elog(ERROR, "missing .. to terminate lower bound of for loop");
10501052
}
10511053
plpgsql_dstring_append(&ds, yytext);
@@ -1083,7 +1085,6 @@ stmt_fors : opt_label K_FOR lno fors_target K_IN K_SELECT expr_until_loop loop_
10831085
new->row = (PLpgSQL_row *)$4;
10841086
break;
10851087
default:
1086-
plpgsql_comperrinfo();
10871088
elog(ERROR, "unknown dtype %d in stmt_fors", $4->dtype);
10881089
}
10891090
new->query = $7;
@@ -1113,7 +1114,6 @@ stmt_dynfors : opt_label K_FOR lno fors_target K_IN K_EXECUTE expr_until_loop lo
11131114
new->row = (PLpgSQL_row *)$4;
11141115
break;
11151116
default:
1116-
plpgsql_comperrinfo();
11171117
elog(ERROR, "unknown dtype %d in stmt_dynfors", $4->dtype);
11181118
}
11191119
new->query = $7;
@@ -1339,7 +1339,7 @@ stmt_open : K_OPEN lno cursor_varptr
13391339

13401340
if (tok != K_FOR)
13411341
{
1342-
plpgsql_comperrinfo();
1342+
plpgsql_error_lineno = $2;
13431343
elog(ERROR, "syntax error at \"%s\" - expected FOR to open a reference cursor", yytext);
13441344
}
13451345

@@ -1355,7 +1355,7 @@ stmt_open : K_OPEN lno cursor_varptr
13551355
break;
13561356

13571357
default:
1358-
plpgsql_comperrinfo();
1358+
plpgsql_error_lineno = $2;
13591359
elog(ERROR, "syntax error at \"%s\"", yytext);
13601360
}
13611361

@@ -1370,7 +1370,7 @@ stmt_open : K_OPEN lno cursor_varptr
13701370

13711371
if (tok != '(')
13721372
{
1373-
plpgsql_comperrinfo();
1373+
plpgsql_error_lineno = yylineno;
13741374
elog(ERROR, "cursor %s has arguments", $3->refname);
13751375
}
13761376

@@ -1384,7 +1384,7 @@ stmt_open : K_OPEN lno cursor_varptr
13841384
--cp;
13851385
if (*cp != ')')
13861386
{
1387-
plpgsql_comperrinfo();
1387+
plpgsql_error_lineno = yylineno;
13881388
elog(ERROR, "missing )");
13891389
}
13901390
*cp = '\0';
@@ -1395,13 +1395,13 @@ stmt_open : K_OPEN lno cursor_varptr
13951395

13961396
if (tok == '(')
13971397
{
1398-
plpgsql_comperrinfo();
1398+
plpgsql_error_lineno = yylineno;
13991399
elog(ERROR, "cursor %s has no arguments", $3->refname);
14001400
}
14011401

14021402
if (tok != ';')
14031403
{
1404-
plpgsql_comperrinfo();
1404+
plpgsql_error_lineno = yylineno;
14051405
elog(ERROR, "syntax error at \"%s\"", yytext);
14061406
}
14071407
}
@@ -1440,7 +1440,7 @@ cursor_varptr : T_VARIABLE
14401440
{
14411441
if (yylval.var->datatype->typoid != REFCURSOROID)
14421442
{
1443-
plpgsql_comperrinfo();
1443+
plpgsql_error_lineno = yylineno;
14441444
elog(ERROR, "%s must be of type cursor or refcursor", yylval.var->refname);
14451445
}
14461446
$$ = yylval.var;
@@ -1451,7 +1451,7 @@ cursor_variable : T_VARIABLE
14511451
{
14521452
if (yylval.var->datatype->typoid != REFCURSOROID)
14531453
{
1454-
plpgsql_comperrinfo();
1454+
plpgsql_error_lineno = yylineno;
14551455
elog(ERROR, "%s must be of type refcursor", yylval.var->refname);
14561456
}
14571457
$$ = yylval.var->varno;
@@ -1545,7 +1545,6 @@ read_sqlstmt (int until, char *s, char *sqlstart)
15451545
{
15461546
case 0:
15471547
plpgsql_error_lineno = lno;
1548-
plpgsql_comperrinfo();
15491548
elog(ERROR, "missing %s at end of SQL statement", s);
15501549
break;
15511550

@@ -1613,7 +1612,6 @@ read_datatype(int tok)
16131612
if (tok == 0)
16141613
{
16151614
plpgsql_error_lineno = lno;
1616-
plpgsql_comperrinfo();
16171615
elog(ERROR, "incomplete datatype declaration");
16181616
}
16191617
/* Possible followers for datatype in a declaration */
@@ -1636,6 +1634,8 @@ read_datatype(int tok)
16361634

16371635
plpgsql_push_back_token(tok);
16381636

1637+
plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
1638+
16391639
result = plpgsql_parse_datatype(plpgsql_dstring_get(&ds));
16401640

16411641
plpgsql_dstring_free(&ds);
@@ -1711,7 +1711,6 @@ make_select_stmt()
17111711
if (tok == 0)
17121712
{
17131713
plpgsql_error_lineno = yylineno;
1714-
plpgsql_comperrinfo();
17151714
elog(ERROR, "unexpected end of file");
17161715
}
17171716
plpgsql_dstring_append(&ds, yytext);
@@ -1772,6 +1771,7 @@ make_select_stmt()
17721771
break;
17731772

17741773
default:
1774+
plpgsql_error_lineno = yylineno;
17751775
elog(ERROR, "plpgsql: %s is not a variable or record field", yytext);
17761776
}
17771777
}
@@ -1850,7 +1850,6 @@ make_select_stmt()
18501850
if (tok == 0)
18511851
{
18521852
plpgsql_error_lineno = yylineno;
1853-
plpgsql_comperrinfo();
18541853
elog(ERROR, "unexpected end of file");
18551854
}
18561855
plpgsql_dstring_append(&ds, yytext);
@@ -1899,7 +1898,6 @@ make_select_stmt()
18991898
if (tok == 0)
19001899
{
19011900
plpgsql_error_lineno = yylineno;
1902-
plpgsql_comperrinfo();
19031901
elog(ERROR, "unexpected end of file");
19041902
}
19051903
plpgsql_dstring_append(&ds, yytext);
@@ -1989,6 +1987,7 @@ make_fetch_stmt()
19891987
break;
19901988

19911989
default:
1990+
plpgsql_error_lineno = yylineno;
19921991
elog(ERROR, "plpgsql: %s is not a variable or record field", yytext);
19931992
}
19941993
}
@@ -2013,16 +2012,18 @@ make_fetch_stmt()
20132012
break;
20142013

20152014
default:
2016-
{
2017-
elog(ERROR, "syntax error at '%s'", yytext);
2018-
}
2015+
plpgsql_error_lineno = yylineno;
2016+
elog(ERROR, "syntax error at '%s'", yytext);
20192017
}
20202018

20212019
if (!have_nexttok)
20222020
tok = yylex();
20232021

20242022
if (tok != ';')
2023+
{
2024+
plpgsql_error_lineno = yylineno;
20252025
elog(ERROR, "syntax error at '%s'", yytext);
2026+
}
20262027

20272028
fetch = malloc(sizeof(PLpgSQL_stmt_select));
20282029
memset(fetch, 0, sizeof(PLpgSQL_stmt_fetch));

0 commit comments

Comments
 (0)