|
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/Perlitself presentlyprovides 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 | + returnundef; |
295 | 359 | $$ LANGUAGE plperl; |
296 | 360 |
|
297 | 361 | SELECT * FROM test_munge(); |
|