aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-02-01 19:22:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-02-01 19:22:07 +0000
commit6994d0b891949ac2c4a9cea01d4e8c8f289b8c79 (patch)
tree927bd04c838b9104cafa9cf2190e5a95ab219668 /src
parentdb047e571d746893682e4a33e789c045696da626 (diff)
downloadpostgresql-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.c21
-rw-r--r--src/test/regress/expected/domain.out16
-rw-r--r--src/test/regress/sql/domain.sql16
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;