Re: plpgsql.warn_shadow

Поиск
Список
Период
Сортировка
От Joel Jacobson
Тема Re: plpgsql.warn_shadow
Дата
Msg-id CAASwCXdhhD-Ci9zLrt=oxZpqb__xQ6Oec1d=KuLwPeH=yUohBw@mail.gmail.com
обсуждение исходный текст
Ответ на Re: plpgsql.warn_shadow  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: plpgsql.warn_shadow  (Andrew Dunstan <andrew@dunslane.net>)
Список pgsql-hackers
On Tue, Mar 4, 2014 at 4:06 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Joel Jacobson <joel@trustly.com> writes:
>> On Tue, Mar 4, 2014 at 12:55 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>>> You're reasoning from a false premise: it's *not* necessarily an error.
>
>> Isn't this almost exactly the same situation as we had in 9.0?
>> "PL/pgSQL now throws an error if a variable name conflicts with a
>> column name used in a query (Tom Lane)"
>
> No; the reason why the old behavior was problematic was precisely that
> it failed to conform to normal block-structured language design rules
> (namely that the most closely nested definition should win).  If it
> had been like that to start with we'd probably have just left it that
> way.  The complexity of behavior that you see there today is there to
> help people with debugging issues created by that change of behavior.
>
> While I don't necessarily have an objection to creating a way to help
> debug variable-name-shadowing issues, the idea that they're broken and
> we can just start throwing errors is *wrong*.  The whole point of block
> structure in a language is that a block of code can be understood
> independently of what surrounds it.

I agree it should be possible to reuse a variable in a new block,
but I think the IN/OUT variable should be considered to be at the
*same* block-level
as the first block of code, thus an error should be thrown.

Consider the same scenario in for instance Perl:

# Example 1
# Prints "1" and doesn't throw an error, which is perfectly OK.
use warnings;
my $foo = 1;
{   my $foo = 2;
}
print $foo;

# Example 2
# "my" variable $foo masks earlier declaration in same scope at
warn_shadow.pl line 3.
use warnings;
my $foo = 1;
my $foo = 2;
print $foo;

Or maybe this is a better example, since we are talking about functions:

# Example 3
# "my" variable $bar masks earlier declaration in same scope at
warn_shadow.pl line 7.
use warnings;
sub foo
{   # IN-variables:   my ($bar) = @_;   # DECLARE:   my $bar;   # BEGIN:   $bar = 1;   return $bar;
}
foo(2);


I understand that from a technical perspective, the mandatory
BEGIN...END you always need in a PL/pgSQL function, is a new block,
and the variables declared are perhaps technically in a new block, at
a deeper level than the IN/OUT variables. But I would still argue the
expected behaviour of PL/pgSQL for a new user would be to consider the
IN/OUT variables to be in the same block as the variables declared in
the function's first block.



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Robert Haas
Дата:
Сообщение: Re: VACUUM FULL/CLUSTER doesn't update pg_class's pg_class.relfrozenxid
Следующее
От: Robert Haas
Дата:
Сообщение: Re: ALTER TABLE lock strength reduction patch is unsafe