Commit d6375d61 authored by Neil Conway's avatar Neil Conway

Documentation for some new PL/Perl features. Patch from David Fetter,

various editorialization from Neil Conway.
parent b4363b77
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.41 2005/06/05 03:16:29 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.42 2005/07/13 02:10:42 neilc Exp $
--> -->
<chapter id="plperl"> <chapter id="plperl">
...@@ -54,6 +54,33 @@ $$ LANGUAGE plperl; ...@@ -54,6 +54,33 @@ $$ LANGUAGE plperl;
</programlisting> </programlisting>
The body of the function is ordinary Perl code. The body of the function is ordinary Perl code.
</para> </para>
<para>
As with ordinary Perl code, you should use the strict pragma,
which you can do in one of two ways:
<itemizedlist>
<listitem>
<para>
Globally, by adding <quote>plperl</quote> to the list of <xref
linkend="guc-custom-variable-classes"> and setting
<literal>plperl.use_strict</literal> to true in
<filename>postgresql.conf</filename>
</para>
</listitem>
<listitem>
<para>
One function at a time, by using PL/PerlU (you must be database
superuser to do this) and including
<programlisting>
use strict;
</programlisting>
in the function body.
</para>
</listitem>
</itemizedlist>
</para>
<para> <para>
The syntax of the <command>CREATE FUNCTION</command> command requires The syntax of the <command>CREATE FUNCTION</command> command requires
...@@ -117,6 +144,20 @@ $$ LANGUAGE plperl; ...@@ -117,6 +144,20 @@ $$ LANGUAGE plperl;
function is strict or not. function is strict or not.
</para> </para>
<para>
Perl can return <productname>PostgreSQL</productname> arrays as
references to Perl arrays. Here is an example:
<programlisting>
CREATE OR REPLACE function returns_array()
RETURNS text[][] AS $$
return [['a"b','c,d'],['e\\f','g']];
$$ LANGUAGE plperl;
select returns_array();
</programlisting>
</para>
<para> <para>
Composite-type arguments are passed to the function as references Composite-type arguments are passed to the function as references
to hashes. The keys of the hash are the attribute names of the to hashes. The keys of the hash are the attribute names of the
...@@ -158,18 +199,47 @@ SELECT * FROM perl_row(); ...@@ -158,18 +199,47 @@ SELECT * FROM perl_row();
</para> </para>
<para> <para>
PL/Perl functions can also return sets of either scalar or composite PL/Perl functions can also return sets of either scalar or
types. To do this, return a reference to an array that contains composite types. In general, you'll want to return rows one at a
either scalars or references to hashes, respectively. Here are time both to speed up startup time and to keep from queueing up
some simple examples: the entire result set in memory. You can do this with
<function>return_next</function> as illustrated below. Note that
after the last <function>return_next</function>, you must put
either <literal>return;</literal> or (better) <literal>return
undef;</literal>
<programlisting> <programlisting>
CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$ CREATE OR REPLACE FUNCTION perl_set_int(int)
return [0..$_[0]]; RETURNS SETOF INTEGER AS $$
foreach (0..$_[0]) {
return_next($_);
}
return undef;
$$ LANGUAGE plperl; $$ LANGUAGE plperl;
SELECT * FROM perl_set_int(5); SELECT * FROM perl_set_int(5);
CREATE OR REPLACE FUNCTION perl_set()
RETURNS SETOF testrowperl AS $$
return_next({ f1 =&gt; 1, f2 =&gt; 'Hello', f3 =&gt; 'World' });
return_next({ f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' });
return_next({ f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' });
return undef;
$$ LANGUAGE plperl;
</programlisting>
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:
<programlisting>
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 $$ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
return [ return [
...@@ -177,16 +247,11 @@ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$ ...@@ -177,16 +247,11 @@ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
{ f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' }, { f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' },
{ f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' } { f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' }
]; ];
$$ LANGUAGE plperl; $$ LANGUAGE plperl;
SELECT * FROM perl_set(); SELECT * FROM perl_set();
</programlisting> </programlisting>
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 <function>return_next</function> 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.
</para> </para>
<para> <para>
...@@ -217,7 +282,7 @@ SELECT * FROM perl_set(); ...@@ -217,7 +282,7 @@ SELECT * FROM perl_set();
</para> </para>
<para> <para>
PL/Perl itself presently provides two additional Perl commands: PL/Perl provides two additional Perl commands:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
...@@ -281,7 +346,6 @@ INSERT INTO test (i, v) VALUES (3, 'third line'); ...@@ -281,7 +346,6 @@ INSERT INTO test (i, v) VALUES (3, 'third line');
INSERT INTO test (i, v) VALUES (4, 'immortal'); INSERT INTO test (i, v) VALUES (4, 'immortal');
CREATE FUNCTION test_munge() RETURNS SETOF test AS $$ CREATE FUNCTION test_munge() RETURNS SETOF test AS $$
my $res = [];
my $rv = spi_exec_query('select i, v from test;'); my $rv = spi_exec_query('select i, v from test;');
my $status = $rv-&gt;{status}; my $status = $rv-&gt;{status};
my $nrows = $rv-&gt;{processed}; my $nrows = $rv-&gt;{processed};
...@@ -289,9 +353,9 @@ CREATE FUNCTION test_munge() RETURNS SETOF test AS $$ ...@@ -289,9 +353,9 @@ CREATE FUNCTION test_munge() RETURNS SETOF test AS $$
my $row = $rv-&gt;{rows}[$rn]; my $row = $rv-&gt;{rows}[$rn];
$row-&gt;{i} += 200 if defined($row-&gt;{i}); $row-&gt;{i} += 200 if defined($row-&gt;{i});
$row-&gt;{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row-&gt;{v})); $row-&gt;{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row-&gt;{v}));
push @$res, $row; return_next($row);
} }
return $res; return undef;
$$ LANGUAGE plperl; $$ LANGUAGE plperl;
SELECT * FROM test_munge(); SELECT * FROM test_munge();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment