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]