v3-0003-plpgsql-pure-parser.patch
text/plain
Filename: v3-0003-plpgsql-pure-parser.patch
Type: text/plain
Part: 2
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v3-0003
Subject: plpgsql: pure parser
| File | + | − |
|---|---|---|
| src/pl/plpgsql/src/nls.mk | 1 | 1 |
| src/pl/plpgsql/src/pl_gram.y | 302 | 300 |
| src/pl/plpgsql/src/plpgsql.h | 5 | 3 |
| src/pl/plpgsql/src/pl_scanner.c | 10 | 10 |
From 5821e9ce7ff85f7304c56f8ff0483f2e07b3be8e Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Thu, 26 Dec 2024 00:08:25 +0100
Subject: [PATCH v3 3/4] plpgsql: pure parser
---
src/pl/plpgsql/src/nls.mk | 2 +-
src/pl/plpgsql/src/pl_gram.y | 602 ++++++++++++++++----------------
src/pl/plpgsql/src/pl_scanner.c | 20 +-
src/pl/plpgsql/src/plpgsql.h | 8 +-
4 files changed, 318 insertions(+), 314 deletions(-)
diff --git a/src/pl/plpgsql/src/nls.mk b/src/pl/plpgsql/src/nls.mk
index ec7c7035add..eb06336675c 100644
--- a/src/pl/plpgsql/src/nls.mk
+++ b/src/pl/plpgsql/src/nls.mk
@@ -6,5 +6,5 @@ GETTEXT_FILES = pl_comp.c \
pl_funcs.c \
pl_handler.c \
pl_scanner.c
-GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) yyerror:2 plpgsql_yyerror:2
+GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) yyerror:3 plpgsql_yyerror:3
GETTEXT_FLAGS = $(BACKEND_COMMON_GETTEXT_FLAGS)
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index e8f81d287a1..cb5c2dca186 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -28,10 +28,6 @@
#include "pl_gram.h"
-/* silence -Wmissing-variable-declarations */
-extern int plpgsql_yychar;
-extern int plpgsql_yynerrs;
-
/* Location tracking support --- simpler than bison's default */
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
@@ -63,7 +59,7 @@ static bool tok_is_keyword(int token, union YYSTYPE *lval,
int kw_token, const char *kw_str);
static void word_is_not_variable(PLword *word, int location);
static void cword_is_not_variable(PLcword *cword, int location);
-static void current_token_is_not_variable(int tok, yyscan_t yyscanner);
+static void current_token_is_not_variable(int tok, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
static PLpgSQL_expr *read_sql_construct(int until,
int until2,
int until3,
@@ -73,31 +69,33 @@ static PLpgSQL_expr *read_sql_construct(int until,
bool valid_sql,
int *startloc,
int *endtoken,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp,
yyscan_t yyscanner);
-static PLpgSQL_expr *read_sql_expression(int until,
- const char *expected, yyscan_t yyscanner);
+static PLpgSQL_expr *read_sql_expression(int until, const char *expected,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
static PLpgSQL_expr *read_sql_expression2(int until, int until2,
- const char *expected,
- int *endtoken, yyscan_t yyscanner);
-static PLpgSQL_expr *read_sql_stmt(yyscan_t yyscanner);
-static PLpgSQL_type *read_datatype(int tok, yyscan_t yyscanner);
+ const char *expected, int *endtoken,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
+static PLpgSQL_expr *read_sql_stmt(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
+static PLpgSQL_type *read_datatype(int tok, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
static PLpgSQL_stmt *make_execsql_stmt(int firsttoken, int location,
- PLword *word, yyscan_t yyscanner);
-static PLpgSQL_stmt_fetch *read_fetch_direction(yyscan_t yyscanner);
+ PLword *word, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
+static PLpgSQL_stmt_fetch *read_fetch_direction(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
static void complete_direction(PLpgSQL_stmt_fetch *fetch,
- bool *check_FROM, yyscan_t yyscanner);
-static PLpgSQL_stmt *make_return_stmt(int location, yyscan_t yyscanner);
-static PLpgSQL_stmt *make_return_next_stmt(int location, yyscan_t yyscanner);
-static PLpgSQL_stmt *make_return_query_stmt(int location, yyscan_t yyscanner);
+ bool *check_FROM, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
+static PLpgSQL_stmt *make_return_stmt(int location, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
+static PLpgSQL_stmt *make_return_next_stmt(int location, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
+static PLpgSQL_stmt *make_return_query_stmt(int location, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
static PLpgSQL_stmt *make_case(int location, PLpgSQL_expr *t_expr,
List *case_when_list, List *else_stmts);
static char *NameOfDatum(PLwdatum *wdatum);
static void check_assignable(PLpgSQL_datum *datum, int location);
-static void read_into_target(PLpgSQL_variable **target,
- bool *strict, yyscan_t yyscanner);
+static void read_into_target(PLpgSQL_variable **target, bool *strict,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
static PLpgSQL_row *read_into_scalar_list(char *initial_name,
PLpgSQL_datum *initial_datum,
int initial_location,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp,
yyscan_t yyscanner);
static PLpgSQL_row *make_scalar_list1(char *initial_name,
PLpgSQL_datum *initial_datum,
@@ -109,15 +107,16 @@ static PLpgSQL_type *parse_datatype(const char *string, int location);
static void check_labels(const char *start_label,
const char *end_label,
int end_location);
-static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor,
- int until, yyscan_t yyscanner);
-static List *read_raise_options(yyscan_t yyscanner);
+static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor, int until,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
+static List *read_raise_options(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
%}
%parse-param {yyscan_t yyscanner}
%lex-param {yyscan_t yyscanner}
+%pure-parser
%expect 0
%name-prefix="plpgsql_yy"
%locations
@@ -581,7 +580,7 @@ opt_scrollable :
decl_cursor_query :
{
- $$ = read_sql_stmt(yyscanner);
+ $$ = read_sql_stmt(&yylval, &yylloc, yyscanner);
}
;
@@ -710,7 +709,7 @@ decl_varname : T_WORD
if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
$1.ident, NULL, NULL,
NULL) != NULL)
- yyerror(yyscanner, "duplicate declaration");
+ yyerror(&yylloc, yyscanner, "duplicate declaration");
if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR ||
plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR)
@@ -738,7 +737,7 @@ decl_varname : T_WORD
if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
$1, NULL, NULL,
NULL) != NULL)
- yyerror(yyscanner, "duplicate declaration");
+ yyerror(&yylloc, yyscanner, "duplicate declaration");
if (plpgsql_curr_compile->extra_warnings & PLPGSQL_XCHECK_SHADOWVAR ||
plpgsql_curr_compile->extra_errors & PLPGSQL_XCHECK_SHADOWVAR)
@@ -770,7 +769,7 @@ decl_datatype :
* consume it, and then we must tell bison to forget
* it.
*/
- $$ = read_datatype(yychar, yyscanner);
+ $$ = read_datatype(yychar, &yylval, &yylloc, yyscanner);
yyclearin;
}
;
@@ -803,7 +802,7 @@ decl_defval : ';'
{ $$ = NULL; }
| decl_defkey
{
- $$ = read_sql_expression(';', ";", yyscanner);
+ $$ = read_sql_expression(';', ";", &yylval, &yylloc, yyscanner);
}
;
@@ -891,7 +890,7 @@ stmt_perform : K_PERFORM
new->cmd_type = PLPGSQL_STMT_PERFORM;
new->lineno = plpgsql_location_to_lineno(@1);
new->stmtid = ++plpgsql_curr_compile->nstatements;
- plpgsql_push_back_token(K_PERFORM);
+ plpgsql_push_back_token(K_PERFORM, &yylval, &yylloc);
/*
* Since PERFORM isn't legal SQL, we have to cheat to
@@ -905,7 +904,7 @@ stmt_perform : K_PERFORM
RAW_PARSE_DEFAULT,
false, false,
&startloc, NULL,
- yyscanner);
+ &yylval, &yylloc, yyscanner);
/* overwrite "perform" ... */
memcpy(new->expr->query, " SELECT", 7);
/* left-justify to get rid of the leading space */
@@ -927,8 +926,8 @@ stmt_call : K_CALL
new->cmd_type = PLPGSQL_STMT_CALL;
new->lineno = plpgsql_location_to_lineno(@1);
new->stmtid = ++plpgsql_curr_compile->nstatements;
- plpgsql_push_back_token(K_CALL);
- new->expr = read_sql_stmt(yyscanner);
+ plpgsql_push_back_token(K_CALL, &yylval, &yylloc);
+ new->expr = read_sql_stmt(&yylval, &yylloc, yyscanner);
new->is_call = true;
/* Remember we may need a procedure resource owner */
@@ -946,8 +945,8 @@ stmt_call : K_CALL
new->cmd_type = PLPGSQL_STMT_CALL;
new->lineno = plpgsql_location_to_lineno(@1);
new->stmtid = ++plpgsql_curr_compile->nstatements;
- plpgsql_push_back_token(K_DO);
- new->expr = read_sql_stmt(yyscanner);
+ plpgsql_push_back_token(K_DO, &yylval, &yylloc);
+ new->expr = read_sql_stmt(&yylval, &yylloc, yyscanner);
new->is_call = false;
/* Remember we may need a procedure resource owner */
@@ -987,12 +986,12 @@ stmt_assign : T_DATUM
new->stmtid = ++plpgsql_curr_compile->nstatements;
new->varno = $1.datum->dno;
/* Push back the head name to include it in the stmt */
- plpgsql_push_back_token(T_DATUM);
+ plpgsql_push_back_token(T_DATUM, &yylval, &yylloc);
new->expr = read_sql_construct(';', 0, 0, ";",
pmode,
false, true,
NULL, NULL,
- yyscanner);
+ &yylval, &yylloc, yyscanner);
$$ = (PLpgSQL_stmt *) new;
}
@@ -1099,7 +1098,7 @@ getdiag_list_item : getdiag_target assign_operator getdiag_item
getdiag_item :
{
- int tok = yylex(yyscanner);
+ int tok = yylex(&yylval, &yylloc, yyscanner);
if (tok_is_keyword(tok, &yylval,
K_ROW_COUNT, "row_count"))
@@ -1141,7 +1140,7 @@ getdiag_item :
K_RETURNED_SQLSTATE, "returned_sqlstate"))
$$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE;
else
- yyerror(yyscanner, "unrecognized GET DIAGNOSTICS item");
+ yyerror(&yylloc, yyscanner, "unrecognized GET DIAGNOSTICS item");
}
;
@@ -1228,14 +1227,14 @@ stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CAS
opt_expr_until_when :
{
PLpgSQL_expr *expr = NULL;
- int tok = yylex(yyscanner);
+ int tok = yylex(&yylval, &yylloc, yyscanner);
if (tok != K_WHEN)
{
- plpgsql_push_back_token(tok);
- expr = read_sql_expression(K_WHEN, "WHEN", yyscanner);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
+ expr = read_sql_expression(K_WHEN, "WHEN", &yylval, &yylloc, yyscanner);
}
- plpgsql_push_back_token(K_WHEN);
+ plpgsql_push_back_token(K_WHEN, &yylval, &yylloc);
$$ = expr;
}
;
@@ -1353,7 +1352,7 @@ stmt_for : opt_loop_label K_FOR for_control loop_body
for_control : for_variable K_IN
{
- int tok = yylex(yyscanner);
+ int tok = yylex(&yylval, &yylloc, yyscanner);
int tokloc = yylloc;
if (tok == K_EXECUTE)
@@ -1365,7 +1364,7 @@ for_control : for_variable K_IN
expr = read_sql_expression2(K_LOOP, K_USING,
"LOOP or USING",
- &term, yyscanner);
+ &term, &yylval, &yylloc, yyscanner);
new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
new->cmd_type = PLPGSQL_STMT_DYNFORS;
@@ -1398,7 +1397,7 @@ for_control : for_variable K_IN
{
expr = read_sql_expression2(',', K_LOOP,
", or LOOP",
- &term, yyscanner);
+ &term, &yylval, &yylloc, yyscanner);
new->params = lappend(new->params, expr);
} while (term == ',');
}
@@ -1433,7 +1432,7 @@ for_control : for_variable K_IN
parser_errposition(tokloc)));
/* collect cursor's parameters if any */
- new->argquery = read_cursor_args(cursor, K_LOOP, yyscanner);
+ new->argquery = read_cursor_args(cursor, K_LOOP, &yylval, &yylloc, yyscanner);
/* create loop's private RECORD variable */
new->var = (PLpgSQL_variable *)
@@ -1467,7 +1466,7 @@ for_control : for_variable K_IN
K_REVERSE, "reverse"))
reverse = true;
else
- plpgsql_push_back_token(tok);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
/*
* Read tokens until we see either a ".."
@@ -1485,7 +1484,7 @@ for_control : for_variable K_IN
false,
&expr1loc,
&tok,
- yyscanner);
+ &yylval, &yylloc, yyscanner);
if (tok == DOT_DOT)
{
@@ -1506,12 +1505,12 @@ for_control : for_variable K_IN
/* Read and check the second one */
expr2 = read_sql_expression2(K_LOOP, K_BY,
"LOOP",
- &tok, yyscanner);
+ &tok, &yylval, &yylloc, yyscanner);
/* Get the BY clause if any */
if (tok == K_BY)
expr_by = read_sql_expression(K_LOOP,
- "LOOP", yyscanner);
+ "LOOP", &yylval, &yylloc, yyscanner);
else
expr_by = NULL;
@@ -1626,13 +1625,14 @@ for_variable : T_DATUM
$$.scalar = $1.datum;
$$.row = NULL;
/* check for comma-separated list */
- tok = yylex(yyscanner);
- plpgsql_push_back_token(tok);
+ tok = yylex(&yylval, &yylloc, yyscanner);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
if (tok == ',')
$$.row = (PLpgSQL_datum *)
read_into_scalar_list($$.name,
$$.scalar,
@1,
+ &yylval, &yylloc,
yyscanner);
}
}
@@ -1645,8 +1645,8 @@ for_variable : T_DATUM
$$.scalar = NULL;
$$.row = NULL;
/* check for comma-separated list */
- tok = yylex(yyscanner);
- plpgsql_push_back_token(tok);
+ tok = yylex(&yylval, &yylloc, yyscanner);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
if (tok == ',')
word_is_not_variable(&($1), @1);
}
@@ -1772,24 +1772,24 @@ stmt_return : K_RETURN
{
int tok;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
if (tok == 0)
- yyerror(yyscanner, "unexpected end of function definition");
+ yyerror(&yylloc, yyscanner, "unexpected end of function definition");
if (tok_is_keyword(tok, &yylval,
K_NEXT, "next"))
{
- $$ = make_return_next_stmt(@1, yyscanner);
+ $$ = make_return_next_stmt(@1, &yylval, &yylloc, yyscanner);
}
else if (tok_is_keyword(tok, &yylval,
K_QUERY, "query"))
{
- $$ = make_return_query_stmt(@1, yyscanner);
+ $$ = make_return_query_stmt(@1, &yylval, &yylloc, yyscanner);
}
else
{
- plpgsql_push_back_token(tok);
- $$ = make_return_stmt(@1, yyscanner);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
+ $$ = make_return_stmt(@1, &yylval, &yylloc, yyscanner);
}
}
;
@@ -1810,9 +1810,9 @@ stmt_raise : K_RAISE
new->params = NIL;
new->options = NIL;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
if (tok == 0)
- yyerror(yyscanner, "unexpected end of function definition");
+ yyerror(&yylloc, yyscanner, "unexpected end of function definition");
/*
* We could have just RAISE, meaning to re-throw
@@ -1827,40 +1827,40 @@ stmt_raise : K_RAISE
K_EXCEPTION, "exception"))
{
new->elog_level = ERROR;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
else if (tok_is_keyword(tok, &yylval,
K_WARNING, "warning"))
{
new->elog_level = WARNING;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
else if (tok_is_keyword(tok, &yylval,
K_NOTICE, "notice"))
{
new->elog_level = NOTICE;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
else if (tok_is_keyword(tok, &yylval,
K_INFO, "info"))
{
new->elog_level = INFO;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
else if (tok_is_keyword(tok, &yylval,
K_LOG, "log"))
{
new->elog_level = LOG;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
else if (tok_is_keyword(tok, &yylval,
K_DEBUG, "debug"))
{
new->elog_level = DEBUG1;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
if (tok == 0)
- yyerror(yyscanner, "unexpected end of function definition");
+ yyerror(&yylloc, yyscanner, "unexpected end of function definition");
/*
* Next we can have a condition name, or
@@ -1878,9 +1878,9 @@ stmt_raise : K_RAISE
* begins the list of parameter expressions,
* or USING to begin the options list.
*/
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
if (tok != ',' && tok != ';' && tok != K_USING)
- yyerror(yyscanner, "syntax error");
+ yyerror(&yylloc, yyscanner, "syntax error");
while (tok == ',')
{
@@ -1891,7 +1891,7 @@ stmt_raise : K_RAISE
RAW_PARSE_PLPGSQL_EXPR,
true, true,
NULL, &tok,
- yyscanner);
+ &yylval, &yylloc, yyscanner);
new->params = lappend(new->params, expr);
}
}
@@ -1904,14 +1904,14 @@ stmt_raise : K_RAISE
/* next token should be a string literal */
char *sqlstatestr;
- if (yylex(yyscanner) != SCONST)
- yyerror(yyscanner, "syntax error");
+ if (yylex(&yylval, &yylloc, yyscanner) != SCONST)
+ yyerror(&yylloc, yyscanner, "syntax error");
sqlstatestr = yylval.str;
if (strlen(sqlstatestr) != 5)
- yyerror(yyscanner, "invalid SQLSTATE code");
+ yyerror(&yylloc, yyscanner, "invalid SQLSTATE code");
if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
- yyerror(yyscanner, "invalid SQLSTATE code");
+ yyerror(&yylloc, yyscanner, "invalid SQLSTATE code");
new->condname = sqlstatestr;
}
else
@@ -1921,17 +1921,17 @@ stmt_raise : K_RAISE
else if (plpgsql_token_is_unreserved_keyword(tok))
new->condname = pstrdup(yylval.keyword);
else
- yyerror(yyscanner, "syntax error");
+ yyerror(&yylloc, yyscanner, "syntax error");
plpgsql_recognize_err_condition(new->condname,
false);
}
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
if (tok != ';' && tok != K_USING)
- yyerror(yyscanner, "syntax error");
+ yyerror(&yylloc, yyscanner, "syntax error");
}
if (tok == K_USING)
- new->options = read_raise_options(yyscanner);
+ new->options = read_raise_options(&yylval, &yylloc, yyscanner);
}
check_raise_parameters(new);
@@ -1953,10 +1953,10 @@ stmt_assert : K_ASSERT
new->cond = read_sql_expression2(',', ';',
", or ;",
- &tok, yyscanner);
+ &tok, &yylval, &yylloc, yyscanner);
if (tok == ',')
- new->message = read_sql_expression(';', ";", yyscanner);
+ new->message = read_sql_expression(';', ";", &yylval, &yylloc, yyscanner);
else
new->message = NULL;
@@ -1984,37 +1984,37 @@ loop_body : proc_sect K_END K_LOOP opt_label ';'
*/
stmt_execsql : K_IMPORT
{
- $$ = make_execsql_stmt(K_IMPORT, @1, NULL, yyscanner);
+ $$ = make_execsql_stmt(K_IMPORT, @1, NULL, &yylval, &yylloc, yyscanner);
}
| K_INSERT
{
- $$ = make_execsql_stmt(K_INSERT, @1, NULL, yyscanner);
+ $$ = make_execsql_stmt(K_INSERT, @1, NULL, &yylval, &yylloc, yyscanner);
}
| K_MERGE
{
- $$ = make_execsql_stmt(K_MERGE, @1, NULL, yyscanner);
+ $$ = make_execsql_stmt(K_MERGE, @1, NULL, &yylval, &yylloc, yyscanner);
}
| T_WORD
{
int tok;
- tok = yylex(yyscanner);
- plpgsql_push_back_token(tok);
+ tok = yylex(&yylval, &yylloc, yyscanner);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
if (tok == '=' || tok == COLON_EQUALS ||
tok == '[' || tok == '.')
word_is_not_variable(&($1), @1);
- $$ = make_execsql_stmt(T_WORD, @1, &($1), yyscanner);
+ $$ = make_execsql_stmt(T_WORD, @1, &($1), &yylval, &yylloc, yyscanner);
}
| T_CWORD
{
int tok;
- tok = yylex(yyscanner);
- plpgsql_push_back_token(tok);
+ tok = yylex(&yylval, &yylloc, yyscanner);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
if (tok == '=' || tok == COLON_EQUALS ||
tok == '[' || tok == '.')
cword_is_not_variable(&($1), @1);
- $$ = make_execsql_stmt(T_CWORD, @1, NULL, yyscanner);
+ $$ = make_execsql_stmt(T_CWORD, @1, NULL, &yylval, &yylloc, yyscanner);
}
;
@@ -2029,7 +2029,7 @@ stmt_dynexecute : K_EXECUTE
RAW_PARSE_PLPGSQL_EXPR,
true, true,
NULL, &endtoken,
- yyscanner);
+ &yylval, &yylloc, yyscanner);
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
@@ -2053,15 +2053,15 @@ stmt_dynexecute : K_EXECUTE
if (endtoken == K_INTO)
{
if (new->into) /* multiple INTO */
- yyerror(yyscanner, "syntax error");
+ yyerror(&yylloc, yyscanner, "syntax error");
new->into = true;
- read_into_target(&new->target, &new->strict, yyscanner);
- endtoken = yylex(yyscanner);
+ read_into_target(&new->target, &new->strict, &yylval, &yylloc, yyscanner);
+ endtoken = yylex(&yylval, &yylloc, yyscanner);
}
else if (endtoken == K_USING)
{
if (new->params) /* multiple USING */
- yyerror(yyscanner, "syntax error");
+ yyerror(&yylloc, yyscanner, "syntax error");
do
{
expr = read_sql_construct(',', ';', K_INTO,
@@ -2069,14 +2069,14 @@ stmt_dynexecute : K_EXECUTE
RAW_PARSE_PLPGSQL_EXPR,
true, true,
NULL, &endtoken,
- yyscanner);
+ &yylval, &yylloc, yyscanner);
new->params = lappend(new->params, expr);
} while (endtoken == ',');
}
else if (endtoken == ';')
break;
else
- yyerror(yyscanner, "syntax error");
+ yyerror(&yylloc, yyscanner, "syntax error");
}
$$ = (PLpgSQL_stmt *) new;
@@ -2099,29 +2099,29 @@ stmt_open : K_OPEN cursor_variable
if ($2->cursor_explicit_expr == NULL)
{
/* be nice if we could use opt_scrollable here */
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
if (tok_is_keyword(tok, &yylval,
K_NO, "no"))
{
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
if (tok_is_keyword(tok, &yylval,
K_SCROLL, "scroll"))
{
new->cursor_options |= CURSOR_OPT_NO_SCROLL;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
}
else if (tok_is_keyword(tok, &yylval,
K_SCROLL, "scroll"))
{
new->cursor_options |= CURSOR_OPT_SCROLL;
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
}
if (tok != K_FOR)
- yyerror(yyscanner, "syntax error, expected \"FOR\"");
+ yyerror(&yylloc, yyscanner, "syntax error, expected \"FOR\"");
- tok = yylex(yyscanner);
+ tok = yylex(&yylval, &yylloc, yyscanner);
if (tok == K_EXECUTE)
{
int endtoken;
@@ -2129,7 +2129,7 @@ stmt_open : K_OPEN cursor_variable
new->dynquery =
read_sql_expression2(K_USING, ';',
"USING or ;",
- &endtoken, yyscanner);
+ &endtoken, &yylval, &yylloc, yyscanner);
/* If we found "USING", collect argument(s) */
if (endtoken == K_USING)
@@ -2140,7 +2140,7 @@ stmt_open : K_OPEN cursor_variable
{
expr = read_sql_expression2(',', ';',
", or ;",
- &endtoken, yyscanner);
+ &endtoken, &yylval, &yylloc, yyscanner);
new->params = lappend(new->params,
expr);
} while (endtoken == ',');
@@ -2148,14 +2148,14 @@ stmt_open : K_OPEN cursor_variable
}
else
{
- plpgsql_push_back_token(tok);
- new->query = read_sql_stmt(yyscanner);
+ plpgsql_push_back_token(tok, &yylval, &yylloc);
+ new->query = read_sql_stmt(&yylval, &yylloc, yyscanner);
}
}
else
{
/* predefined cursor query, so read args */
- new->argquery = read_cursor_args($2, ';', yyscanner);
+ new->argquery = read_cursor_args($2, ';', &yylval, &yylloc, yyscanner);
}
$$ = (PLpgSQL_stmt *) new;
@@ -2168,10 +2168,10 @@ stmt_fetch : K_FETCH opt_fetch_direction cursor_variable K_INTO
PLpgSQL_variable *target;
/* We have already parsed everything through the INTO keyword */
- read_into_target(&target, NULL, yyscanner);
+ read_into_target(&target, NULL, &yylval, &yylloc, yyscanner);
- if (yylex(yyscanner) != ';')
- yyerror(yyscanner, "syntax error");
+ if (yylex(&yylval, &yylloc, yyscanner) != ';')
+ yyerror(&yylloc, yyscanner, "syntax error");
/*
* We don't allow multiple rows in PL/pgSQL's FETCH
@@ -2206,7 +2206,7 @@ stmt_move : K_MOVE opt_fetch_direction cursor_variable ';'
opt_fetch_direction :
{
- $$ = read_fetch_direction(yyscanner);
+ $$ = read_fetch_direction(&yylval, &yylloc, yyscanner);
}
;
@@ -2394,14 +2394,14 @@ proc_condition : any_identifier
char *sqlstatestr;
/* next token should be a string literal */
- if (yylex(yyscanner) != SCONST)
- yyerror(yyscanner, "syntax error");
+ if (yylex(&yylval, &yylloc, yyscanner) != SCONST)
+ yyerror(&yylloc, yyscanner, "syntax error");
sqlstatestr = yylval.str;
if (strlen(sqlstatestr) != 5)
- yyerror(yyscanner, "invalid SQLSTATE code");
+ yyerror(&yylloc, yyscanner, "invalid SQLSTATE code");
if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
- yyerror(yyscanner, "invalid SQLSTATE code");
+ yyerror(&yylloc, yyscanner, "invalid SQLSTATE code");
new = palloc(sizeof(PLpgSQL_condition));
new->sqlerrstate =
@@ -2419,15 +2419,15 @@ proc_condition : any_identifier
;
expr_until_semi :
- { $$ = read_sql_expression(';', ";", yyscanner); }
+ { $$ = read_sql_expression(';', ";", &yylval, &yylloc, yyscanner); }
;
expr_until_then :
- { $$ = read_sql_expression(K_THEN, "THEN", yyscanner); }
+ { $$ = read_sql_expression(K_THEN, "THEN", &yylval, &yylloc, yyscanner); }
;
expr_until_loop :
- { $$ = read_sql_expression(K_LOOP, "LOOP", yyscanner); }
+ { $$ = read_sql_expression(K_LOOP, "LOOP", &yylval, &yylloc, yyscanner); }
;
opt_block_label :
@@ -2485,7 +2485,7 @@ any_identifier : T_WORD
| T_DATUM
{
if ($1.ident == NULL) /* composite name not OK */
- yyerror(yyscanner, "syntax error");
+ yyerror(&yylloc, yyscanner, "syntax error");
$$ = $1.ident;
}
;
@@ -2637,45 +2637,45 @@ cword_is_not_variable(PLcword *cword, int location)
* look at yylval and yylloc.
*/
static void
-current_token_is_not_variable(int tok, yyscan_t yyscanner)
+current_token_is_not_variable(int tok, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
if (tok == T_WORD)
- word_is_not_variable(&(yylval.word), yylloc);
+ word_is_not_variable(&(yylvalp->word), *yyllocp);
else if (tok == T_CWORD)
- cword_is_not_variable(&(yylval.cword), yylloc);
+ cword_is_not_variable(&(yylvalp->cword), *yyllocp);
else
- yyerror(yyscanner, "syntax error");
+ yyerror(yyllocp, yyscanner, "syntax error");
}
/* Convenience routine to read an expression with one possible terminator */
static PLpgSQL_expr *
-read_sql_expression(int until, const char *expected, yyscan_t yyscanner)
+read_sql_expression(int until, const char *expected, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
return read_sql_construct(until, 0, 0, expected,
RAW_PARSE_PLPGSQL_EXPR,
true, true, NULL, NULL,
- yyscanner);
+ yylvalp, yyllocp, yyscanner);
}
/* Convenience routine to read an expression with two possible terminators */
static PLpgSQL_expr *
read_sql_expression2(int until, int until2, const char *expected,
- int *endtoken, yyscan_t yyscanner)
+ int *endtoken, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
return read_sql_construct(until, until2, 0, expected,
RAW_PARSE_PLPGSQL_EXPR,
true, true, NULL, endtoken,
- yyscanner);
+ yylvalp, yyllocp, yyscanner);
}
/* Convenience routine to read a SQL statement that must end with ';' */
static PLpgSQL_expr *
-read_sql_stmt(yyscan_t yyscanner)
+read_sql_stmt(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
return read_sql_construct(';', 0, 0, ";",
RAW_PARSE_DEFAULT,
false, true, NULL, NULL,
- yyscanner);
+ yylvalp, yyllocp, yyscanner);
}
/*
@@ -2702,6 +2702,7 @@ read_sql_construct(int until,
bool valid_sql,
int *startloc,
int *endtoken,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp,
yyscan_t yyscanner)
{
int tok;
@@ -2720,9 +2721,9 @@ read_sql_construct(int until,
for (;;)
{
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (startlocation < 0) /* remember loc of first token */
- startlocation = yylloc;
+ startlocation = *yyllocp;
if (tok == until && parenlevel == 0)
break;
if (tok == until2 && parenlevel == 0)
@@ -2735,7 +2736,7 @@ read_sql_construct(int until,
{
parenlevel--;
if (parenlevel < 0)
- yyerror(yyscanner, "mismatched parentheses");
+ yyerror(yyllocp, yyscanner, "mismatched parentheses");
}
/*
@@ -2746,22 +2747,22 @@ read_sql_construct(int until,
if (tok == 0 || tok == ';')
{
if (parenlevel != 0)
- yyerror(yyscanner, "mismatched parentheses");
+ yyerror(yyllocp, yyscanner, "mismatched parentheses");
if (isexpression)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing \"%s\" at end of SQL expression",
expected),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing \"%s\" at end of SQL statement",
expected),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
}
/* Remember end+1 location of last accepted token */
- endlocation = yylloc + plpgsql_token_length();
+ endlocation = *yyllocp + plpgsql_token_length();
}
plpgsql_IdentifierLookup = save_IdentifierLookup;
@@ -2775,9 +2776,9 @@ read_sql_construct(int until,
if (startlocation >= endlocation)
{
if (isexpression)
- yyerror(yyscanner, "missing expression");
+ yyerror(yyllocp, yyscanner, "missing expression");
else
- yyerror(yyscanner, "missing SQL statement");
+ yyerror(yyllocp, yyscanner, "missing SQL statement");
}
/*
@@ -2809,7 +2810,7 @@ read_sql_construct(int until,
* Returns a PLpgSQL_type struct.
*/
static PLpgSQL_type *
-read_datatype(int tok, yyscan_t yyscanner)
+read_datatype(int tok, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
StringInfoData ds;
char *type_name;
@@ -2822,10 +2823,10 @@ read_datatype(int tok, yyscan_t yyscanner)
/* Often there will be a lookahead token, but if not, get one */
if (tok == YYEMPTY)
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
/* The current token is the start of what we'll pass to parse_datatype */
- startlocation = yylloc;
+ startlocation = *yyllocp;
/*
* If we have a simple or composite identifier, check for %TYPE and
@@ -2833,48 +2834,48 @@ read_datatype(int tok, yyscan_t yyscanner)
*/
if (tok == T_WORD)
{
- char *dtname = yylval.word.ident;
+ char *dtname = yylvalp->word.ident;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == '%')
{
- tok = yylex(yyscanner);
- if (tok_is_keyword(tok, &yylval,
+ tok = yylex(yylvalp, yyllocp, yyscanner);
+ if (tok_is_keyword(tok, yylvalp,
K_TYPE, "type"))
result = plpgsql_parse_wordtype(dtname);
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_ROWTYPE, "rowtype"))
result = plpgsql_parse_wordrowtype(dtname);
}
}
else if (plpgsql_token_is_unreserved_keyword(tok))
{
- char *dtname = pstrdup(yylval.keyword);
+ char *dtname = pstrdup(yylvalp->keyword);
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == '%')
{
- tok = yylex(yyscanner);
- if (tok_is_keyword(tok, &yylval,
+ tok = yylex(yylvalp, yyllocp, yyscanner);
+ if (tok_is_keyword(tok, yylvalp,
K_TYPE, "type"))
result = plpgsql_parse_wordtype(dtname);
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_ROWTYPE, "rowtype"))
result = plpgsql_parse_wordrowtype(dtname);
}
}
else if (tok == T_CWORD)
{
- List *dtnames = yylval.cword.idents;
+ List *dtnames = yylvalp->cword.idents;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == '%')
{
- tok = yylex(yyscanner);
- if (tok_is_keyword(tok, &yylval,
+ tok = yylex(yylvalp, yyllocp, yyscanner);
+ if (tok_is_keyword(tok, yylvalp,
K_TYPE, "type"))
result = plpgsql_parse_cwordtype(dtnames);
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_ROWTYPE, "rowtype"))
result = plpgsql_parse_cwordrowtype(dtnames);
}
@@ -2892,24 +2893,24 @@ read_datatype(int tok, yyscan_t yyscanner)
{
bool is_array = false;
- tok = yylex(yyscanner);
- if (tok_is_keyword(tok, &yylval,
+ tok = yylex(yylvalp, yyllocp, yyscanner);
+ if (tok_is_keyword(tok, yylvalp,
K_ARRAY, "array"))
{
is_array = true;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
}
while (tok == '[')
{
is_array = true;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == ICONST)
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok != ']')
- yyerror(yyscanner, "syntax error, expected \"]\"");
- tok = yylex(yyscanner);
+ yyerror(yyllocp, yyscanner, "syntax error, expected \"]\"");
+ tok = yylex(yylvalp, yyllocp, yyscanner);
}
- plpgsql_push_back_token(tok);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
if (is_array)
result = plpgsql_build_datatype_arrayof(result);
@@ -2928,9 +2929,9 @@ read_datatype(int tok, yyscan_t yyscanner)
if (tok == 0)
{
if (parenlevel != 0)
- yyerror(yyscanner, "mismatched parentheses");
+ yyerror(yyllocp, yyscanner, "mismatched parentheses");
else
- yyerror(yyscanner, "incomplete data type declaration");
+ yyerror(yyllocp, yyscanner, "incomplete data type declaration");
}
/* Possible followers for datatype in a declaration */
if (tok == K_COLLATE || tok == K_NOT ||
@@ -2944,22 +2945,22 @@ read_datatype(int tok, yyscan_t yyscanner)
else if (tok == ')')
parenlevel--;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
}
/* set up ds to contain complete typename text */
initStringInfo(&ds);
- plpgsql_append_source_text(&ds, startlocation, yylloc);
+ plpgsql_append_source_text(&ds, startlocation, *yyllocp);
type_name = ds.data;
if (type_name[0] == '\0')
- yyerror(yyscanner, "missing data type declaration");
+ yyerror(yyllocp, yyscanner, "missing data type declaration");
result = parse_datatype(type_name, startlocation);
pfree(ds.data);
- plpgsql_push_back_token(tok);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
return result;
}
@@ -2970,7 +2971,7 @@ read_datatype(int tok, yyscan_t yyscanner)
* If firsttoken == T_WORD, pass its yylval value as "word", else pass NULL.
*/
static PLpgSQL_stmt *
-make_execsql_stmt(int firsttoken, int location, PLword *word, yyscan_t yyscanner)
+make_execsql_stmt(int firsttoken, int location, PLword *word, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
StringInfoData ds;
IdentifierLookup save_IdentifierLookup;
@@ -3039,22 +3040,22 @@ make_execsql_stmt(int firsttoken, int location, PLword *word, yyscan_t yyscanner
for (;;)
{
prev_tok = tok;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (have_into && into_end_loc < 0)
- into_end_loc = yylloc; /* token after the INTO part */
+ into_end_loc = *yyllocp; /* token after the INTO part */
/* Detect CREATE [OR REPLACE] {FUNCTION|PROCEDURE} */
if (tokens[0] == 'c' && token_count < sizeof(tokens))
{
if (tok == K_OR)
tokens[token_count] = 'o';
else if (tok == T_WORD &&
- strcmp(yylval.word.ident, "replace") == 0)
+ strcmp(yylvalp->word.ident, "replace") == 0)
tokens[token_count] = 'r';
else if (tok == T_WORD &&
- strcmp(yylval.word.ident, "function") == 0)
+ strcmp(yylvalp->word.ident, "function") == 0)
tokens[token_count] = 'f';
else if (tok == T_WORD &&
- strcmp(yylval.word.ident, "procedure") == 0)
+ strcmp(yylvalp->word.ident, "procedure") == 0)
tokens[token_count] = 'f'; /* treat same as "function" */
if (tokens[1] == 'f' ||
(tokens[1] == 'o' && tokens[2] == 'r' && tokens[3] == 'f'))
@@ -3078,7 +3079,7 @@ make_execsql_stmt(int firsttoken, int location, PLword *word, yyscan_t yyscanner
if (tok == ';' && paren_depth == 0 && begin_depth == 0)
break;
if (tok == 0)
- yyerror(yyscanner, "unexpected end of function definition");
+ yyerror(yyllocp, yyscanner, "unexpected end of function definition");
if (tok == K_INTO)
{
if (prev_tok == K_INSERT)
@@ -3088,11 +3089,11 @@ make_execsql_stmt(int firsttoken, int location, PLword *word, yyscan_t yyscanner
if (firsttoken == K_IMPORT)
continue; /* IMPORT ... INTO is not an INTO-target */
if (have_into)
- yyerror(yyscanner, "INTO specified more than once");
+ yyerror(yyllocp, yyscanner, "INTO specified more than once");
have_into = true;
- into_start_loc = yylloc;
+ into_start_loc = *yyllocp;
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
- read_into_target(&target, &have_strict, yyscanner);
+ read_into_target(&target, &have_strict, yylvalp, yyllocp, yyscanner);
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
}
}
@@ -3108,10 +3109,10 @@ make_execsql_stmt(int firsttoken, int location, PLword *word, yyscan_t yyscanner
*/
plpgsql_append_source_text(&ds, location, into_start_loc);
appendStringInfoSpaces(&ds, into_end_loc - into_start_loc);
- plpgsql_append_source_text(&ds, into_end_loc, yylloc);
+ plpgsql_append_source_text(&ds, into_end_loc, *yyllocp);
}
else
- plpgsql_append_source_text(&ds, location, yylloc);
+ plpgsql_append_source_text(&ds, location, *yyllocp);
/* trim any trailing whitespace, for neatness */
while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
@@ -3145,7 +3146,7 @@ make_execsql_stmt(int firsttoken, int location, PLword *word, yyscan_t yyscanner
* Read FETCH or MOVE direction clause (everything through FROM/IN).
*/
static PLpgSQL_stmt_fetch *
-read_fetch_direction(yyscan_t yyscanner)
+read_fetch_direction(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
PLpgSQL_stmt_fetch *fetch;
int tok;
@@ -3164,65 +3165,65 @@ read_fetch_direction(yyscan_t yyscanner)
fetch->expr = NULL;
fetch->returns_multiple_rows = false;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == 0)
- yyerror(yyscanner, "unexpected end of function definition");
+ yyerror(yyllocp, yyscanner, "unexpected end of function definition");
- if (tok_is_keyword(tok, &yylval,
+ if (tok_is_keyword(tok, yylvalp,
K_NEXT, "next"))
{
/* use defaults */
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_PRIOR, "prior"))
{
fetch->direction = FETCH_BACKWARD;
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_FIRST, "first"))
{
fetch->direction = FETCH_ABSOLUTE;
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_LAST, "last"))
{
fetch->direction = FETCH_ABSOLUTE;
fetch->how_many = -1;
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_ABSOLUTE, "absolute"))
{
fetch->direction = FETCH_ABSOLUTE;
fetch->expr = read_sql_expression2(K_FROM, K_IN,
"FROM or IN",
- NULL, yyscanner);
+ NULL, yylvalp, yyllocp, yyscanner);
check_FROM = false;
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_RELATIVE, "relative"))
{
fetch->direction = FETCH_RELATIVE;
fetch->expr = read_sql_expression2(K_FROM, K_IN,
"FROM or IN",
- NULL, yyscanner);
+ NULL, yylvalp, yyllocp, yyscanner);
check_FROM = false;
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_ALL, "all"))
{
fetch->how_many = FETCH_ALL;
fetch->returns_multiple_rows = true;
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_FORWARD, "forward"))
{
- complete_direction(fetch, &check_FROM, yyscanner);
+ complete_direction(fetch, &check_FROM, yylvalp, yyllocp, yyscanner);
}
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_BACKWARD, "backward"))
{
fetch->direction = FETCH_BACKWARD;
- complete_direction(fetch, &check_FROM, yyscanner);
+ complete_direction(fetch, &check_FROM, yylvalp, yyllocp, yyscanner);
}
else if (tok == K_FROM || tok == K_IN)
{
@@ -3232,7 +3233,7 @@ read_fetch_direction(yyscan_t yyscanner)
else if (tok == T_DATUM)
{
/* Assume there's no direction clause and tok is a cursor name */
- plpgsql_push_back_token(tok);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
check_FROM = false;
}
else
@@ -3245,10 +3246,10 @@ read_fetch_direction(yyscan_t yyscanner)
* will trigger. Perhaps this can be improved someday, but it hardly
* seems worth a lot of work.
*/
- plpgsql_push_back_token(tok);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
fetch->expr = read_sql_expression2(K_FROM, K_IN,
"FROM or IN",
- NULL, yyscanner);
+ NULL, yylvalp, yyllocp, yyscanner);
fetch->returns_multiple_rows = true;
check_FROM = false;
}
@@ -3256,9 +3257,9 @@ read_fetch_direction(yyscan_t yyscanner)
/* check FROM or IN keyword after direction's specification */
if (check_FROM)
{
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok != K_FROM && tok != K_IN)
- yyerror(yyscanner, "expected FROM or IN");
+ yyerror(yyllocp, yyscanner, "expected FROM or IN");
}
return fetch;
@@ -3271,13 +3272,13 @@ read_fetch_direction(yyscan_t yyscanner)
* BACKWARD expr, BACKWARD ALL, BACKWARD
*/
static void
-complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM, yyscan_t yyscanner)
+complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
int tok;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == 0)
- yyerror(yyscanner, "unexpected end of function definition");
+ yyerror(yyllocp, yyscanner, "unexpected end of function definition");
if (tok == K_FROM || tok == K_IN)
{
@@ -3293,17 +3294,17 @@ complete_direction(PLpgSQL_stmt_fetch *fetch, bool *check_FROM, yyscan_t yyscann
return;
}
- plpgsql_push_back_token(tok);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
fetch->expr = read_sql_expression2(K_FROM, K_IN,
"FROM or IN",
- NULL, yyscanner);
+ NULL, yylvalp, yyllocp, yyscanner);
fetch->returns_multiple_rows = true;
*check_FROM = false;
}
static PLpgSQL_stmt *
-make_return_stmt(int location, yyscan_t yyscanner)
+make_return_stmt(int location, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
PLpgSQL_stmt_return *new;
@@ -3316,36 +3317,36 @@ make_return_stmt(int location, yyscan_t yyscanner)
if (plpgsql_curr_compile->fn_retset)
{
- if (yylex(yyscanner) != ';')
+ if (yylex(yylvalp, yyllocp, yyscanner) != ';')
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function returning set"),
errhint("Use RETURN NEXT or RETURN QUERY."),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
}
else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
{
- if (yylex(yyscanner) != ';')
+ if (yylex(yylvalp, yyllocp, yyscanner) != ';')
{
if (plpgsql_curr_compile->fn_prokind == PROKIND_PROCEDURE)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("RETURN cannot have a parameter in a procedure"),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
else
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function returning void"),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
}
}
else if (plpgsql_curr_compile->out_param_varno >= 0)
{
- if (yylex(yyscanner) != ';')
+ if (yylex(yylvalp, yyllocp, yyscanner) != ';')
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function with OUT parameters"),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
new->retvarno = plpgsql_curr_compile->out_param_varno;
}
else
@@ -3354,17 +3355,17 @@ make_return_stmt(int location, yyscan_t yyscanner)
* We want to special-case simple variable references for efficiency.
* So peek ahead to see if that's what we have.
*/
- int tok = yylex(yyscanner);
+ int tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == T_DATUM && plpgsql_peek(yyscanner) == ';' &&
- (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
+ (yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
{
- new->retvarno = yylval.wdatum.datum->dno;
+ new->retvarno = yylvalp->wdatum.datum->dno;
/* eat the semicolon token that we only peeked at above */
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
Assert(tok == ';');
}
else
@@ -3375,8 +3376,8 @@ make_return_stmt(int location, yyscan_t yyscanner)
* Note that a well-formed expression is _required_ here; anything
* else is a compile-time error.
*/
- plpgsql_push_back_token(tok);
- new->expr = read_sql_expression(';', ";", yyscanner);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
+ new->expr = read_sql_expression(';', ";", yylvalp, yyllocp, yyscanner);
}
}
@@ -3385,7 +3386,7 @@ make_return_stmt(int location, yyscan_t yyscanner)
static PLpgSQL_stmt *
-make_return_next_stmt(int location, yyscan_t yyscanner)
+make_return_next_stmt(int location, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
PLpgSQL_stmt_return_next *new;
@@ -3404,11 +3405,11 @@ make_return_next_stmt(int location, yyscan_t yyscanner)
if (plpgsql_curr_compile->out_param_varno >= 0)
{
- if (yylex(yyscanner) != ';')
+ if (yylex(yylvalp, yyllocp, yyscanner) != ';')
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
new->retvarno = plpgsql_curr_compile->out_param_varno;
}
else
@@ -3417,17 +3418,17 @@ make_return_next_stmt(int location, yyscan_t yyscanner)
* We want to special-case simple variable references for efficiency.
* So peek ahead to see if that's what we have.
*/
- int tok = yylex(yyscanner);
+ int tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok == T_DATUM && plpgsql_peek(yyscanner) == ';' &&
- (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
+ (yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
{
- new->retvarno = yylval.wdatum.datum->dno;
+ new->retvarno = yylvalp->wdatum.datum->dno;
/* eat the semicolon token that we only peeked at above */
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
Assert(tok == ';');
}
else
@@ -3438,8 +3439,8 @@ make_return_next_stmt(int location, yyscan_t yyscanner)
* Note that a well-formed expression is _required_ here; anything
* else is a compile-time error.
*/
- plpgsql_push_back_token(tok);
- new->expr = read_sql_expression(';', ";", yyscanner);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
+ new->expr = read_sql_expression(';', ";", yylvalp, yyllocp, yyscanner);
}
}
@@ -3448,7 +3449,7 @@ make_return_next_stmt(int location, yyscan_t yyscanner)
static PLpgSQL_stmt *
-make_return_query_stmt(int location, yyscan_t yyscanner)
+make_return_query_stmt(int location, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
PLpgSQL_stmt_return_query *new;
int tok;
@@ -3465,11 +3466,11 @@ make_return_query_stmt(int location, yyscan_t yyscanner)
new->stmtid = ++plpgsql_curr_compile->nstatements;
/* check for RETURN QUERY EXECUTE */
- if ((tok = yylex(yyscanner)) != K_EXECUTE)
+ if ((tok = yylex(yylvalp, yyllocp, yyscanner)) != K_EXECUTE)
{
/* ordinary static query */
- plpgsql_push_back_token(tok);
- new->query = read_sql_stmt(yyscanner);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
+ new->query = read_sql_stmt(yylvalp, yyllocp, yyscanner);
}
else
{
@@ -3477,14 +3478,14 @@ make_return_query_stmt(int location, yyscan_t yyscanner)
int term;
new->dynquery = read_sql_expression2(';', K_USING, "; or USING",
- &term, yyscanner);
+ &term, yylvalp, yyllocp, yyscanner);
if (term == K_USING)
{
do
{
PLpgSQL_expr *expr;
- expr = read_sql_expression2(',', ';', ", or ;", &term, yyscanner);
+ expr = read_sql_expression2(',', ';', ", or ;", &term, yylvalp, yyllocp, yyscanner);
new->params = lappend(new->params, expr);
} while (term == ',');
}
@@ -3538,7 +3539,7 @@ check_assignable(PLpgSQL_datum *datum, int location)
* INTO keyword.
*/
static void
-read_into_target(PLpgSQL_variable **target, bool *strict, yyscan_t yyscanner)
+read_into_target(PLpgSQL_variable **target, bool *strict, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
int tok;
@@ -3547,11 +3548,11 @@ read_into_target(PLpgSQL_variable **target, bool *strict, yyscan_t yyscanner)
if (strict)
*strict = false;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (strict && tok == K_STRICT)
{
*strict = true;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
}
/*
@@ -3564,30 +3565,30 @@ read_into_target(PLpgSQL_variable **target, bool *strict, yyscan_t yyscanner)
switch (tok)
{
case T_DATUM:
- if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
+ if (yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
{
- check_assignable(yylval.wdatum.datum, yylloc);
- *target = (PLpgSQL_variable *) yylval.wdatum.datum;
+ check_assignable(yylvalp->wdatum.datum, *yyllocp);
+ *target = (PLpgSQL_variable *) yylvalp->wdatum.datum;
- if ((tok = yylex(yyscanner)) == ',')
+ if ((tok = yylex(yylvalp, yyllocp, yyscanner)) == ',')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("record variable cannot be part of multiple-item INTO list"),
- parser_errposition(yylloc)));
- plpgsql_push_back_token(tok);
+ parser_errposition(*yyllocp)));
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
}
else
{
*target = (PLpgSQL_variable *)
- read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
- yylval.wdatum.datum, yylloc, yyscanner);
+ read_into_scalar_list(NameOfDatum(&(yylvalp->wdatum)),
+ yylvalp->wdatum.datum, *yyllocp, yylvalp, yyllocp, yyscanner);
}
break;
default:
/* just to give a better message than "syntax error" */
- current_token_is_not_variable(tok, yyscanner);
+ current_token_is_not_variable(tok, yylvalp, yyllocp, yyscanner);
}
}
@@ -3601,6 +3602,7 @@ static PLpgSQL_row *
read_into_scalar_list(char *initial_name,
PLpgSQL_datum *initial_datum,
int initial_location,
+ YYSTYPE *yylvalp, YYLTYPE *yyllocp,
yyscan_t yyscanner)
{
int nfields;
@@ -3614,34 +3616,34 @@ read_into_scalar_list(char *initial_name,
varnos[0] = initial_datum->dno;
nfields = 1;
- while ((tok = yylex(yyscanner)) == ',')
+ while ((tok = yylex(yylvalp, yyllocp, yyscanner)) == ',')
{
/* Check for array overflow */
if (nfields >= 1024)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many INTO variables specified"),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
switch (tok)
{
case T_DATUM:
- check_assignable(yylval.wdatum.datum, yylloc);
- if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
- yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
+ check_assignable(yylvalp->wdatum.datum, *yyllocp);
+ if (yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ yylvalp->wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("\"%s\" is not a scalar variable",
- NameOfDatum(&(yylval.wdatum))),
- parser_errposition(yylloc)));
- fieldnames[nfields] = NameOfDatum(&(yylval.wdatum));
- varnos[nfields++] = yylval.wdatum.datum->dno;
+ NameOfDatum(&(yylvalp->wdatum))),
+ parser_errposition(*yyllocp)));
+ fieldnames[nfields] = NameOfDatum(&(yylvalp->wdatum));
+ varnos[nfields++] = yylvalp->wdatum.datum->dno;
break;
default:
/* just to give a better message than "syntax error" */
- current_token_is_not_variable(tok, yyscanner);
+ current_token_is_not_variable(tok, yylvalp, yyllocp, yyscanner);
}
}
@@ -3649,7 +3651,7 @@ read_into_scalar_list(char *initial_name,
* We read an extra, non-comma token from yylex(), so push it back onto
* the input stream
*/
- plpgsql_push_back_token(tok);
+ plpgsql_push_back_token(tok, yylvalp, yyllocp);
row = palloc0(sizeof(PLpgSQL_row));
row->dtype = PLPGSQL_DTYPE_ROW;
@@ -3852,7 +3854,7 @@ check_labels(const char *start_label, const char *end_label, int end_location)
* parens).
*/
static PLpgSQL_expr *
-read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
+read_cursor_args(PLpgSQL_var *cursor, int until, YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
PLpgSQL_expr *expr;
PLpgSQL_row *row;
@@ -3862,7 +3864,7 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
StringInfoData ds;
bool any_named = false;
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (cursor->cursor_explicit_argrow < 0)
{
/* No arguments expected */
@@ -3871,10 +3873,10 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor \"%s\" has no arguments",
cursor->refname),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
if (tok != until)
- yyerror(yyscanner, "syntax error");
+ yyerror(yyllocp, yyscanner, "syntax error");
return NULL;
}
@@ -3885,7 +3887,7 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor \"%s\" has arguments",
cursor->refname),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
/*
* Read the arguments, one by one.
@@ -3912,8 +3914,8 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
/* Read the argument name, ignoring any matching variable */
save_IdentifierLookup = plpgsql_IdentifierLookup;
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
- yylex(yyscanner);
- argname = yylval.str;
+ yylex(yylvalp, yyllocp, yyscanner);
+ argname = yylvalp->str;
plpgsql_IdentifierLookup = save_IdentifierLookup;
/* Match argument name to cursor arguments */
@@ -3927,15 +3929,15 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor \"%s\" has no argument named \"%s\"",
cursor->refname, argname),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
/*
* Eat the ":=". We already peeked, so the error should never
* happen.
*/
- tok2 = yylex(yyscanner);
+ tok2 = yylex(yylvalp, yyllocp, yyscanner);
if (tok2 != COLON_EQUALS)
- yyerror(yyscanner, "syntax error");
+ yyerror(yyllocp, yyscanner, "syntax error");
any_named = true;
}
@@ -3960,7 +3962,7 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
RAW_PARSE_PLPGSQL_EXPR,
true, true,
NULL, &endtoken,
- yyscanner);
+ yylvalp, yyllocp, yyscanner);
argv[argpos] = item->query;
@@ -3969,14 +3971,14 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("not enough arguments for cursor \"%s\"",
cursor->refname),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
if (endtoken == ',' && (argc == row->nfields - 1))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("too many arguments for cursor \"%s\"",
cursor->refname),
- parser_errposition(yylloc)));
+ parser_errposition(*yyllocp)));
}
/* Make positional argument list */
@@ -4007,9 +4009,9 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
pfree(ds.data);
/* Next we'd better find the until token */
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok != until)
- yyerror(yyscanner, "syntax error");
+ yyerror(yyllocp, yyscanner, "syntax error");
return expr;
}
@@ -4018,7 +4020,7 @@ read_cursor_args(PLpgSQL_var *cursor, int until, yyscan_t yyscanner)
* Parse RAISE ... USING options
*/
static List *
-read_raise_options(yyscan_t yyscanner)
+read_raise_options(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
List *result = NIL;
@@ -4027,46 +4029,46 @@ read_raise_options(yyscan_t yyscanner)
PLpgSQL_raise_option *opt;
int tok;
- if ((tok = yylex(yyscanner)) == 0)
- yyerror(yyscanner, "unexpected end of function definition");
+ if ((tok = yylex(yylvalp, yyllocp, yyscanner)) == 0)
+ yyerror(yyllocp, yyscanner, "unexpected end of function definition");
opt = (PLpgSQL_raise_option *) palloc(sizeof(PLpgSQL_raise_option));
- if (tok_is_keyword(tok, &yylval,
+ if (tok_is_keyword(tok, yylvalp,
K_ERRCODE, "errcode"))
opt->opt_type = PLPGSQL_RAISEOPTION_ERRCODE;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_MESSAGE, "message"))
opt->opt_type = PLPGSQL_RAISEOPTION_MESSAGE;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_DETAIL, "detail"))
opt->opt_type = PLPGSQL_RAISEOPTION_DETAIL;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_HINT, "hint"))
opt->opt_type = PLPGSQL_RAISEOPTION_HINT;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_COLUMN, "column"))
opt->opt_type = PLPGSQL_RAISEOPTION_COLUMN;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_CONSTRAINT, "constraint"))
opt->opt_type = PLPGSQL_RAISEOPTION_CONSTRAINT;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_DATATYPE, "datatype"))
opt->opt_type = PLPGSQL_RAISEOPTION_DATATYPE;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_TABLE, "table"))
opt->opt_type = PLPGSQL_RAISEOPTION_TABLE;
- else if (tok_is_keyword(tok, &yylval,
+ else if (tok_is_keyword(tok, yylvalp,
K_SCHEMA, "schema"))
opt->opt_type = PLPGSQL_RAISEOPTION_SCHEMA;
else
- yyerror(yyscanner, "unrecognized RAISE statement option");
+ yyerror(yyllocp, yyscanner, "unrecognized RAISE statement option");
- tok = yylex(yyscanner);
+ tok = yylex(yylvalp, yyllocp, yyscanner);
if (tok != '=' && tok != COLON_EQUALS)
- yyerror(yyscanner, "syntax error, expected \"=\"");
+ yyerror(yyllocp, yyscanner, "syntax error, expected \"=\"");
- opt->expr = read_sql_expression2(',', ';', ", or ;", &tok, yyscanner);
+ opt->expr = read_sql_expression2(',', ';', ", or ;", &tok, yylvalp, yyllocp, yyscanner);
result = lappend(result, opt);
diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c
index eeb40c301db..abf2d40c07a 100644
--- a/src/pl/plpgsql/src/pl_scanner.c
+++ b/src/pl/plpgsql/src/pl_scanner.c
@@ -142,7 +142,7 @@ static void location_lineno_init(void);
* matches one of those.
*/
int
-plpgsql_yylex(yyscan_t yyscanner)
+plpgsql_yylex(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner)
{
int tok1;
TokenAuxData aux1;
@@ -296,8 +296,8 @@ plpgsql_yylex(yyscan_t yyscanner)
*/
}
- plpgsql_yylval = aux1.lval;
- plpgsql_yylloc = aux1.lloc;
+ *yylvalp = aux1.lval;
+ *yyllocp = aux1.lloc;
plpgsql_yyleng = aux1.leng;
plpgsql_yytoken = tok1;
return tok1;
@@ -383,12 +383,12 @@ push_back_token(int token, TokenAuxData *auxdata)
* is not a good idea to push back a token code other than what you read.
*/
void
-plpgsql_push_back_token(int token)
+plpgsql_push_back_token(int token, YYSTYPE *yylvalp, YYLTYPE *yyllocp)
{
TokenAuxData auxdata;
- auxdata.lval = plpgsql_yylval;
- auxdata.lloc = plpgsql_yylloc;
+ auxdata.lval = *yylvalp;
+ auxdata.lloc = *yyllocp;
auxdata.leng = plpgsql_yyleng;
push_back_token(token, &auxdata);
}
@@ -512,9 +512,9 @@ plpgsql_scanner_errposition(int location)
* be misleading!
*/
void
-plpgsql_yyerror(yyscan_t yyscanner, const char *message)
+plpgsql_yyerror(YYLTYPE *yyllocp, yyscan_t yyscanner, const char *message)
{
- char *yytext = core_yy_extra.scanbuf + plpgsql_yylloc;
+ char *yytext = core_yy_extra.scanbuf + *yyllocp;
if (*yytext == '\0')
{
@@ -522,7 +522,7 @@ plpgsql_yyerror(yyscan_t yyscanner, const char *message)
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: %s is typically the translation of "syntax error" */
errmsg("%s at end of input", _(message)),
- plpgsql_scanner_errposition(plpgsql_yylloc)));
+ plpgsql_scanner_errposition(*yyllocp)));
}
else
{
@@ -538,7 +538,7 @@ plpgsql_yyerror(yyscan_t yyscanner, const char *message)
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: first %s is typically the translation of "syntax error" */
errmsg("%s at or near \"%s\"", _(message), yytext),
- plpgsql_scanner_errposition(plpgsql_yylloc)));
+ plpgsql_scanner_errposition(*yyllocp)));
}
}
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 07dcfa84f88..151ae7943df 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -1315,13 +1315,15 @@ extern void plpgsql_dumptree(PLpgSQL_function *func);
/*
* Scanner functions in pl_scanner.c
*/
+union YYSTYPE;
+#define YYLTYPE int
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void *yyscan_t;
#endif
-extern int plpgsql_yylex(yyscan_t yyscanner);
+extern int plpgsql_yylex(union YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t yyscanner);
extern int plpgsql_token_length(void);
-extern void plpgsql_push_back_token(int token);
+extern void plpgsql_push_back_token(int token, union YYSTYPE *yylvalp, YYLTYPE *yyllocp);
extern bool plpgsql_token_is_unreserved_keyword(int token);
extern void plpgsql_append_source_text(StringInfo buf,
int startlocation, int endlocation);
@@ -1329,7 +1331,7 @@ extern int plpgsql_peek(yyscan_t yyscanner);
extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc,
int *tok2_loc, yyscan_t yyscanner);
extern int plpgsql_scanner_errposition(int location);
-extern void plpgsql_yyerror(yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
+extern void plpgsql_yyerror(YYLTYPE *yyllocp, yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
extern int plpgsql_location_to_lineno(int location);
extern int plpgsql_latest_lineno(void);
extern yyscan_t plpgsql_scanner_init(const char *str);
--
2.47.1