diff -c -r --new-file pgsql.old/src/pl/plpgsql/src/gram.y pgsql.new/src/pl/plpgsql/src/gram.y
*** pgsql.old/src/pl/plpgsql/src/gram.y	2005-04-07 16:53:04.000000000 +0200
--- pgsql.new/src/pl/plpgsql/src/gram.y	2005-06-01 10:33:49.000000000 +0200
***************
*** 108,120 ****
  %type <str>		decl_stmts decl_stmt
  
  %type <expr>	expr_until_semi expr_until_rightbracket
! %type <expr>	expr_until_then expr_until_loop
  %type <expr>	opt_exitcond
  
! %type <ival>	assign_var cursor_variable
  %type <var>		cursor_varptr
  %type <variable>	decl_cursor_arg
  %type <forvariable>	for_variable
  %type <stmt>	for_control
  
  %type <str>		opt_lblname opt_label
--- 108,121 ----
  %type <str>		decl_stmts decl_stmt
  
  %type <expr>	expr_until_semi expr_until_rightbracket
! %type <expr>	expr_until_then expr_until_loop expr_until_intosemi
  %type <expr>	opt_exitcond
  
! %type <ival>	assign_var cursor_variable 
  %type <var>		cursor_varptr
  %type <variable>	decl_cursor_arg
  %type <forvariable>	for_variable
+ %type <forvariable> 	opt_into_rec
  %type <stmt>	for_control
  
  %type <str>		opt_lblname opt_label
***************
*** 809,814 ****
--- 810,816 ----
  					}
  				;
  
+ 
  stmt_for		: opt_label K_FOR for_control loop_body
  					{
  						/* This runs after we've scanned the loop body */
***************
*** 1250,1268 ****
  					}
  				;
  
! stmt_dynexecute : K_EXECUTE lno expr_until_semi
  					{
  						PLpgSQL_stmt_dynexecute *new;
  
  						new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
  						new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
  						new->lineno   = $2;
! 						new->query	  = $3;
! 
  						$$ = (PLpgSQL_stmt *)new;
  					}
  				;
! 
  stmt_open		: K_OPEN lno cursor_varptr
  					{
  						PLpgSQL_stmt_open *new;
--- 1252,1287 ----
  					}
  				;
  
! stmt_dynexecute: K_EXECUTE lno expr_until_intosemi opt_into_rec
  					{
  						PLpgSQL_stmt_dynexecute *new;
  
  						new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
  						new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
  						new->lineno   = $2;
! 						new->query    = $3;
! 						new->rec 	= $4.rec;
! 						new->row	= $4.row;
  						$$ = (PLpgSQL_stmt *)new;
+ 
  					}
  				;
! opt_into_rec: 				{ $$.rec = NULL; $$.row = NULL; }
! 		    	
! 		| T_RECORD ';'
! 		 			{
! 						check_assignable((PLpgSQL_datum *) yylval.rec);
! 						$$.rec = yylval.rec; 
! 						$$.row = NULL;
! 					}
! 		| T_ROW ';'
! 					{
! 						check_assignable((PLpgSQL_datum *) yylval.row);
! 						$$.rec = NULL; 
! 						$$.row = yylval.row;
! 					}
! 				;					
! 		    
  stmt_open		: K_OPEN lno cursor_varptr
  					{
  						PLpgSQL_stmt_open *new;
***************
*** 1513,1518 ****
--- 1532,1540 ----
  					{ $$ = plpgsql_read_expression(K_LOOP, "LOOP"); }
  				;
  
+ expr_until_intosemi:			{ $$ = plpgsql_read_expression2(K_INTO, ';', "INTO/;"); }
+ 				;
+ 
  opt_label		:
  					{
  						plpgsql_ns_push(NULL);
***************
*** 1571,1576 ****
--- 1593,1605 ----
  	return read_sql_construct(until, 0, expected, "SELECT ", true, true, NULL);
  }
  
+ PLpgSQL_expr *
+ plpgsql_read_expression2(int until, int until2, const char *expected)
+ {
+ 	return read_sql_construct(until, until2, expected, "SELECT ", true, true, NULL);
+ }
+ 
+ 
  static PLpgSQL_expr *
  read_sql_stmt(const char *sqlstart)
  {
diff -c -r --new-file pgsql.old/src/pl/plpgsql/src/pl_exec.c pgsql.new/src/pl/plpgsql/src/pl_exec.c
*** pgsql.old/src/pl/plpgsql/src/pl_exec.c	2005-05-30 08:55:09.000000000 +0200
--- pgsql.new/src/pl/plpgsql/src/pl_exec.c	2005-06-01 10:38:40.000000000 +0200
***************
*** 2245,2250 ****
--- 2245,2257 ----
  	Oid			restype;
  	char	   *querystr;
  	int			exec_res;
+ 	PLpgSQL_rec *rec = NULL;
+ 	PLpgSQL_row *row = NULL;
+ 
+ 	if (stmt->rec != NULL)
+ 		rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->recno]);
+ 	else if (stmt->row != NULL)
+ 		row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
  
  	/*
  	 * First we evaluate the string expression after the EXECUTE keyword.
***************
*** 2267,2275 ****
--- 2274,2297 ----
  	 * results will be discarded.
  	 */
  	exec_res = SPI_execute(querystr, estate->readonly_func, 0);
+ 	if (exec_res != SPI_OK_SELECT && (rec || row))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 			 errmsg("EXECUTE ... INTO is only for SELECT")));
+ 	
  	switch (exec_res)
  	{
  		case SPI_OK_SELECT:
+ 		{
+ 			if (row || rec) 
+ 			{
+ 			    if (SPI_processed == 0)
+ 				exec_move_row(estate, rec, row, NULL, SPI_tuptable->tupdesc);
+ 			    else
+ 				exec_move_row(estate, rec, row, SPI_tuptable->vals[0], SPI_tuptable->tupdesc);
+ 			}
+ 			break;
+ 		}
  		case SPI_OK_INSERT:
  		case SPI_OK_UPDATE:
  		case SPI_OK_DELETE:
***************
*** 2339,2344 ****
--- 2361,2367 ----
  	estate->eval_processed = SPI_processed;
  	estate->eval_lastoid = SPI_lastoid;
  
+ 
  	return PLPGSQL_RC_OK;
  }
  
diff -c -r --new-file pgsql.old/src/pl/plpgsql/src/plpgsql.h pgsql.new/src/pl/plpgsql/src/plpgsql.h
*** pgsql.old/src/pl/plpgsql/src/plpgsql.h	2005-05-30 07:39:32.000000000 +0200
--- pgsql.new/src/pl/plpgsql/src/plpgsql.h	2005-06-01 08:35:20.000000000 +0200
***************
*** 524,529 ****
--- 524,531 ----
  {								/* Dynamic SQL string to execute */
  	int			cmd_type;
  	int			lineno;
+ 	PLpgSQL_rec *rec;
+ 	PLpgSQL_row *row;	    
  	PLpgSQL_expr *query;
  } PLpgSQL_stmt_dynexecute;
  
***************
*** 734,739 ****
--- 736,742 ----
   * ----------
   */
  extern PLpgSQL_expr *plpgsql_read_expression(int until, const char *expected);
+ extern PLpgSQL_expr *plpgsql_read_expression2(int until, int until2, const char *expected);
  extern int	plpgsql_yyparse(void);
  extern int	plpgsql_base_yylex(void);
  extern int	plpgsql_yylex(void);
