Skip to content

Commit 29d82d6

Browse files
committed
parser: allow multiple DECLARE keywords in function definitions
Previously, UDFs with multiple DECLARE statements would cause the parser to panic. This patch allows us to accept these statements, which is what Postgres does. Fixes: #129285 Release note (bug fix): Using more than one DECLARE statment in the definition of a user defined function now correctly declares additional variables.
1 parent 870c5fb commit 29d82d6

File tree

2 files changed

+45
-21
lines changed

2 files changed

+45
-21
lines changed

pkg/ccl/logictestccl/testdata/logic_test/plpgsql_block

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,3 +693,40 @@ BEGIN
693693
END IF;
694694
END;
695695
$$ LANGUAGE PLpgSQL;
696+
697+
subtest multi_declare
698+
699+
statement ok
700+
DROP FUNCTION IF EXISTS f;
701+
702+
statement ok
703+
CREATE FUNCTION f() RETURNS INT AS $$
704+
DECLARE
705+
x INT := 0;
706+
DECLARE
707+
y INT := x + 1;
708+
BEGIN
709+
RAISE NOTICE '% %', x, y;
710+
RETURN 0;
711+
END;
712+
$$ LANGUAGE PLpgSQL;
713+
714+
query T noticetrace
715+
SELECT f();
716+
----
717+
NOTICE: 0 1
718+
719+
statement ok
720+
DROP FUNCTION IF EXISTS f;
721+
722+
statement error pgcode 42601 pq: duplicate declaration at or near "x"
723+
CREATE FUNCTION f() RETURNS INT AS $$
724+
DECLARE
725+
x INT := 0;
726+
DECLARE
727+
x INT := 1;
728+
BEGIN
729+
RAISE NOTICE '%', x;
730+
RETURN 0;
731+
END;
732+
$$ LANGUAGE PLpgSQL;

pkg/sql/plpgsql/parser/plpgsql.y

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ func (u *plpgsqlSymUnion) sqlStatement() tree.Statement {
344344
%type <plpgsqltree.Statement> stmt_commit stmt_rollback
345345
%type <plpgsqltree.Statement> stmt_case stmt_foreach_a
346346

347-
%type <plpgsqltree.Statement> decl_stmt decl_statement
347+
%type <plpgsqltree.Statement> decl_statement
348348
%type <[]plpgsqltree.Statement> decl_sect opt_decl_stmts decl_stmts
349349

350350
%type <[]plpgsqltree.Exception> exception_sect proc_exceptions
@@ -419,36 +419,23 @@ opt_decl_stmts: decl_stmts
419419
}
420420
;
421421

422-
decl_stmts: decl_stmts decl_stmt
422+
opt_declare: DECLARE {}
423+
| {}
424+
;
425+
426+
decl_stmts: decl_stmts opt_declare decl_statement
423427
{
424428
decs := $1.statements()
425-
dec := $2.statement()
429+
dec := $3.statement()
426430
$$.val = append(decs, dec)
427431
}
428-
| decl_stmt
432+
| decl_statement
429433
{
430434
dec := $1.statement()
431435
$$.val = []plpgsqltree.Statement{dec}
432436
}
433437
;
434438

435-
decl_stmt : decl_statement
436-
{
437-
$$.val = $1.statement()
438-
}
439-
| DECLARE
440-
{
441-
// This is to allow useless extra "DECLARE" keywords in the declare section.
442-
$$.val = (plpgsqltree.Statement)(nil)
443-
}
444-
// TODO(drewk): turn this block on and throw useful error if user
445-
// tries to put the block label just before BEGIN instead of before
446-
// DECLARE.
447-
//| LESS_LESS any_identifier GREATER_GREATER
448-
// {
449-
// }
450-
;
451-
452439
decl_statement: decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval
453440
{
454441
$$.val = &plpgsqltree.Declaration{

0 commit comments

Comments
 (0)