Clobbered parameter names via DECLARE in PL/PgSQL

Brendan Jurd <direvus@gmail.com>

From: Brendan Jurd <direvus@gmail.com>
To: pgsql-hackers@postgresql.org
Date: 2012-04-15T07:49:30Z
Lists: pgsql-hackers
Hello hackers,

It turns out that in a PL/PgSQL function, you can DECLARE a variable
using the same name as one of the function parameters.  This has the
effect of clobbering the parameter, for example:

CREATE OR REPLACE FUNCTION declare_clobber(foo int)
RETURNS int LANGUAGE plpgsql AS $$
	DECLARE
		foo text;
	BEGIN
		RETURN foo;
	END;
$$;

SELECT declare_clobber(1);
==> NULL

On the other hand, PL/PgSQL does protect against duplicate definitions
within DECLARE:

CREATE OR REPLACE FUNCTION declare_clobber(foo int)
RETURNS int LANGUAGE plpgsql AS $$
	DECLARE
		foo int;
		foo text;
	BEGIN
		RETURN foo;
	END;
$$;
==> ERROR:  duplicate declaration at or near "foo"

And it also protects against using a DECLAREd name as a parameter alias:

CREATE OR REPLACE FUNCTION declare_clobber(foo int)
RETURNS int LANGUAGE plpgsql AS $$
	DECLARE
		bar int;
		bar ALIAS FOR $1;
	BEGIN
		RETURN bar;
	END;
$$;
==> ERROR:  duplicate declaration at or near "bar"

I would suggest that if the user DECLAREs a variable with the same
name as a parameter, it is very evidently a programming error, and we
should raise the same "duplicate declaration" error.  I haven't yet
looked at how difficult this would be to fix, but if there are no
objections I would like to attempt a patch.

Cheers,
BJ