From 8c78f8e65c2f68e946f145770cf24a49ac88c891 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Thu, 5 Feb 2009 15:25:49 +0000
Subject: [PATCH] Add PL/PgSQL FOUND and GET DIAGNOSTICS support for RETURN
 QUERY statement

Pavel Stehule
---
 doc/src/sgml/plpgsql.sgml             | 10 ++++++++-
 src/pl/plpgsql/src/pl_exec.c          |  7 +++++-
 src/test/regress/expected/plpgsql.out | 32 +++++++++++++++++++++++++++
 src/test/regress/sql/plpgsql.sql      | 24 ++++++++++++++++++++
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index 0e9e43065df..db6d08fd69f 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.137 2009/02/04 21:30:41 alvherre Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.138 2009/02/05 15:25:49 momjian Exp $ -->
 
 <chapter id="plpgsql">
   <title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
@@ -1356,6 +1356,14 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
             execution of other statements within the loop body.
            </para>
           </listitem>
+          <listitem>
+           <para>
+            A <command>RETURN QUERY</command> and <command>RETURN QUERY
+            EXECUTE</command> statements set <literal>FOUND</literal>
+            true if the query returns at least one row, false if no row
+            is returned.
+           </para>
+          </listitem>
          </itemizedlist>
 
      <literal>FOUND</literal> is a local variable within each
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 69fea921537..4e5388f6249 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.231 2009/01/21 11:13:14 heikki Exp $
+ *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.232 2009/02/05 15:25:49 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2286,6 +2286,7 @@ exec_stmt_return_query(PLpgSQL_execstate *estate,
 					   PLpgSQL_stmt_return_query *stmt)
 {
 	Portal		portal;
+	uint32			processed = 0;
 
 	if (!estate->retisset)
 		ereport(ERROR,
@@ -2327,6 +2328,7 @@ exec_stmt_return_query(PLpgSQL_execstate *estate,
 			HeapTuple	tuple = SPI_tuptable->vals[i];
 
 			tuplestore_puttuple(estate->tuple_store, tuple);
+			processed++;
 		}
 		MemoryContextSwitchTo(old_cxt);
 
@@ -2336,6 +2338,9 @@ exec_stmt_return_query(PLpgSQL_execstate *estate,
 	SPI_freetuptable(SPI_tuptable);
 	SPI_cursor_close(portal);
 
+	estate->eval_processed = processed;
+	exec_set_found(estate, processed != 0);
+
 	return PLPGSQL_RC_OK;
 }
 
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index 94a485f46b3..b6f333c787d 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -3666,3 +3666,35 @@ select * from tftest(10);
 (2 rows)
 
 drop function tftest(int);
+create or replace function rttest()
+returns setof int as $$
+declare rc int;
+begin
+  return query values(10),(20);
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+  return query select * from (values(10),(20)) f(a) where false;
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+  return query execute 'values(10),(20)';
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+  return query execute 'select * from (values(10),(20)) f(a) where false';
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+end;
+$$ language plpgsql;
+select * from rttest();
+NOTICE:  t 2
+NOTICE:  f 0
+NOTICE:  t 2
+NOTICE:  f 0
+ rttest 
+--------
+     10
+     20
+     10
+     20
+(4 rows)
+
+drop function rttest();
diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql
index 9ebe2b5f332..1e261747f46 100644
--- a/src/test/regress/sql/plpgsql.sql
+++ b/src/test/regress/sql/plpgsql.sql
@@ -2948,3 +2948,27 @@ $$ language plpgsql immutable strict;
 select * from tftest(10);
 
 drop function tftest(int);
+
+create or replace function rttest()
+returns setof int as $$
+declare rc int;
+begin
+  return query values(10),(20);
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+  return query select * from (values(10),(20)) f(a) where false;
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+  return query execute 'values(10),(20)';
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+  return query execute 'select * from (values(10),(20)) f(a) where false';
+  get diagnostics rc = row_count;
+  raise notice '% %', found, rc;
+end;
+$$ language plpgsql;
+
+select * from rttest();
+
+drop function rttest();
+
-- 
GitLab