Index: doc/src/sgml/plpgsql.sgml
===================================================================
RCS file: /var/lib/cvs/pgsql-server/doc/src/sgml/plpgsql.sgml,v
retrieving revision 1.1
diff -c -r1.1 plpgsql.sgml
*** doc/src/sgml/plpgsql.sgml	30 Jul 2002 19:36:10 -0000	1.1
--- doc/src/sgml/plpgsql.sgml	13 Aug 2002 17:26:03 -0000
***************
*** 852,861 ****
      </para>
  
      <para>
!      There is a special variable named FOUND of type
!      <type>boolean</type> that can be used immediately after a SELECT
!      INTO to check if an assignment had success (that is, at least one
!      row was returned by the SELECT).  For example,
    
  <programlisting>
  SELECT INTO myrec * FROM EMP WHERE empname = myname;
--- 852,888 ----
      </para>
  
      <para>
! 	 There is a special variable named <literal>FOUND</literal> of
!      type <type>boolean</type>. It will be set to true if:
! 	 <itemizedlist>
! 	  <listitem>
! 	   <para>
! 		A SELECT INTO statement is executed, and it returns one or
! 		more rows.
! 	   </para>
! 	  </listitem>
! 	  <listitem>
! 	   <para>
! 		A UPDATE, INSERT, or DELETE statement is executed, and it
! 		affects one or more rows.
! 	   </para>
! 	  </listitem>
! 	  <listitem>
! 	   <para>
! 		A PERFORM statement is executed, and it discards one or more
! 		rows.
! 	   </para>
! 	  </listitem>
! 	  <listitem>
! 	   <para>
! 		A FETCH statement is executed, and it returns an additional
! 		row.
! 	   </para>
! 	  </listitem>
! 	 </itemizedlist>
! 	 You can use <literal>FOUND</literal> immediately after a SELECT
! 	 INTO statement to check if an assignment is successful (that is,
! 	 at least one row was returned by the SELECT statement). For example,
    
  <programlisting>
  SELECT INTO myrec * FROM EMP WHERE empname = myname;
Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.56
diff -c -r1.56 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c	24 Jun 2002 23:12:06 -0000	1.56
--- src/pl/plpgsql/src/pl_exec.c	13 Aug 2002 17:26:03 -0000
***************
*** 1846,1851 ****
--- 1846,1856 ----
  	bool		isnull;
  
  	/*
+ 	 * Set magic FOUND variable to false
+ 	 */
+ 	exec_set_found(estate, false);
+ 
+ 	/*
  	 * On the first call for this expression generate the plan
  	 */
  	if (expr->plan == NULL)
***************
*** 1921,1929 ****
--- 1926,1943 ----
  	{
  		case SPI_OK_UTILITY:
  		case SPI_OK_SELINTO:
+ 			break;
+ 
+ 			/*
+ 			 * If the INSERT, DELETE, or UPDATE query affected at least
+ 			 * one tuple, set the magic 'FOUND' variable to true. This
+ 			 * conforms with the behavior of PL/SQL.
+ 			 */
  		case SPI_OK_INSERT:
  		case SPI_OK_DELETE:
  		case SPI_OK_UPDATE:
+ 			if (SPI_processed > 0)
+ 				exec_set_found(estate, true);
  			break;
  
  		case SPI_OK_SELECT:
***************
*** 1931,1938 ****
  				 "\n\tIf you want to discard the results, use PERFORM instead.");
  
  		default:
! 			elog(ERROR, "error executing query \"%s\"",
! 				 expr->query);
  	}
  
  	/*
--- 1945,1951 ----
  				 "\n\tIf you want to discard the results, use PERFORM instead.");
  
  		default:
! 			elog(ERROR, "error executing query \"%s\"", expr->query);
  	}
  
  	/*
Index: src/test/regress/expected/plpgsql.out
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/test/regress/expected/plpgsql.out,v
retrieving revision 1.6
diff -c -r1.6 plpgsql.out
*** src/test/regress/expected/plpgsql.out	21 Sep 2001 00:11:31 -0000	1.6
--- src/test/regress/expected/plpgsql.out	13 Aug 2002 17:26:03 -0000
***************
*** 1534,1536 ****
--- 1534,1581 ----
   4,3,2,1,3
  (1 row)
  
+ --
+ -- Test the FOUND magic variable
+ --
+ CREATE TABLE found_test_tbl (a int);
+ create function test_found ()
+   returns boolean as '
+   declare
+   begin
+   insert into found_test_tbl values (1);
+   if FOUND then
+      insert into found_test_tbl values (2);
+   else
+      insert into found_test_tbl values (3);
+   end if;
+ 
+   update found_test_tbl set a = 10 where a = 1;
+   if FOUND then
+     insert into found_test_tbl values (4);
+   else
+     insert into found_test_tbl values (5);
+   end if;
+ 
+   delete from found_test_tbl where a = 100; -- matches no rows
+   if FOUND then
+     insert into found_test_tbl values (6);
+   else
+     insert into found_test_tbl values (7);
+   end if;
+   return true;
+   end;' language 'plpgsql';
+ select test_found();
+  test_found 
+ ------------
+  t
+ (1 row)
+ 
+ select * from found_test_tbl;
+  a  
+ ----
+   2
+  10
+   4
+   7
+ (4 rows)
+ 
Index: src/test/regress/sql/plpgsql.sql
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/test/regress/sql/plpgsql.sql,v
retrieving revision 1.5
diff -c -r1.5 plpgsql.sql
*** src/test/regress/sql/plpgsql.sql	21 Sep 2001 00:11:31 -0000	1.5
--- src/test/regress/sql/plpgsql.sql	13 Aug 2002 17:26:03 -0000
***************
*** 1414,1416 ****
--- 1414,1451 ----
  END;' LANGUAGE 'plpgsql';
  
  SELECT recursion_test(4,3);
+ 
+ --
+ -- Test the FOUND magic variable
+ --
+ CREATE TABLE found_test_tbl (a int);
+ 
+ create function test_found ()
+   returns boolean as '
+   declare
+   begin
+   insert into found_test_tbl values (1);
+   if FOUND then
+      insert into found_test_tbl values (2);
+   else
+      insert into found_test_tbl values (3);
+   end if;
+ 
+   update found_test_tbl set a = 10 where a = 1;
+   if FOUND then
+     insert into found_test_tbl values (4);
+   else
+     insert into found_test_tbl values (5);
+   end if;
+ 
+   delete from found_test_tbl where a = 100; -- matches no rows
+   if FOUND then
+     insert into found_test_tbl values (6);
+   else
+     insert into found_test_tbl values (7);
+   end if;
+   return true;
+   end;' language 'plpgsql';
+ 
+ select test_found();
+ select * from found_test_tbl;
