|
1 | 1 | <!--
|
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 $ |
3 | 3 | -->
|
4 | 4 |
|
5 | 5 | <chapter id="plperl">
|
@@ -54,6 +54,33 @@ $$ LANGUAGE plperl;
|
54 | 54 | </programlisting>
|
55 | 55 | The body of the function is ordinary Perl code.
|
56 | 56 | </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> |
57 | 84 |
|
58 | 85 | <para>
|
59 | 86 | The syntax of the <command>CREATE FUNCTION</command> command requires
|
@@ -117,6 +144,20 @@ $$ LANGUAGE plperl;
|
117 | 144 | function is strict or not.
|
118 | 145 | </para>
|
119 | 146 |
|
| 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 | + |
120 | 161 | <para>
|
121 | 162 | Composite-type arguments are passed to the function as references
|
122 | 163 | to hashes. The keys of the hash are the attribute names of the
|
@@ -158,35 +199,59 @@ SELECT * FROM perl_row();
|
158 | 199 | </para>
|
159 | 200 |
|
160 | 201 | <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> |
165 | 210 |
|
166 | 211 | <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; |
169 | 218 | $$ LANGUAGE plperl;
|
170 | 219 |
|
171 | 220 | SELECT * FROM perl_set_int(5);
|
172 | 221 |
|
| 222 | +CREATE OR REPLACE FUNCTION perl_set() |
| 223 | +RETURNS SETOF testrowperl AS $$ |
| 224 | + return_next({ f1 => 1, f2 => 'Hello', f3 => 'World' }); |
| 225 | + return_next({ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' }); |
| 226 | + return_next({ f1 => 3, f2 => 'Hello', f3 => '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); |
173 | 243 |
|
174 | 244 | CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
|
175 | 245 | return [
|
176 | 246 | { f1 => 1, f2 => 'Hello', f3 => 'World' },
|
177 | 247 | { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' },
|
178 | 248 | { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }
|
179 | 249 | ];
|
180 |
| -$$ LANGUAGE plperl; |
| 250 | +$$ LANGUAGE plperl; |
181 | 251 |
|
182 | 252 | SELECT * FROM perl_set();
|
183 | 253 | </programlisting>
|
184 | 254 |
|
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. |
190 | 255 | </para>
|
191 | 256 |
|
192 | 257 | <para>
|
@@ -217,7 +282,7 @@ SELECT * FROM perl_set();
|
217 | 282 | </para>
|
218 | 283 |
|
219 | 284 | <para>
|
220 |
| - PL/Perl itself presently provides two additional Perl commands: |
| 285 | + PL/Perl provides two additional Perl commands: |
221 | 286 |
|
222 | 287 | <variablelist>
|
223 | 288 | <varlistentry>
|
@@ -281,17 +346,16 @@ INSERT INTO test (i, v) VALUES (3, 'third line');
|
281 | 346 | INSERT INTO test (i, v) VALUES (4, 'immortal');
|
282 | 347 |
|
283 | 348 | CREATE FUNCTION test_munge() RETURNS SETOF test AS $$
|
284 |
| - my $res = []; |
285 | 349 | my $rv = spi_exec_query('select i, v from test;');
|
286 | 350 | my $status = $rv->{status};
|
287 | 351 | my $nrows = $rv->{processed};
|
288 | 352 | foreach my $rn (0 .. $nrows - 1) {
|
289 | 353 | my $row = $rv->{rows}[$rn];
|
290 | 354 | $row->{i} += 200 if defined($row->{i});
|
291 | 355 | $row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
|
292 |
| - push @$res, $row; |
| 356 | + return_next($row); |
293 | 357 | }
|
294 |
| - return $res; |
| 358 | + return undef; |
295 | 359 | $$ LANGUAGE plperl;
|
296 | 360 |
|
297 | 361 | SELECT * FROM test_munge();
|
|
0 commit comments