diff -c -r --new-file pgsql.00/doc/src/sgml/plpgsql.sgml pgsql.001/doc/src/sgml/plpgsql.sgml
*** pgsql.00/doc/src/sgml/plpgsql.sgml	2005-06-06 15:29:00.000000000 +0200
--- pgsql.001/doc/src/sgml/plpgsql.sgml	2005-06-12 21:27:56.000000000 +0200
***************
*** 2515,2523 ****
     <para>
      Inside the format string, <literal>%</literal> is replaced by the
      next optional argument's string representation. Write
!     <literal>%%</literal> to emit a literal <literal>%</literal>. Note
!     that the optional arguments must presently be simple variables,
!     not expressions, and the format must be a simple string literal.
     </para>
  
     <!--
--- 2515,2523 ----
     <para>
      Inside the format string, <literal>%</literal> is replaced by the
      next optional argument's string representation. Write
!     <literal>%%</literal> to emit a literal <literal>%</literal>. 
!     Arguments can be simple variables or expressions, 
!     and the format must be a simple string literal.
     </para>
  
     <!--
diff -c -r --new-file pgsql.00/src/pl/plpgsql/src/gram.y pgsql.001/src/pl/plpgsql/src/gram.y
*** pgsql.00/src/pl/plpgsql/src/gram.y	2005-06-06 15:29:53.000000000 +0200
--- pgsql.001/src/pl/plpgsql/src/gram.y	2005-06-12 19:56:45.000000000 +0200
***************
*** 133,140 ****
  %type <exception>	proc_exception
  %type <condition>	proc_conditions
  
! %type <list>	raise_params
! %type <ival>	raise_level raise_param
  %type <str>		raise_msg
  
  %type <list>	getdiag_list
--- 133,140 ----
  %type <exception>	proc_exception
  %type <condition>	proc_conditions
  
! 
! %type <ival>	raise_level
  %type <str>		raise_msg
  
  %type <list>	getdiag_list
***************
*** 1155,1161 ****
  					}
  				;
  
! stmt_raise		: K_RAISE lno raise_level raise_msg raise_params ';'
  					{
  						PLpgSQL_stmt_raise		*new;
  
--- 1155,1161 ----
  					}
  				;
  
! stmt_raise		: K_RAISE lno raise_level raise_msg ',' expr_until_semi 
  					{
  						PLpgSQL_stmt_raise		*new;
  
***************
*** 1165,1171 ****
  						new->lineno		= $2;
  						new->elog_level = $3;
  						new->message	= $4;
! 						new->params		= $5;
  
  						$$ = (PLpgSQL_stmt *)new;
  					}
--- 1165,1171 ----
  						new->lineno		= $2;
  						new->elog_level = $3;
  						new->message	= $4;
! 						new->params_expr	= $6;
  
  						$$ = (PLpgSQL_stmt *)new;
  					}
***************
*** 1179,1185 ****
  						new->lineno		= $2;
  						new->elog_level = $3;
  						new->message	= $4;
! 						new->params		= NIL;
  
  						$$ = (PLpgSQL_stmt *)new;
  					}
--- 1179,1185 ----
  						new->lineno		= $2;
  						new->elog_level = $3;
  						new->message	= $4;
! 						new->params_expr = NULL;
  
  						$$ = (PLpgSQL_stmt *)new;
  					}
***************
*** 1217,1238 ****
  					}
  				;
  
- raise_params	: raise_params raise_param
- 					{
- 						$$ = lappend_int($1, $2);
- 					}
- 				| raise_param
- 					{
- 						$$ = list_make1_int($1);
- 					}
- 				;
- 
- raise_param		: ',' T_SCALAR
- 					{
- 						$$ = yylval.scalar->dno;
- 					}
- 				;
- 
  loop_body		: proc_sect K_END K_LOOP ';'
  					{ $$ = $1; }
  				;
--- 1217,1222 ----
diff -c -r --new-file pgsql.00/src/pl/plpgsql/src/pl_exec.c pgsql.001/src/pl/plpgsql/src/pl_exec.c
*** pgsql.00/src/pl/plpgsql/src/pl_exec.c	2005-06-06 15:29:53.000000000 +0200
--- pgsql.001/src/pl/plpgsql/src/pl_exec.c	2005-06-12 21:21:34.000000000 +0200
***************
*** 1892,1901 ****
  {
  	char	   *cp;
  	PLpgSQL_dstring ds;
! 	ListCell   *current_param;
  
  	plpgsql_dstring_init(&ds);
! 	current_param = list_head(stmt->params);
  
  	for (cp = stmt->message; *cp; cp++)
  	{
--- 1892,1931 ----
  {
  	char	   *cp;
  	PLpgSQL_dstring ds;
! 	int   param_idx = 0;
! 	int rc;
! 	int params_count = 0;
  
  	plpgsql_dstring_init(&ds);
! 
! 	if (stmt->params_expr)
! 	{
! 	    if (stmt->params_expr->plan == NULL)
! 		exec_prepare_plan(estate, stmt->params_expr);
! 	    rc = exec_run_select(estate, stmt->params_expr, 2, NULL);
! 	    if (rc != SPI_OK_SELECT)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
! 			       errmsg("query \"%s\" did not return data", stmt->params_expr->query)));
! 
! 	    if (estate->eval_processed == 0)
! 	    {
! 		    ereport(ERROR,
! 		    		(errcode(ERRCODE_WRONG_OBJECT_TYPE),
! 			   errmsg("query \"%s\" did not return data", stmt->params_expr->query)));
! 	    }
! 
! 	    /*
! 	    * Check that the expression returned one single Datum
! 	    */
! 	    if (estate->eval_processed > 1)
! 	    	    ereport(ERROR,
! 				(errcode(ERRCODE_CARDINALITY_VIOLATION),
! 				 errmsg("query \"%s\" returned more than one row",
! 						stmt->params_expr->query)));
! 
! 	    params_count = estate->eval_tuptable->tupdesc->natts;
! 	}
  
  	for (cp = stmt->message; *cp; cp++)
  	{
***************
*** 1917,1947 ****
  				continue;
  			}
  
! 			if (current_param == NULL)
  				ereport(ERROR,
  						(errcode(ERRCODE_SYNTAX_ERROR),
  						 errmsg("too few parameters specified for RAISE")));
  
! 			exec_eval_datum(estate, estate->datums[lfirst_int(current_param)],
! 							InvalidOid,
! 							&paramtypeid, &paramvalue, &paramisnull);
  			if (paramisnull)
  				extval = "<NULL>";
  			else
  				extval = convert_value_to_string(paramvalue, paramtypeid);
  			plpgsql_dstring_append(&ds, extval);
! 			current_param = lnext(current_param);
  			continue;
  		}
  
  		plpgsql_dstring_append_char(&ds, cp[0]);
  	}
  
  	/*
  	 * If more parameters were specified than were required to process
  	 * the format string, throw an error
  	 */
! 	if (current_param != NULL)
  		ereport(ERROR,
  				(errcode(ERRCODE_SYNTAX_ERROR),
  				 errmsg("too many parameters specified for RAISE")));
--- 1947,1980 ----
  				continue;
  			}
  
! 			if (param_idx == params_count)
  				ereport(ERROR,
  						(errcode(ERRCODE_SYNTAX_ERROR),
  						 errmsg("too few parameters specified for RAISE")));
  
! 			paramvalue = SPI_getbinval(estate->eval_tuptable->vals[0], 
! 						   estate->eval_tuptable->tupdesc, param_idx+1, &paramisnull);
! 			paramtypeid = SPI_gettypeid(estate->eval_tuptable->tupdesc, param_idx+1);
! 
  			if (paramisnull)
  				extval = "<NULL>";
  			else
  				extval = convert_value_to_string(paramvalue, paramtypeid);
  			plpgsql_dstring_append(&ds, extval);
! 			param_idx++;
  			continue;
  		}
  
  		plpgsql_dstring_append_char(&ds, cp[0]);
  	}
  
+ 	exec_eval_cleanup(estate);
+ 
  	/*
  	 * If more parameters were specified than were required to process
  	 * the format string, throw an error
  	 */
! 	if (param_idx != params_count)
  		ereport(ERROR,
  				(errcode(ERRCODE_SYNTAX_ERROR),
  				 errmsg("too many parameters specified for RAISE")));
diff -c -r --new-file pgsql.00/src/pl/plpgsql/src/pl_funcs.c pgsql.001/src/pl/plpgsql/src/pl_funcs.c
*** pgsql.00/src/pl/plpgsql/src/pl_funcs.c	2005-06-06 15:29:53.000000000 +0200
--- pgsql.001/src/pl/plpgsql/src/pl_funcs.c	2005-06-12 21:10:11.000000000 +0200
***************
*** 883,894 ****
  static void
  dump_raise(PLpgSQL_stmt_raise *stmt)
  {
- 	ListCell *l;
  
  	dump_ind();
  	printf("RAISE '%s'", stmt->message);
! 	foreach (l, stmt->params)
! 		printf(" %d", lfirst_int(l));
  	printf("\n");
  }
  
--- 883,892 ----
  static void
  dump_raise(PLpgSQL_stmt_raise *stmt)
  {
  
  	dump_ind();
  	printf("RAISE '%s'", stmt->message);
! 	dump_expr(stmt->params_expr);
  	printf("\n");
  }
  
diff -c -r --new-file pgsql.00/src/pl/plpgsql/src/plpgsql.h pgsql.001/src/pl/plpgsql/src/plpgsql.h
*** pgsql.00/src/pl/plpgsql/src/plpgsql.h	2005-06-06 15:29:53.000000000 +0200
--- pgsql.001/src/pl/plpgsql/src/plpgsql.h	2005-06-12 19:52:13.000000000 +0200
***************
*** 508,514 ****
  	int			lineno;
  	int			elog_level;
  	char	   *message;
! 	List	   *params;
  } PLpgSQL_stmt_raise;
  
  
--- 508,514 ----
  	int			lineno;
  	int			elog_level;
  	char	   *message;
! 	PLpgSQL_expr  *params_expr;
  } PLpgSQL_stmt_raise;
  
  
diff -c -r --new-file pgsql.00/src/test/regress/expected/plpgsql.out pgsql.001/src/test/regress/expected/plpgsql.out
*** pgsql.00/src/test/regress/expected/plpgsql.out	2005-06-06 15:30:06.000000000 +0200
--- pgsql.001/src/test/regress/expected/plpgsql.out	2005-06-12 21:39:31.000000000 +0200
***************
*** 2380,2382 ****
--- 2380,2398 ----
  CONTEXT:  PL/pgSQL function "missing_return_expr"
  drop function void_return_expr();
  drop function missing_return_expr();
+ -- parameters of raise stmt can be expressions
+ create function raise_exprs() returns void as $$
+ declare a integer[] = '{10,20,30}'; c varchar; i integer;
+ begin i := 2;
+   raise notice '>>>%<<< >>>%<<< % % %', a, a[i], c, (select 1), row(10,'aaa',30);
+ end;$$ language plpgsql;
+ ERROR:  function "raise_exprs" already exists with same argument types
+ select raise_exprs();
+ NOTICE:  >>>{10,20,30}<<< >>>20<<< <NULL> 1 (10,aaa,30)
+  raise_exprs 
+ -------------
+  
+ (1 row)
+ 
+ drop function raise_exprs();
+ DROP FUNCTION
diff -c -r --new-file pgsql.00/src/test/regress/sql/plpgsql.sql pgsql.001/src/test/regress/sql/plpgsql.sql
*** pgsql.00/src/test/regress/sql/plpgsql.sql	2005-06-06 15:30:03.000000000 +0200
--- pgsql.001/src/test/regress/sql/plpgsql.sql	2005-06-12 21:40:10.000000000 +0200
***************
*** 2018,2020 ****
--- 2018,2032 ----
  
  drop function void_return_expr();
  drop function missing_return_expr();
+ 
+ -- parameters of raise stmt can be expressions
+ create function raise_exprs() returns void as $$
+ declare a integer[] = '{10,20,30}'; c varchar; i integer;
+ begin i := 2;
+   raise notice '>>>%<<< >>>%<<< % % %', a, a[i], c, (select 1), row(10,'aaa',30);
+ end;$$ language plpgsql;
+ 
+ select raise_exprs();
+ 
+ drop function raise_exprs();
+ 
