Fix plpgsql so that when a local variable has no initial-value expression,
an error will be thrown correctly if the variable is of a NOT NULL domain. Report and almost-correct fix from Sergiy Vyshnevetskiy (bug #2948).
This commit is contained in:
parent
db047e571d
commit
6994d0b891
src
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.186 2007/01/30 18:02:22 tgl Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.187 2007/02/01 19:22:07 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -890,8 +890,27 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
|
|||||||
{
|
{
|
||||||
if (var->default_val == NULL)
|
if (var->default_val == NULL)
|
||||||
{
|
{
|
||||||
|
/* Initially it contains a NULL */
|
||||||
var->value = (Datum) 0;
|
var->value = (Datum) 0;
|
||||||
var->isnull = true;
|
var->isnull = true;
|
||||||
|
/*
|
||||||
|
* If needed, give the datatype a chance to reject
|
||||||
|
* NULLs, by assigning a NULL to the variable.
|
||||||
|
* We claim the value is of type UNKNOWN, not the
|
||||||
|
* var's datatype, else coercion will be skipped.
|
||||||
|
* (Do this before the notnull check to be
|
||||||
|
* consistent with exec_assign_value.)
|
||||||
|
*/
|
||||||
|
if (!var->datatype->typinput.fn_strict)
|
||||||
|
{
|
||||||
|
bool valIsNull = true;
|
||||||
|
|
||||||
|
exec_assign_value(estate,
|
||||||
|
(PLpgSQL_datum *) var,
|
||||||
|
(Datum) 0,
|
||||||
|
UNKNOWNOID,
|
||||||
|
&valIsNull);
|
||||||
|
}
|
||||||
if (var->notnull)
|
if (var->notnull)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||||
|
@ -382,6 +382,22 @@ ERROR: domain pos_int does not allow null values
|
|||||||
-- and local variables are enforced correctly.
|
-- and local variables are enforced correctly.
|
||||||
create function doubledecrement(p1 pos_int) returns pos_int as $$
|
create function doubledecrement(p1 pos_int) returns pos_int as $$
|
||||||
declare v pos_int;
|
declare v pos_int;
|
||||||
|
begin
|
||||||
|
return p1;
|
||||||
|
end$$ language plpgsql;
|
||||||
|
select doubledecrement(3); -- fail because of implicit null assignment
|
||||||
|
ERROR: domain pos_int does not allow null values
|
||||||
|
CONTEXT: PL/pgSQL function "doubledecrement" line 2 during statement block local variable initialization
|
||||||
|
create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
|
||||||
|
declare v pos_int := 0;
|
||||||
|
begin
|
||||||
|
return p1;
|
||||||
|
end$$ language plpgsql;
|
||||||
|
select doubledecrement(3); -- fail at initialization assignment
|
||||||
|
ERROR: value for domain pos_int violates check constraint "pos_int_check"
|
||||||
|
CONTEXT: PL/pgSQL function "doubledecrement" line 2 during statement block local variable initialization
|
||||||
|
create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
|
||||||
|
declare v pos_int := 1;
|
||||||
begin
|
begin
|
||||||
v := p1 - 1;
|
v := p1 - 1;
|
||||||
return v - 1;
|
return v - 1;
|
||||||
|
@ -309,6 +309,22 @@ execute s1(NULL); -- should fail
|
|||||||
|
|
||||||
create function doubledecrement(p1 pos_int) returns pos_int as $$
|
create function doubledecrement(p1 pos_int) returns pos_int as $$
|
||||||
declare v pos_int;
|
declare v pos_int;
|
||||||
|
begin
|
||||||
|
return p1;
|
||||||
|
end$$ language plpgsql;
|
||||||
|
|
||||||
|
select doubledecrement(3); -- fail because of implicit null assignment
|
||||||
|
|
||||||
|
create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
|
||||||
|
declare v pos_int := 0;
|
||||||
|
begin
|
||||||
|
return p1;
|
||||||
|
end$$ language plpgsql;
|
||||||
|
|
||||||
|
select doubledecrement(3); -- fail at initialization assignment
|
||||||
|
|
||||||
|
create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
|
||||||
|
declare v pos_int := 1;
|
||||||
begin
|
begin
|
||||||
v := p1 - 1;
|
v := p1 - 1;
|
||||||
return v - 1;
|
return v - 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user