Index: src/pl/plpgsql/src/gram.y
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/pl/plpgsql/src/gram.y,v
retrieving revision 1.36
diff -c -r1.36 gram.y
*** src/pl/plpgsql/src/gram.y	30 Aug 2002 00:28:41 -0000	1.36
--- src/pl/plpgsql/src/gram.y	1 Sep 2002 07:31:40 -0000
***************
*** 1159,1165 ****
  					}
  				;
  
- /* FIXME: this syntax needs work, RETURN NEXT breaks stmt_return */
  stmt_return_next: K_RETURN_NEXT lno
  					{
  						PLpgSQL_stmt_return_next *new;
--- 1159,1164 ----
Index: src/pl/plpgsql/src/pl_comp.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/pl/plpgsql/src/pl_comp.c,v
retrieving revision 1.49
diff -c -r1.49 pl_comp.c
*** src/pl/plpgsql/src/pl_comp.c	30 Aug 2002 00:28:41 -0000	1.49
--- src/pl/plpgsql/src/pl_comp.c	1 Sep 2002 07:31:40 -0000
***************
*** 212,221 ****
  			typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
  
  			/* Disallow pseudotype result, except VOID */
- 			/* XXX someday allow RECORD? */
  			if (typeStruct->typtype == 'p')
  			{
! 				if (procStruct->prorettype == VOIDOID)
  					/* okay */;
  				else if (procStruct->prorettype == TRIGGEROID ||
  						 procStruct->prorettype == OPAQUEOID)
--- 212,221 ----
  			typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
  
  			/* Disallow pseudotype result, except VOID */
  			if (typeStruct->typtype == 'p')
  			{
! 				if (procStruct->prorettype == VOIDOID ||
! 					procStruct->prorettype == RECORDOID)
  					/* okay */;
  				else if (procStruct->prorettype == TRIGGEROID ||
  						 procStruct->prorettype == OPAQUEOID)
***************
*** 227,233 ****
  						 format_type_be(procStruct->prorettype));
  			}
  
! 			if (typeStruct->typrelid != InvalidOid)
  				function->fn_retistuple = true;
  			else
  			{
--- 227,234 ----
  						 format_type_be(procStruct->prorettype));
  			}
  
! 			if (typeStruct->typrelid != InvalidOid ||
! 				procStruct->prorettype == RECORDOID)
  				function->fn_retistuple = true;
  			else
  			{
***************
*** 486,493 ****
  	}
  
  	/*
! 	 * Create the magic found variable indicating if the last FOR or
! 	 * SELECT statement returned data
  	 */
  	var = malloc(sizeof(PLpgSQL_var));
  	memset(var, 0, sizeof(PLpgSQL_var));
--- 487,493 ----
  	}
  
  	/*
! 	 * Create the magic FOUND variable.
  	 */
  	var = malloc(sizeof(PLpgSQL_var));
  	memset(var, 0, sizeof(PLpgSQL_var));
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.61
diff -c -r1.61 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c	30 Aug 2002 23:59:46 -0000	1.61
--- src/pl/plpgsql/src/pl_exec.c	1 Sep 2002 07:31:40 -0000
***************
*** 1588,1596 ****
  exec_stmt_return_next(PLpgSQL_execstate *estate,
  					  PLpgSQL_stmt_return_next *stmt)
  {
! 	TupleDesc tupdesc;
! 	int		 natts;
! 	HeapTuple tuple;
  	bool		free_tuple = false;
  
  	if (!estate->retisset)
--- 1588,1596 ----
  exec_stmt_return_next(PLpgSQL_execstate *estate,
  					  PLpgSQL_stmt_return_next *stmt)
  {
! 	TupleDesc	tupdesc;
! 	int			natts;
! 	HeapTuple	tuple;
  	bool		free_tuple = false;
  
  	if (!estate->retisset)
Index: src/test/regress/expected/plpgsql.out
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/test/regress/expected/plpgsql.out,v
retrieving revision 1.10
diff -c -r1.10 plpgsql.out
*** src/test/regress/expected/plpgsql.out	30 Aug 2002 00:28:41 -0000	1.10
--- src/test/regress/expected/plpgsql.out	1 Sep 2002 07:31:40 -0000
***************
*** 1680,1682 ****
--- 1680,1735 ----
                    11
  (10 rows)
  
+ create function test_ret_set_rec_dyn(int) returns setof record as '
+ DECLARE
+ 	retval RECORD;
+ BEGIN
+ 	IF $1 > 10 THEN
+ 		SELECT INTO retval 5, 10, 15;
+ 		RETURN NEXT retval;
+ 		RETURN NEXT retval;
+ 	ELSE
+ 		SELECT INTO retval 50, 5::numeric, ''xxx''::text;
+ 		RETURN NEXT retval;
+ 		RETURN NEXT retval;
+ 	END IF;
+ 	RETURN;
+ END;' language 'plpgsql';
+ SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int);
+  a | b  | c  
+ ---+----+----
+  5 | 10 | 15
+  5 | 10 | 15
+ (2 rows)
+ 
+ SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text);
+  a  | b |  c  
+ ----+---+-----
+  50 | 5 | xxx
+  50 | 5 | xxx
+ (2 rows)
+ 
+ create function test_ret_rec_dyn(int) returns record as '
+ DECLARE
+ 	retval RECORD;
+ BEGIN
+ 	IF $1 > 10 THEN
+ 		SELECT INTO retval 5, 10, 15;
+ 		RETURN retval;
+ 	ELSE
+ 		SELECT INTO retval 50, 5::numeric, ''xxx''::text;
+ 		RETURN retval;
+ 	END IF;
+ END;' language 'plpgsql';
+ SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int);
+  a | b  | c  
+ ---+----+----
+  5 | 10 | 15
+ (1 row)
+ 
+ SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text);
+  a  | b |  c  
+ ----+---+-----
+  50 | 5 | xxx
+ (1 row)
+ 
Index: src/test/regress/sql/plpgsql.sql
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/test/regress/sql/plpgsql.sql,v
retrieving revision 1.9
diff -c -r1.9 plpgsql.sql
*** src/test/regress/sql/plpgsql.sql	30 Aug 2002 00:28:41 -0000	1.9
--- src/test/regress/sql/plpgsql.sql	1 Sep 2002 07:31:40 -0000
***************
*** 1524,1526 ****
--- 1524,1561 ----
  END;' language 'plpgsql';
  
  select * from test_ret_set_scalar(1,10);
+ 
+ create function test_ret_set_rec_dyn(int) returns setof record as '
+ DECLARE
+ 	retval RECORD;
+ BEGIN
+ 	IF $1 > 10 THEN
+ 		SELECT INTO retval 5, 10, 15;
+ 		RETURN NEXT retval;
+ 		RETURN NEXT retval;
+ 	ELSE
+ 		SELECT INTO retval 50, 5::numeric, ''xxx''::text;
+ 		RETURN NEXT retval;
+ 		RETURN NEXT retval;
+ 	END IF;
+ 	RETURN;
+ END;' language 'plpgsql';
+ 
+ SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int);
+ SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text);
+ 
+ create function test_ret_rec_dyn(int) returns record as '
+ DECLARE
+ 	retval RECORD;
+ BEGIN
+ 	IF $1 > 10 THEN
+ 		SELECT INTO retval 5, 10, 15;
+ 		RETURN retval;
+ 	ELSE
+ 		SELECT INTO retval 50, 5::numeric, ''xxx''::text;
+ 		RETURN retval;
+ 	END IF;
+ END;' language 'plpgsql';
+ 
+ SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int);
+ SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text);
