Here's a patch to do the following:

1. Rename spi_return_next to return_next.
2. Add a new test for return_next.
3. Update the expected output.
4. Update the documentation.

Abhijit Menon-Sen
This commit is contained in:
Bruce Momjian 2005-06-05 03:16:42 +00:00
parent 27bdb0c40d
commit bebe7c5600
5 changed files with 55 additions and 57 deletions

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.40 2005/05/20 01:52:24 neilc Exp $
$PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.41 2005/06/05 03:16:29 momjian Exp $
-->
<chapter id="plperl">
@ -182,8 +182,11 @@ $$ LANGUAGE plperl;
SELECT * FROM perl_set();
</programlisting>
Note that 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.
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>

View File

@ -98,7 +98,7 @@ spi_spi_exec_query(query, ...)
RETVAL
void
spi_spi_return_next(rv)
spi_return_next(rv)
SV *rv;
CODE:
plperl_return_next(rv);

View File

@ -40,10 +40,7 @@ CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
return undef;
$$ LANGUAGE plperl;
SELECT perl_set_int(5);
perl_set_int
--------------
(0 rows)
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_set_int(5);
perl_set_int
--------------
@ -53,16 +50,7 @@ CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
return [0..$_[0]];
$$ LANGUAGE plperl;
SELECT perl_set_int(5);
perl_set_int
--------------
0
1
2
3
4
5
(6 rows)
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_set_int(5);
perl_set_int
--------------
@ -109,10 +97,7 @@ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
return undef;
$$ LANGUAGE plperl;
SELECT perl_set();
perl_set
----------
(0 rows)
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_set();
f1 | f2 | f3
----+----+----
@ -126,9 +111,9 @@ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
];
$$ LANGUAGE plperl;
SELECT perl_set();
ERROR: elements of Perl result array must be reference to hash
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_set();
ERROR: elements of Perl result array must be reference to hash
ERROR: setof-composite-returning Perl function must call return_next with reference to hash
CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
return [
{ f1 => 1, f2 => 'Hello', f3 => 'World' },
@ -137,13 +122,7 @@ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
];
$$ LANGUAGE plperl;
SELECT perl_set();
perl_set
----------------------
(1,Hello,World)
(2,Hello,PostgreSQL)
(3,Hello,PL/Perl)
(3 rows)
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_set();
f1 | f2 | f3
----+-------+------------
@ -186,10 +165,7 @@ CREATE OR REPLACE FUNCTION perl_record_set() RETURNS SETOF record AS $$
return undef;
$$ LANGUAGE plperl;
SELECT perl_record_set();
perl_record_set
-----------------
(0 rows)
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_record_set();
ERROR: a column definition list is required for functions returning "record"
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
@ -205,11 +181,11 @@ CREATE OR REPLACE FUNCTION perl_record_set() RETURNS SETOF record AS $$
];
$$ LANGUAGE plperl;
SELECT perl_record_set();
ERROR: function returning record called in context that cannot accept type record
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_record_set();
ERROR: a column definition list is required for functions returning "record"
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
ERROR: elements of Perl result array must be reference to hash
ERROR: setof-composite-returning Perl function must call return_next with reference to hash
CREATE OR REPLACE FUNCTION perl_record_set() RETURNS SETOF record AS $$
return [
{ f1 => 1, f2 => 'Hello', f3 => 'World' },
@ -218,7 +194,7 @@ CREATE OR REPLACE FUNCTION perl_record_set() RETURNS SETOF record AS $$
];
$$ LANGUAGE plperl;
SELECT perl_record_set();
ERROR: function returning record called in context that cannot accept type record
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_record_set();
ERROR: a column definition list is required for functions returning "record"
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
@ -261,13 +237,7 @@ RETURNS SETOF record AS $$
];
$$ LANGUAGE plperl;
SELECT perl_out_params_set();
perl_out_params_set
----------------------
(1,Hello,World)
(2,Hello,PostgreSQL)
(3,Hello,PL/Perl)
(3 rows)
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_out_params_set();
f1 | f2 | f3
----+-------+------------
@ -277,13 +247,7 @@ SELECT * FROM perl_out_params_set();
(3 rows)
SELECT (perl_out_params_set()).f3;
f3
------------
World
PostgreSQL
PL/Perl
(3 rows)
ERROR: set-valued function called in context that cannot accept a set
--
-- Check behavior with erroneous return values
--
@ -323,12 +287,12 @@ CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return 42;
$$ LANGUAGE plperl;
SELECT * FROM foo_set_bad();
ERROR: set-returning Perl function must return reference to array
ERROR: set-returning Perl function must return reference to array or use return_next
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return {y => 3, z => 4};
$$ LANGUAGE plperl;
SELECT * FROM foo_set_bad();
ERROR: set-returning Perl function must return reference to array
ERROR: set-returning Perl function must return reference to array or use return_next
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return [
[1, 2],
@ -336,7 +300,7 @@ return [
];
$$ LANGUAGE plperl;
SELECT * FROM foo_set_bad();
ERROR: elements of Perl result array must be reference to hash
ERROR: setof-composite-returning Perl function must call return_next with reference to hash
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return [
{y => 3, z => 4}
@ -368,3 +332,21 @@ SELECT perl_get_field((11,12), 'z');
(1 row)
--
-- Test return_next
--
CREATE OR REPLACE FUNCTION perl_srf_rn() RETURNS SETOF RECORD AS $$
$i = 0;
for ("World", "PostgreSQL", "PL/Perl") {
return_next({f1=>++$i, f2=>'Hello', f3=>$_});
}
return;
$$ language plperl;
SELECT * from perl_srf_rn() AS (f1 INTEGER, f2 TEXT, f3 TEXT);
f1 | f2 | f3
----+-------+------------
1 | Hello | World
2 | Hello | PostgreSQL
3 | Hello | PL/Perl
(3 rows)

View File

@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.75 2005/06/04 20:33:06 momjian Exp $
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.76 2005/06/05 03:16:35 momjian Exp $
*
**********************************************************************/
@ -222,7 +222,7 @@ plperl_safe_init(void)
"use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');"
"$PLContainer->permit_only(':default');"
"$PLContainer->permit(qw[:base_math !:base_io sort time]);"
"$PLContainer->share(qw[&elog &spi_exec_query &spi_return_next "
"$PLContainer->share(qw[&elog &spi_exec_query &return_next "
"&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);"
;

View File

@ -234,3 +234,16 @@ $$ LANGUAGE plperl;
SELECT perl_get_field((11,12), 'x');
SELECT perl_get_field((11,12), 'y');
SELECT perl_get_field((11,12), 'z');
--
-- Test return_next
--
CREATE OR REPLACE FUNCTION perl_srf_rn() RETURNS SETOF RECORD AS $$
$i = 0;
for ("World", "PostgreSQL", "PL/Perl") {
return_next({f1=>++$i, f2=>'Hello', f3=>$_});
}
return;
$$ language plperl;
SELECT * from perl_srf_rn() AS (f1 INTEGER, f2 TEXT, f3 TEXT);