Re: PG 8.1beta3 out soon

From: Andrew Dunstan <andrew(at)dunslane(dot)net>
To: Greg Sabino Mullane <greg(at)turnstep(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: PG 8.1beta3 out soon
Date: 2005-10-11 01:06:23
Message-ID: 434B100F.1080506@dunslane.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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(at)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(at)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

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2005-10-11 01:10:38 Re: slower merge join on sorted data chosen over nested loop
Previous Message Kevin Grittner 2005-10-10 23:34:25 Re: slower merge join on sorted data chosen over