Re: PG 8.1beta3 out soon

Поиск
Список
Период
Сортировка
От Andrew Dunstan
Тема Re: PG 8.1beta3 out soon
Дата
Msg-id 434B100F.1080506@dunslane.net
обсуждение исходный текст
Ответ на Re: PG 8.1beta3 out soon  ("Greg Sabino Mullane" <greg@turnstep.com>)
Ответы Re: PG 8.1beta3 out soon  (Tom Lane <tgl@sss.pgh.pa.us>)
Re: PG 8.1beta3 out soon  ("Greg Sabino Mullane" <greg@turnstep.com>)
Список pgsql-hackers

Greg Sabino Mullane wrote:

>>Core's current plan is to bundle 8.1beta3 tomorrow evening (Tuesday PM,
>>North American east coast time) for announcement Wednesday.  Any last
>>minute bug fixes out there?
>>    
>>
>
>Anyone able to duplicate my plperl bug? If it is genuine, I would really
>like to see it fixed for 8.1, as it's a showstopper.
>
>
>  
>

I take it you are referring to this: 
http://archives.postgresql.org/pgsql-bugs/2005-10/msg00095.php

I don't think it's really a bug - it's a well known perl effect that has 
caught many people over the years, especially unwary users of 
Apache::Registry who fail to recognise that their scripts are being 
wrapped inside an anonymous subroutine.

I took your example and simulated it entirely outside postgres/plperl to 
show that this is a pure perl effect. The script is like this:

---------------------------------------------------
#!/usr/bin/perl

use strict;
use warnings;

use constant { INFO => 'INFO' };

sub elog
{   print join(": ",@_),"\n";
}

my $func = sub
{
   my $_TD = $_[0]; shift;
#    use vars qw($_TD); local $_TD = shift;
   my $event = $_TD->{event};   elog(INFO, "Top event    : $event");   my $newname = $_TD->{new}{a};   elog(INFO, "Top
newname : $newname");   &subber($event);     sub subber   {       no warnings qw(uninitialized);       my $arg = shift;
     elog(INFO, join(" | ",caller(0)));       elog(INFO, join(" | ",caller(1)));       elog(INFO, "Sub global   :
$event");      elog(INFO, "Sub direct   : $_TD->{event}");       my $newname = $_TD->{new}{a};       elog(INFO, "Sub
newname : $newname");   }   elog(INFO, "Bottom event : $event");
 
};

&$func({ new=>{a=>22},event=>'INSERT' });
&$func({ new=>{a=>33},event=>'UPDATE' });
&$func({ new=>{a=>44},event=>'INSERT' });
&$func({ new=>{a=>55},event=>'UPDATE' });

--------------------------------------------------

and the output is this - not the telltale first two lines:

[andrew@alphonso ~]$ perl nonanontry.pl
Variable "$event" will not stay shared at nonanontry.pl line 34.
Variable "$_TD" will not stay shared at nonanontry.pl line 35.
INFO: Top event    : INSERT
INFO: Top newname  : 22
INFO: main | nonanontry.pl | 26 | main::subber | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: main | nonanontry.pl | 43 | main::__ANON__ | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: Sub global   : INSERT
INFO: Sub direct   : INSERT
INFO: Sub newname  : 22
INFO: Bottom event : INSERT
INFO: Top event    : UPDATE
INFO: Top newname  : 33
INFO: main | nonanontry.pl | 26 | main::subber | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: main | nonanontry.pl | 44 | main::__ANON__ | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: Sub global   : INSERT
INFO: Sub direct   : INSERT
INFO: Sub newname  : 22
INFO: Bottom event : UPDATE
INFO: Top event    : INSERT
INFO: Top newname  : 44
INFO: main | nonanontry.pl | 26 | main::subber | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: main | nonanontry.pl | 45 | main::__ANON__ | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: Sub global   : INSERT
INFO: Sub direct   : INSERT
INFO: Sub newname  : 22
INFO: Bottom event : INSERT
INFO: Top event    : UPDATE
INFO: Top newname  : 55
INFO: main | nonanontry.pl | 26 | main::subber | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: main | nonanontry.pl | 46 | main::__ANON__ | 1 |  |  |  | 2 | 
UUUUUUUUUUUU
INFO: Sub global   : INSERT
INFO: Sub direct   : INSERT
INFO: Sub newname  : 22
INFO: Bottom event : UPDATE
[andrew@alphonso ~]$


Now, if we swap the line that declares $_TD (which is just like it is in 
plperl.c) for the line underneath it, we could get rid of this effect 
(try it and see). I don't think it would have any memory leaks, but we'd 
need to check.

However, that would only avoid the problem for what we know about, 
namely $_TD. The problem would remain for any lexical variable, because 
you are using a named nested subroutine which tries to access the 
lexical in its declaratory scope. Pass the hashref as an argument and 
have it only refer to the passed object rather than the one that is 
lexically visible and all should be well.

My take: we should document this better, but it ain't broke so it don't 
need fixing, although I would not object strenuously to changing the 
behaviour of $_TD.

cheers

andrew


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

Предыдущее
От: "Kevin Grittner"
Дата:
Сообщение: Re: slower merge join on sorted data chosen over
Следующее
От: Tom Lane
Дата:
Сообщение: Re: slower merge join on sorted data chosen over nested loop