Thread: session persistent data for plperl
The attached tiny patch (not intended for application yet) provides a space for plperl functions to create and share session persistent data, which I should think would increase the utility of plperl. Essentially it creates a hash called %session_globals which it then injects into the safe container where plperl functions live. Comments are welcome - this is just a proof of concept. If this seems good to people, I will try to use a similar mechanism to "register" plperl functions so they can call each other. cheers andrew (stupid) example use (using dollar quoting in psql ;-) ): andrew=# create function perlfunc() returns text language plperl as $$ andrew$# if (!exists $session_globals{x}) { $session_globals{x} = 'abcxyz'; } andrew$# return $session_globals{x}++; andrew$# $$; CREATE FUNCTION andrew=# select perlfunc();perlfunc ----------abcxyz (1 row) andrew=# select perlfunc();perlfunc ----------abcxza (1 row) andrew=# create function perlfunc2() returns text language plperl as $$ andrew$# if (!exists $session_globals{x}) { $session_globals{x} = 'abcxyz'; } andrew$# $session_globals{x} = reverse $session_globals{x}; andrew$# return $session_globals{x}++; andrew$# $$; CREATE FUNCTION andrew=# select perlfunc2();perlfunc2 -----------bzxcba (1 row) andrew=# select perlfunc2();perlfunc2 -----------bbcxzb (1 row) andrew=# select perlfunc();perlfunc ----------bbcxzc (1 row)
I wrote: > > The attached tiny patch (not intended for application yet) provides a > space for plperl functions to create and share session persistent > data, which I should think would increase the utility of plperl. > Essentially it creates a hash called %session_globals which it then > injects into the safe container where plperl functions live. > ...and the patch is attached here Index: src/pl/plperl/plperl.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/pl/plperl/plperl.c,v retrieving revision 1.42 diff -c -w -r1.42 plperl.c *** src/pl/plperl/plperl.c 6 Jan 2004 23:55:19 -0000 1.42 --- src/pl/plperl/plperl.c 8 Feb 2004 17:18:18 -0000 *************** *** 207,215 **** * no commas between the next 5 please. They are supposed to be * one string */ ! "require Safe; SPI::bootstrap();" "sub ::mksafefunc { my $x = new Safe; $x->permit_only(':default');$x->permit(':base_math');" ! "$x->share(qw[&elog &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR]);" " return $x->reval(qq[sub { $_[0] }]); }" "sub ::mkunsafefunc {return eval(qq[ sub { $_[0] } ]); }" }; --- 207,215 ---- * no commas between the next 5 please. They are supposed to be * one string */ ! "require Safe; SPI::bootstrap(); use vars qw(%session_globals);" "sub ::mksafefunc { my $x = new Safe; $x->permit_only(':default');$x->permit(':base_math');" ! "$x->share(qw[&elog &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %session_globals]);" " return $x->reval(qq[sub { $_[0] }]); }" "sub ::mkunsafefunc {return eval(qq[ sub { $_[0] } ]); }" };
What about transactions? Let's say the first call was in a transaction that's been rolled back. Semantically, that means the call never happened. If you maintain the session data in a table, everything is fine of course. But if it's in memory the solution has some rather nasty implications to it. This is one scenario where I think it would be useful if the backend provided some transaction callback mechanisms (discussed in this group earlier under topic "Transaction callback"). That would enable the implementation of "transaction aware session persistent data" in memory. Regards, - thomas "Andrew Dunstan" <andrew@dunslane.net> wrote in message news:402672F4.4050905@dunslane.net... > > The attached tiny patch (not intended for application yet) provides a > space for plperl functions to create and share session persistent data, > which I should think would increase the utility of plperl. Essentially > it creates a hash called %session_globals which it then injects into the > safe container where plperl functions live. > > Comments are welcome - this is just a proof of concept. If this seems > good to people, I will try to use a similar mechanism to "register" > plperl functions so they can call each other. > > cheers > > andrew > > (stupid) example use (using dollar quoting in psql ;-) ): > > andrew=# create function perlfunc() returns text language plperl as $$ > andrew$# if (!exists $session_globals{x}) { $session_globals{x} = > 'abcxyz'; } > andrew$# return $session_globals{x}++; > andrew$# $$; > CREATE FUNCTION > andrew=# select perlfunc(); > perlfunc > ---------- > abcxyz > (1 row) > > andrew=# select perlfunc(); > perlfunc > ---------- > abcxza > (1 row) > > andrew=# create function perlfunc2() returns text language plperl as $$ > andrew$# if (!exists $session_globals{x}) { $session_globals{x} = > 'abcxyz'; } > andrew$# $session_globals{x} = reverse $session_globals{x}; > andrew$# return $session_globals{x}++; > andrew$# $$; > CREATE FUNCTION > andrew=# select perlfunc2(); > perlfunc2 > ----------- > bzxcba > (1 row) > > andrew=# select perlfunc2(); > perlfunc2 > ----------- > bbcxzb > (1 row) > > andrew=# select perlfunc(); > perlfunc > ---------- > bbcxzc > (1 row) > > > > ---------------------------(end of broadcast)--------------------------- > TIP 8: explain analyze is your friend >
"Thomas Hallgren" <thhal@mailblocks.com> writes: > "Andrew Dunstan" <andrew@dunslane.net> wrote: >> The attached tiny patch (not intended for application yet) provides a >> space for plperl functions to create and share session persistent data, > What about transactions? AFAICS, Andrew is just emulating a feature that has always existed in pltcl. Insisting that the plperl version must have intelligence not found in the pltcl version seems like raising the bar unfairly. regards, tom lane
As Tom Lane noted, pltcl already allows this. In fact, it appears that plperl already allows functions to create their own session-persistent data, but doesn't share data between functions. I guess there's a philosophical question: should we apply transactional safety to (transient) data not stored in the database? I can see both sides of the argument, but have no motivation myself to provide such transactional safety, at least not now. cheers andrew Thomas Hallgren wrote: >What about transactions? Let's say the first call was in a transaction >that's been rolled back. Semantically, that means the call never happened. >If you maintain the session data in a table, everything is fine of course. >But if it's in memory the solution has some rather nasty implications to it. > >This is one scenario where I think it would be useful if the backend >provided some transaction callback mechanisms (discussed in this group >earlier under topic "Transaction callback"). That would enable the >implementation of "transaction aware session persistent data" in memory. > >Regards, > >- thomas > >"Andrew Dunstan" <andrew@dunslane.net> wrote in message >news:402672F4.4050905@dunslane.net... > > >>The attached tiny patch (not intended for application yet) provides a >>space for plperl functions to create and share session persistent data, >>which I should think would increase the utility of plperl. Essentially >>it creates a hash called %session_globals which it then injects into the >>safe container where plperl functions live. >> >>Comments are welcome - this is just a proof of concept. If this seems >>good to people, I will try to use a similar mechanism to "register" >>plperl functions so they can call each other. >> >> >> > >
I'm not insisting anything. I merely suggest something that all pl<lang> implementations would have a potential benefit from. But perhaps I should insist. Both with respect to plperl, pltcl, or any other pl<lang> where session data is possible. IMHO, session data spanning more than one transcation is dangerous and error prone if it's not coordinated with the transactions. Even if one can argue that, it's the developers responsability to avoid the pitfalls, I still think its a bit harsh to just disregard the benefits such mechanisms could gain by transaction callback. Regards, - thomas "Tom Lane" <tgl@sss.pgh.pa.us> wrote in message news:4322.1076266805@sss.pgh.pa.us... > "Thomas Hallgren" <thhal@mailblocks.com> writes: > > "Andrew Dunstan" <andrew@dunslane.net> wrote: > >> The attached tiny patch (not intended for application yet) provides a > >> space for plperl functions to create and share session persistent data, > > > What about transactions? > > AFAICS, Andrew is just emulating a feature that has always existed in > pltcl. Insisting that the plperl version must have intelligence not > found in the pltcl version seems like raising the bar unfairly. > > regards, tom lane > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faqs/FAQ.html >
Adnrew, > The attached tiny patch (not intended for application yet) provides a > space for plperl functions to create and share session persistent data, > which I should think would increase the utility of plperl. You want to really make PL/Perl more useful? Add an SPI interface, and work out the kinks in error-trapping via eval{}. This would be far more useful that session variables. Just a thought. -- Josh Berkus Aglio Database Solutions San Francisco
Josh Berkus wrote: >Adnrew, > Jsoh :-) >You want to really make PL/Perl more useful? Add an SPI interface, and work >out the kinks in error-trapping via eval{}. This would be far more useful >that session variables. > >Just a thought. > I don't intend to stop there. I admit that the gain in value from my patch is limited, but I think it is greater than 0, and for a 2 line change a cheap win. When I have bedded down some other things I am working on (e.g. logging enhancements, dollar quoting) I intend to look further at some of the Perl issues, both on the server side and the client side. As a longtime and fond Perl user, I don't like seeing Perl as the poor cousin PL in our community. cheers andrew