Documentation for some new PL/Perl features. Patch from David Fetter,
authorNeil Conway
Wed, 13 Jul 2005 02:10:42 +0000 (02:10 +0000)
committerNeil Conway
Wed, 13 Jul 2005 02:10:42 +0000 (02:10 +0000)
various editorialization from Neil Conway.

doc/src/sgml/plperl.sgml

index c6fdb3bae2b66da6a0a828956eb517b7543ca05d..03a2064d3cda519f6ebc42fe5ff0a4cd4b16f855 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -54,6 +54,33 @@ $$ LANGUAGE plperl;
 
    The body of the function is ordinary Perl code.
   
+    
+    As with ordinary Perl code, you should use the strict pragma,
+    which you can do in one of two ways:
+
+    
+     
+      
+       Globally, by adding plperl to the list of 
+        linkend="guc-custom-variable-classes"> and setting
+       plperl.use_strict to true in
+       postgresql.conf
+      
+    
+     
+      
+       One function at a time, by using PL/PerlU (you must be database
+       superuser to do this) and including
+
+
+use strict;
+
+
+        in the function body.
+        
+    
+    
+    
 
    
     The syntax of the CREATE FUNCTION command requires
@@ -117,6 +144,20 @@ $$ LANGUAGE plperl;
    function is strict or not.
   
 
+  
+   Perl can return PostgreSQL arrays as
+   references to Perl arrays.  Here is an example:
+
+
+CREATE OR REPLACE function returns_array()
+RETURNS text[][] AS $$
+    return [['a"b','c,d'],['e\\f','g']];
+$$ LANGUAGE plperl;
+
+select returns_array();
+
+  
+
   
    Composite-type arguments are passed to the function as references
    to hashes.  The keys of the hash are the attribute names of the
@@ -158,18 +199,47 @@ SELECT * FROM perl_row();
   
 
   
-   PL/Perl functions can also return sets of either scalar or composite
-   types.  To do this, return a reference to an array that contains
-   either scalars or references to hashes, respectively.  Here are
-   some simple examples:
+    PL/Perl functions can also return sets of either scalar or
+    composite types.  In general, you'll want to return rows one at a
+    time both to speed up startup time and to keep from queueing up
+    the entire result set in memory.  You can do this with
+    return_next as illustrated below.  Note that
+    after the last return_next, you must put
+    either return; or (better) return
+    undef;
 
 
-CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
-return [0..$_[0]];
+CREATE OR REPLACE FUNCTION perl_set_int(int)
+RETURNS SETOF INTEGER AS $$
+    foreach (0..$_[0]) {
+        return_next($_);
+    }
+    return undef;
 $$ LANGUAGE plperl;
 
 SELECT * FROM perl_set_int(5);
 
+CREATE OR REPLACE FUNCTION perl_set()
+RETURNS SETOF testrowperl AS $$
+    return_next({ f1 => 1, f2 => 'Hello', f3 => 'World' });
+    return_next({ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' });
+    return_next({ f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' });
+    return undef;
+$$ LANGUAGE plperl;
+
+
+    For small result sets, you can return a reference to an array that
+    contains either scalars, references to arrays, or references to
+    hashes for simple types, array types, and composite types,
+    respectively.  Here are some simple examples of returning the entire
+    result set as a reference:
+
+
+CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
+    return [0..$_[0]];
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_set_int(5);
 
 CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
     return [
@@ -177,16 +247,11 @@ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
         { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' },
         { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }
     ];
-$$  LANGUAGE plperl;
+$$ LANGUAGE plperl;
 
 SELECT * FROM perl_set();
 
 
-   When you do this, Perl will have to build the entire array in memory;
-   therefore the technique does not scale to very large result sets. You
-   can instead call return_next for each element of
-   the result set, passing it either a scalar or a reference to a hash,
-   as appropriate to your function's return type.
   
 
     
@@ -217,7 +282,7 @@ SELECT * FROM perl_set();
   
 
   
-   PL/Perl itself presently provides two additional Perl commands:
+   PL/Perl provides two additional Perl commands:
 
    
     
@@ -281,7 +346,6 @@ 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 $res = [];
     my $rv = spi_exec_query('select i, v from test;');
     my $status = $rv->{status};
     my $nrows = $rv->{processed};
@@ -289,9 +353,9 @@ CREATE FUNCTION test_munge() RETURNS SETOF test AS $$
         my $row = $rv->{rows}[$rn];
         $row->{i} += 200 if defined($row->{i});
         $row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
-        push @$res, $row;
+        return_next($row);
     }
-    return $res;
+    return undef;
 $$ LANGUAGE plperl;
 
 SELECT * FROM test_munge();