diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-02-01 19:22:07 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-02-01 19:22:07 +0000 |
commit | 6994d0b891949ac2c4a9cea01d4e8c8f289b8c79 (patch) | |
tree | 927bd04c838b9104cafa9cf2190e5a95ab219668 /src | |
parent | db047e571d746893682e4a33e789c045696da626 (diff) | |
download | postgresql-6994d0b891949ac2c4a9cea01d4e8c8f289b8c79.tar.gz postgresql-6994d0b891949ac2c4a9cea01d4e8c8f289b8c79.zip |
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).
Diffstat (limited to 'src')
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 21 | ||||
-rw-r--r-- | src/test/regress/expected/domain.out | 16 | ||||
-rw-r--r-- | src/test/regress/sql/domain.sql | 16 |
3 files changed, 52 insertions, 1 deletions
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 8a9c0093c5b..cc5eb733534 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8,7 +8,7 @@ * * * 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) { + /* Initially it contains a NULL */ var->value = (Datum) 0; 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) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index c4cad728b3a..4acaaa4121c 100644 --- a/src/test/regress/expected/domain.out +++ b/src/test/regress/expected/domain.out @@ -383,6 +383,22 @@ ERROR: domain pos_int does not allow null values create function doubledecrement(p1 pos_int) returns pos_int as $$ 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 v := p1 - 1; return v - 1; end$$ language plpgsql; diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index 21940e0e618..411d64648a6 100644 --- a/src/test/regress/sql/domain.sql +++ b/src/test/regress/sql/domain.sql @@ -310,6 +310,22 @@ execute s1(NULL); -- should fail create function doubledecrement(p1 pos_int) returns pos_int as $$ 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 v := p1 - 1; return v - 1; end$$ language plpgsql; |