Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc1008f0

Browse files
committed
Check number of parameters in RAISE statement at compile time.
The number of % parameter markers in RAISE statement should match the numberof parameters given. We used to check that at execution time, but we haveall the information needed at compile time, so let's check it at compiletime instead. It's generally better to find mistakes earlier.Marko Tiikkaja, reviewed by Fabien Coelho
1 parentf8f4227 commitc1008f0

File tree

5 files changed

+68
-17
lines changed

5 files changed

+68
-17
lines changed

‎doc/src/sgml/plpgsql.sgml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3403,6 +3403,9 @@ RAISE ;
34033403
Inside the format string, <literal>%</literal> is replaced by the
34043404
string representation of the next optional argument's value. Write
34053405
<literal>%%</literal> to emit a literal <literal>%</literal>.
3406+
The number of arguments must match the number of <literal>%</>
3407+
placeholders in the format string, or an error is raised during
3408+
the compilation of the function.
34063409
</para>
34073410

34083411
<para>

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,10 +2939,9 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
29392939
continue;
29402940
}
29412941

2942+
/* should have been checked at compile time */
29422943
if (current_param==NULL)
2943-
ereport(ERROR,
2944-
(errcode(ERRCODE_SYNTAX_ERROR),
2945-
errmsg("too few parameters specified for RAISE")));
2944+
elog(ERROR,"unexpected RAISE parameter list length");
29462945

29472946
paramvalue=exec_eval_expr(estate,
29482947
(PLpgSQL_expr*)lfirst(current_param),
@@ -2963,14 +2962,9 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
29632962
appendStringInfoChar(&ds,cp[0]);
29642963
}
29652964

2966-
/*
2967-
* If more parameters were specified than were required to process the
2968-
* format string, throw an error
2969-
*/
2965+
/* should have been checked at compile time */
29702966
if (current_param!=NULL)
2971-
ereport(ERROR,
2972-
(errcode(ERRCODE_SYNTAX_ERROR),
2973-
errmsg("too many parameters specified for RAISE")));
2967+
elog(ERROR,"unexpected RAISE parameter list length");
29742968

29752969
err_message=ds.data;
29762970
/* No pfree(ds.data), the pfree(err_message) does it */

‎src/pl/plpgsql/src/pl_gram.y

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ staticvoid check_labels(const char *start_label,
106106
staticPLpgSQL_expr*read_cursor_args(PLpgSQL_var *cursor,
107107
int until,constchar *expected);
108108
staticList*read_raise_options(void);
109+
staticvoidcheck_raise_parameters(PLpgSQL_stmt_raise *stmt);
109110

110111
%}
111112

@@ -1849,6 +1850,8 @@ stmt_raise: K_RAISE
18491850
new->options =read_raise_options();
18501851
}
18511852

1853+
check_raise_parameters(new);
1854+
18521855
$$ = (PLpgSQL_stmt *)new;
18531856
}
18541857
;
@@ -3767,6 +3770,41 @@ read_raise_options(void)
37673770
return result;
37683771
}
37693772

3773+
/*
3774+
* Check that the number of parameter placeholders in the message matches the
3775+
* number of parameters passed to it, if a message was given.
3776+
*/
3777+
static void
3778+
check_raise_parameters(PLpgSQL_stmt_raise *stmt)
3779+
{
3780+
char *cp;
3781+
intexpected_nparams = 0;
3782+
3783+
if (stmt->message == NULL)
3784+
return;
3785+
3786+
for (cp = stmt->message; *cp; cp++)
3787+
{
3788+
if (cp[0] == '%')
3789+
{
3790+
/* ignore literal % characters*/
3791+
if (cp[1] == '%')
3792+
cp++;
3793+
else
3794+
expected_nparams++;
3795+
}
3796+
}
3797+
3798+
if (expected_nparams < list_length(stmt->params))
3799+
ereport(ERROR,
3800+
(errcode(ERRCODE_SYNTAX_ERROR),
3801+
errmsg("too many parameters specified for RAISE")));
3802+
if (expected_nparams > list_length(stmt->params))
3803+
ereport(ERROR,
3804+
(errcode(ERRCODE_SYNTAX_ERROR),
3805+
errmsg("too few parameters specified for RAISE")));
3806+
}
3807+
37703808
/*
37713809
* Fix up CASE statement
37723810
*/

‎src/test/regress/expected/plpgsql.out

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2446,18 +2446,29 @@ begin
24462446
return $1;
24472447
end;
24482448
$$ language plpgsql;
2449-
select raise_test1(5);
24502449
ERROR: too many parameters specified for RAISE
2451-
CONTEXT: PL/pgSQL function raise_test1(integer)line 3 at RAISE
2450+
CONTEXT:compilation ofPL/pgSQL function"raise_test1" nearline 3
24522451
create function raise_test2(int) returns int as $$
24532452
begin
24542453
raise notice 'This message has too few parameters: %, %, %', $1, $1;
24552454
return $1;
24562455
end;
24572456
$$ language plpgsql;
2458-
select raise_test2(10);
24592457
ERROR: too few parameters specified for RAISE
2460-
CONTEXT: PL/pgSQL function raise_test2(integer) line 3 at RAISE
2458+
CONTEXT: compilation of PL/pgSQL function "raise_test2" near line 3
2459+
create function raise_test3(int) returns int as $$
2460+
begin
2461+
raise notice 'This message has no parameters (despite having %% signs in it)!';
2462+
return $1;
2463+
end;
2464+
$$ language plpgsql;
2465+
select raise_test3(1);
2466+
NOTICE: This message has no parameters (despite having % signs in it)!
2467+
raise_test3
2468+
-------------
2469+
1
2470+
(1 row)
2471+
24612472
-- Test re-RAISE inside a nested exception block. This case is allowed
24622473
-- by Oracle's PL/SQL but was handled differently by PG before 9.1.
24632474
CREATE FUNCTION reraise_test() RETURNS void AS $$

‎src/test/regress/sql/plpgsql.sql

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,16 +2078,21 @@ begin
20782078
end;
20792079
$$ language plpgsql;
20802080

2081-
select raise_test1(5);
2082-
20832081
createfunctionraise_test2(int) returnsintas $$
20842082
begin
20852083
raise notice'This message has too few parameters: %, %, %', $1, $1;
20862084
return $1;
20872085
end;
20882086
$$ language plpgsql;
20892087

2090-
select raise_test2(10);
2088+
createfunctionraise_test3(int) returnsintas $$
2089+
begin
2090+
raise notice'This message has no parameters (despite having %% signs in it)!';
2091+
return $1;
2092+
end;
2093+
$$ language plpgsql;
2094+
2095+
select raise_test3(1);
20912096

20922097
-- Test re-RAISE inside a nested exception block. This case is allowed
20932098
-- by Oracle's PL/SQL but was handled differently by PG before 9.1.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp