X-Original-To: pgsql-docs-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 3AE0D52A71; Sat, 30 Jul 2005 02:44:19 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 62495-01; Sat, 30 Jul 2005 05:44:07 +0000 (GMT) Received: from fetter.org (dsl092-188-065.sfo1.dsl.speakeasy.net [66.92.188.65]) by svr1.postgresql.org (Postfix) with ESMTP id 2448C52A2B; Sat, 30 Jul 2005 02:44:06 -0300 (ADT) Received: from fetter.org (localhost.localdomain [127.0.0.1]) by fetter.org (8.13.4/8.12.10) with ESMTP id j6U5hu8N012414; Fri, 29 Jul 2005 22:43:56 -0700 Received: (from shackle@localhost) by fetter.org (8.13.4/8.13.4/Submit) id j6U5hsNo012413; Fri, 29 Jul 2005 22:43:54 -0700 Date: Fri, 29 Jul 2005 22:43:54 -0700 From: David Fetter To: PostgreSQL Patches , PostgreSQL Docs , Bruce Momjian Cc: Andrew Dunstan , Alvaro Herrera , Michael Fuhr , pgsql-hackers@postgresql.org Subject: Re: [HACKERS] PL/Perl list value return causes segfault Message-ID: <20050730054354.GL27147@fetter.org> References: <42D44731.90306@dunslane.net> <200507300324.j6U3Ob713189@candle.pha.pa.us> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="uAKRQypu60I7Lcqm" Content-Disposition: inline In-Reply-To: <200507300324.j6U3Ob713189@candle.pha.pa.us> User-Agent: Mutt/1.4.2.1i X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.062 tagged_above=0 required=5 tests=AWL, FORGED_RCVD_HELO X-Spam-Level: X-Archive-Number: 200507/35 X-Sequence-Number: 3161 --uAKRQypu60I7Lcqm Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Jul 29, 2005 at 11:24:37PM -0400, Bruce Momjian wrote: > > Would someone who knows perl update plperl.sgml and send me a patch? > > Also, is this still true in 8.1: > > In the current implementation, if you are fetching or returning > very large data sets, you should be aware that these will all go > into memory. That's no longer true. Please find enclosed a new patch :) Cheers, D -- David Fetter david@fetter.org http://fetter.org/ phone: +1 510 893 6100 mobile: +1 415 235 3778 Remember to vote! --uAKRQypu60I7Lcqm Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="plperl_new_features.diff" Index: doc/src/sgml/plperl.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/plperl.sgml,v retrieving revision 2.42 diff -c -r2.42 plperl.sgml *** doc/src/sgml/plperl.sgml 13 Jul 2005 02:10:42 -0000 2.42 --- doc/src/sgml/plperl.sgml 30 Jul 2005 05:42:56 -0000 *************** *** 46,52 **** To create a function in the PL/Perl language, use the standard ! syntax: CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ # PL/Perl function body --- 46,57 ---- To create a function in the PL/Perl language, use the standard ! syntax. A PL/Perl function must always return a scalar value. You ! can return more complex structures (arrays, records, and sets) ! in the appropriate context by returning a reference. ! Never return a list. Here follows an example of a PL/Perl ! function. ! CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ # PL/Perl function body *************** *** 282,288 **** ! PL/Perl provides two additional Perl commands: --- 287,293 ---- ! PL/Perl provides three additional Perl commands: *************** *** 293,303 **** spi_exec_query(query [, max-rows]) spi_exec_query(command) ! Executes an SQL command. Here is an example of a query ! (SELECT command) with the optional maximum ! number of rows: $rv = spi_exec_query('SELECT * FROM my_table', 5); --- 298,315 ---- spi_exec_query(query [, max-rows]) spi_exec_query(command) + spi_query(command) + spi_fetchrow(command) + ! spi_exec_query executes an SQL command and ! returns the entire rowset as a reference to an array of hash ! references. You should only use this command when you know ! that the result set will be relatively small. Here is an ! example of a query (SELECT command) with the ! optional maximum number of rows: ! $rv = spi_exec_query('SELECT * FROM my_table', 5); *************** *** 345,351 **** INSERT INTO test (i, v) VALUES (3, 'third line'); INSERT INTO test (i, v) VALUES (4, 'immortal'); ! CREATE FUNCTION test_munge() RETURNS SETOF test AS $$ my $rv = spi_exec_query('select i, v from test;'); my $status = $rv->{status}; my $nrows = $rv->{processed}; --- 357,363 ---- INSERT INTO test (i, v) VALUES (3, 'third line'); INSERT INTO test (i, v) VALUES (4, 'immortal'); ! CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$ my $rv = spi_exec_query('select i, v from test;'); my $status = $rv->{status}; my $nrows = $rv->{processed}; *************** *** 360,366 **** SELECT * FROM test_munge(); ! --- 372,416 ---- SELECT * FROM test_munge(); ! ! ! spi_query and spi_fetchrow ! work together as a pair for rowsets which may be large, or for cases ! where you wish to return rows as they arrive. ! spi_fetchrow works only with ! spi_query. The following example illustrates how ! you use them together: ! ! ! CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT); ! ! CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ ! use Digest::MD5 qw(md5_hex); ! my $file = '/usr/share/dict/words'; ! my $t = localtime; ! elog(NOTICE, "opening file $file at $t" ); ! open my $fh, '<', $file # ooh, it's a file access! ! or elog(ERROR, "Can't open $file for reading: $!"); ! my @words = <$fh>; ! close $fh; ! $t = localtime; ! elog(NOTICE, "closed file $file at $t"); ! chomp(@words); ! my $row; ! my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)"); ! while (defined ($row = spi_fetchrow($sth))) { ! return_next({ ! the_num => $row->{a}, ! the_text => md5_hex($words[rand @words]) ! }); ! } ! return; ! $$ LANGUAGE plperlu; ! ! SELECT * from lotsa_md5(500); ! ! ! *************** *** 716,724 **** ! In the current implementation, if you are fetching or returning ! very large data sets, you should be aware that these will all go ! into memory. --- 766,776 ---- ! If you are fetching or returning very large data sets using ! spi_exec_query, you should be aware that ! these will all go into memory. You can avoid this by using ! spi_query/spi_fetchrow as ! illustrated earlier. --uAKRQypu60I7Lcqm--