Here's a patch to do the following:
authorBruce Momjian <bruce@momjian.us>
Sun, 5 Jun 2005 03:16:42 +0000 (03:16 +0000)
committerBruce Momjian <bruce@momjian.us>
Sun, 5 Jun 2005 03:16:42 +0000 (03:16 +0000)
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

doc/src/sgml/plperl.sgml
src/pl/plperl/SPI.xs
src/pl/plperl/expected/plperl.out
src/pl/plperl/plperl.c
src/pl/plperl/sql/plperl.sql

index 0680c6106e89296755bf4017bf0d08bfa0e7697a..c6fdb3bae2b66da6a0a828956eb517b7543ca05d 100644 (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>
index cfcbc779a6f918ca26704db1da5cd102ac370422..d1bab6d39b75e574282f70d9bdb5a9f87a942f93 100644 (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);
index c488c4a4fcad09d7cff36298350cae8928e983ae..ea067c972405d64f94359a8b0bd9b80eaaad7414 100644 (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)
+
index 82fdb86b180c864cd9f9a0f0ce8612ab16c5104a..6cd3494fb9f275d726e3b31d6522c998ce1d9f08 100644 (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 ]);"
               ;
 
index 0cfcd1752db4d6c4983d541e2b3ac3ba1f4bbea1..3e601173ddf316ec038dde50f105a55b7e44e6c9 100644 (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);