Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d6375d6

Browse files
author
Neil Conway
committed
Documentation for some new PL/Perl features. Patch from David Fetter,
various editorialization from Neil Conway.
1 parent b4363b7 commit d6375d6

File tree

1 file changed

+81
-17
lines changed

1 file changed

+81
-17
lines changed

doc/src/sgml/plperl.sgml

Lines changed: 81 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.41 2005/06/05 03:16:29 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.42 2005/07/13 02:10:42 neilc Exp $
33
-->
44

55
<chapter id="plperl">
@@ -54,6 +54,33 @@ $$ LANGUAGE plperl;
5454
</programlisting>
5555
The body of the function is ordinary Perl code.
5656
</para>
57+
<para>
58+
As with ordinary Perl code, you should use the strict pragma,
59+
which you can do in one of two ways:
60+
61+
<itemizedlist>
62+
<listitem>
63+
<para>
64+
Globally, by adding <quote>plperl</quote> to the list of <xref
65+
linkend="guc-custom-variable-classes"> and setting
66+
<literal>plperl.use_strict</literal> to true in
67+
<filename>postgresql.conf</filename>
68+
</para>
69+
</listitem>
70+
<listitem>
71+
<para>
72+
One function at a time, by using PL/PerlU (you must be database
73+
superuser to do this) and including
74+
75+
<programlisting>
76+
use strict;
77+
</programlisting>
78+
79+
in the function body.
80+
</para>
81+
</listitem>
82+
</itemizedlist>
83+
</para>
5784

5885
<para>
5986
The syntax of the <command>CREATE FUNCTION</command> command requires
@@ -117,6 +144,20 @@ $$ LANGUAGE plperl;
117144
function is strict or not.
118145
</para>
119146

147+
<para>
148+
Perl can return <productname>PostgreSQL</productname> arrays as
149+
references to Perl arrays. Here is an example:
150+
151+
<programlisting>
152+
CREATE OR REPLACE function returns_array()
153+
RETURNS text[][] AS $$
154+
return [['a"b','c,d'],['e\\f','g']];
155+
$$ LANGUAGE plperl;
156+
157+
select returns_array();
158+
</programlisting>
159+
</para>
160+
120161
<para>
121162
Composite-type arguments are passed to the function as references
122163
to hashes. The keys of the hash are the attribute names of the
@@ -158,35 +199,59 @@ SELECT * FROM perl_row();
158199
</para>
159200

160201
<para>
161-
PL/Perl functions can also return sets of either scalar or composite
162-
types. To do this, return a reference to an array that contains
163-
either scalars or references to hashes, respectively. Here are
164-
some simple examples:
202+
PL/Perl functions can also return sets of either scalar or
203+
composite types. In general, you'll want to return rows one at a
204+
time both to speed up startup time and to keep from queueing up
205+
the entire result set in memory. You can do this with
206+
<function>return_next</function> as illustrated below. Note that
207+
after the last <function>return_next</function>, you must put
208+
either <literal>return;</literal> or (better) <literal>return
209+
undef;</literal>
165210

166211
<programlisting>
167-
CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
168-
return [0..$_[0]];
212+
CREATE OR REPLACE FUNCTION perl_set_int(int)
213+
RETURNS SETOF INTEGER AS $$
214+
foreach (0..$_[0]) {
215+
return_next($_);
216+
}
217+
return undef;
169218
$$ LANGUAGE plperl;
170219

171220
SELECT * FROM perl_set_int(5);
172221

222+
CREATE OR REPLACE FUNCTION perl_set()
223+
RETURNS SETOF testrowperl AS $$
224+
return_next({ f1 =&gt; 1, f2 =&gt; 'Hello', f3 =&gt; 'World' });
225+
return_next({ f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' });
226+
return_next({ f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' });
227+
return undef;
228+
$$ LANGUAGE plperl;
229+
</programlisting>
230+
231+
For small result sets, you can return a reference to an array that
232+
contains either scalars, references to arrays, or references to
233+
hashes for simple types, array types, and composite types,
234+
respectively. Here are some simple examples of returning the entire
235+
result set as a reference:
236+
237+
<programlisting>
238+
CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
239+
return [0..$_[0]];
240+
$$ LANGUAGE plperl;
241+
242+
SELECT * FROM perl_set_int(5);
173243

174244
CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
175245
return [
176246
{ f1 =&gt; 1, f2 =&gt; 'Hello', f3 =&gt; 'World' },
177247
{ f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' },
178248
{ f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' }
179249
];
180-
$$ LANGUAGE plperl;
250+
$$ LANGUAGE plperl;
181251

182252
SELECT * FROM perl_set();
183253
</programlisting>
184254

185-
When you do this, Perl will have to build the entire array in memory;
186-
therefore the technique does not scale to very large result sets. You
187-
can instead call <function>return_next</function> for each element of
188-
the result set, passing it either a scalar or a reference to a hash,
189-
as appropriate to your function's return type.
190255
</para>
191256

192257
<para>
@@ -217,7 +282,7 @@ SELECT * FROM perl_set();
217282
</para>
218283

219284
<para>
220-
PL/Perl itself presently provides two additional Perl commands:
285+
PL/Perl provides two additional Perl commands:
221286

222287
<variablelist>
223288
<varlistentry>
@@ -281,17 +346,16 @@ INSERT INTO test (i, v) VALUES (3, 'third line');
281346
INSERT INTO test (i, v) VALUES (4, 'immortal');
282347

283348
CREATE FUNCTION test_munge() RETURNS SETOF test AS $$
284-
my $res = [];
285349
my $rv = spi_exec_query('select i, v from test;');
286350
my $status = $rv-&gt;{status};
287351
my $nrows = $rv-&gt;{processed};
288352
foreach my $rn (0 .. $nrows - 1) {
289353
my $row = $rv-&gt;{rows}[$rn];
290354
$row-&gt;{i} += 200 if defined($row-&gt;{i});
291355
$row-&gt;{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row-&gt;{v}));
292-
push @$res, $row;
356+
return_next($row);
293357
}
294-
return $res;
358+
return undef;
295359
$$ LANGUAGE plperl;
296360

297361
SELECT * FROM test_munge();

0 commit comments

Comments
 (0)