Re: example of really weird caching (or whatever) problem

Поиск
Список
Период
Сортировка
От Richard Huxton
Тема Re: example of really weird caching (or whatever) problem
Дата
Msg-id 4925882C.1000909@archonet.com
обсуждение исходный текст
Ответ на Re: example of really weird caching (or whatever) problem  ("Brandon Metcalf" <bmetcalf@nortel.com>)
Ответы Re: example of really weird caching (or whatever) problem  ("Brandon Metcalf" <bmetcalf@nortel.com>)
Список pgsql-general
Brandon Metcalf wrote:
> d == dev@archonet.com writes:
>
>  d> Brandon Metcalf wrote:
>  d> > Yep, it seems that's the problem.  If I pass in $table and use a
>  d> > lexical variable defined inside do_delete(), the problem goes away.
>  d> > So, this is where my understanding of how triggers work lacks.  For a
>  d> > given session, each execution of a trigger isn't completely
>  d> > independent?
>
>  d> Nothing to do with triggers - it's all to do with your Perl code.
>
>
> I respectfully disagree because if I don't execute a DELETE on foo2 as
> shown in my original email, the problem doesn't occur.

Of course not.

>  Somewhere in
> the trigger execution it's remembering the first table on which the
> trigger fired.

Yes. in your "sub do_delete" with it's local variable.

> So, the information about foo2 is coming from
> somewhere and it's in the Perl code.

Yes, your local copy of $table in do_delete.

> In other words, I performing two
> different DELETEs which cause two different invocations of the same
> trigger.

You've written your code such that do_delete has a local copy of $table.
  In fact, the way it actually works iirc is that when you exit the
trigger function "my $table" goes out of scope and vanishes, but the
"$table" in do_delete doesn't vanish and persists from call to call. You
might call this a static variable in C terms.

>  d> #!/usr/bin/perl
>
>  d> sub foo {
>  d>     my $x = shift;
>  d>     print "foo x = $x\n";
>  d>     bar();
>  d>     return;
>
>  d>     sub bar {
>  d>         print "bar x = $x\n";
>  d>     }
>  d> }
>
>  d> foo(1);
>  d> foo(2);
>  d> exit;

This code mirrors _exactly_ what is happening with your trigger. On the
first call to foo $x is set to 1, on the second it's set to 2. That
doesn't affect "sub bar" though because its copy of $x is still the one
from the first call.

Maybe the following makes it clearer:
#!/usr/bin/perl

sub foo {
        my $x = shift;
        print "foo x = $x, ";
        bar();
        return;

        sub bar {
                print "bar x = $x\n";
                $x--;
        }
}

for my $i (1..5) { foo($i); }
exit;

$ ./perl_example.pl
foo x = 1, bar x = 1
foo x = 2, bar x = 0
foo x = 3, bar x = -1
foo x = 4, bar x = -2
foo x = 5, bar x = -3

The two $x variables go their separate ways and the one in "bar" doesn't
go out of scope at the end of the function.

--
  Richard Huxton
  Archonet Ltd

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

Предыдущее
От: "Jean-Christophe Arnu"
Дата:
Сообщение: Re: lesslog "incorrect resource manager data checksum."
Следующее
От: Tom Lane
Дата:
Сообщение: Re: transaction_read_only effects on performance, actual meaning (was: How to reduce impact of a query)