Hello,
I did trivial patch which eliminate limit raise command. Using
expressions instead of variables are a little bit expensive, but little.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
pokus=# create or replace function x() returns void as $$
declare c integer[] = '{10,20,30}'; a integer = 3;b record;
begin b := row(1,2);
raise notice 'sss % % % % % % % % %', interval '23 hour',
1, current_user, c,now(), c[1],
(select * from fx where 1 = 0 limit 1),
null,current_timestamp::timestamp(0);
end; $$ language plpgsql;
CREATE FUNCTION
pokus=# select x();
NOTICE: sss 23:00:00 1 root {10,20,30} 2005-06-13 07:06:07.43569+02 10
<NULL> <NULL> 2005-06-13 07:
06:07
Regards
Pavel Stehule
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,
! ¶mtypeid,
¶mvalue, ¶misnull);
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, ¶misnull);
! 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();
+
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]