SELECT * FROM test_assign_booltrue(false, true);
ERROR: value for domain booltrue violates check constraint "booltrue_check"
-CONTEXT: PL/pgSQL function test_assign_booltrue(boolean,boolean) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function test_assign_booltrue(boolean,boolean) line 2 during statement block local variable initialization
SELECT * FROM test_assign_booltrue(true, false);
ERROR: value for domain booltrue violates check constraint "booltrue_check"
CONTEXT: PL/pgSQL function test_assign_booltrue(boolean,boolean) line 4 at assignment
CONTEXT: PL/pgSQL function test_assign_uint2(integer,integer) line 4 at assignment
SELECT * FROM test_assign_uint2(-100, 50);
ERROR: value for domain uint2 violates check constraint "uint2_check"
-CONTEXT: PL/pgSQL function test_assign_uint2(integer,integer) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function test_assign_uint2(integer,integer) line 2 during statement block local variable initialization
SELECT * FROM test_assign_uint2(null, 1);
test_assign_uint2
-------------------
SELECT * FROM test_assign_nnint(null, 20);
ERROR: domain nnint does not allow null values
-CONTEXT: PL/pgSQL function test_assign_nnint(integer,integer) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function test_assign_nnint(integer,integer) line 2 during statement block local variable initialization
SELECT * FROM test_assign_nnint(10, null);
ERROR: domain nnint does not allow null values
CONTEXT: PL/pgSQL function test_assign_nnint(integer,integer) line 4 at assignment
CONTEXT: PL/pgSQL function test_assign_ordered_pair_domain(integer,integer,integer) line 4 at assignment
SELECT * FROM test_assign_ordered_pair_domain(2,1,3);
ERROR: value for domain ordered_pair_domain violates check constraint "ordered_pair_domain_check"
-CONTEXT: PL/pgSQL function test_assign_ordered_pair_domain(integer,integer,integer) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function test_assign_ordered_pair_domain(integer,integer,integer) line 2 during statement block local variable initialization
--
-- Arrays of domains
--
CONTEXT: PL/pgSQL function test_assign_nnint_container(integer,integer,integer) line 4 at assignment
SELECT * FROM test_assign_nnint_container(1,null,3);
ERROR: domain nnint does not allow null values
-CONTEXT: PL/pgSQL function test_assign_nnint_container(integer,integer,integer) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function test_assign_nnint_container(integer,integer,integer) line 2 during statement block local variable initialization
-- Since core system allows this:
SELECT null::nnint_container;
nnint_container
CONTEXT: PL/pgSQL function test_assign_ordered_named_pair(integer,integer,integer) line 4 at assignment
SELECT * FROM test_assign_ordered_named_pair(2,1,3);
ERROR: value for domain ordered_named_pair violates check constraint "ordered_named_pair_check"
-CONTEXT: PL/pgSQL function test_assign_ordered_named_pair(integer,integer,integer) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function test_assign_ordered_named_pair(integer,integer,integer) line 2 during statement block local variable initialization
CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$
begin
return array[row(i, j), row(i, j+1)];
SELECT * FROM test_assign_ordered_named_pairs(2,1,3);
ERROR: value for domain ordered_named_pair violates check constraint "ordered_named_pair_check"
-CONTEXT: PL/pgSQL function test_assign_ordered_named_pairs(integer,integer,integer) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function test_assign_ordered_named_pairs(integer,integer,integer) line 2 during statement block local variable initialization
SELECT * FROM test_assign_ordered_named_pairs(1,2,0); -- should fail someday
test_assign_ordered_named_pairs
---------------------------------
end$$;
ERROR: division by zero
CONTEXT: SQL expression "1/0"
-PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x bigint[] := array[1,3,5];
begin
raise notice 'x = %', x;
end$$;
ERROR: null value cannot be assigned to variable "x" declared NOT NULL
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x record not null; -- fail
begin
raise notice 'x = %', x;
end$$;
ERROR: null value cannot be assigned to variable "x" declared NOT NULL
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x var_record not null; -- fail
begin
raise notice 'x = %', x;
end$$;
ERROR: null value cannot be assigned to variable "x" declared NOT NULL
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
-- Check that variables are reinitialized on block re-entry.
do $$
begin
raise notice 'x = %', x;
end$$;
ERROR: domain int_nn does not allow null values
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x int_nn := null; -- fail
begin
raise notice 'x = %', x;
end$$;
ERROR: domain int_nn does not allow null values
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x int_nn := 42;
begin
raise notice 'x = %', x;
end$$;
ERROR: domain var_record_nn does not allow null values
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x var_record_nn := null; -- fail
begin
raise notice 'x = %', x;
end$$;
ERROR: domain var_record_nn does not allow null values
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x var_record_nn := row(1,2);
begin
raise notice 'x = %', x;
end$$;
ERROR: value for domain var_record_colnn violates check constraint "var_record_colnn_check"
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x var_record_colnn := null; -- fail
begin
raise notice 'x = %', x;
end$$;
ERROR: value for domain var_record_colnn violates check constraint "var_record_colnn_check"
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x var_record_colnn := row(1,null); -- fail
begin
raise notice 'x = %', x;
end$$;
ERROR: value for domain var_record_colnn violates check constraint "var_record_colnn_check"
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x var_record_colnn := row(1,2);
begin
plpgsql_exec_error_callback(void *arg)
{
PLpgSQL_execstate *estate = (PLpgSQL_execstate *) arg;
+ int err_lineno;
+
+ /*
+ * If err_var is set, report the variable's declaration line number.
+ * Otherwise, if err_stmt is set, report the err_stmt's line number. When
+ * err_stmt is not set, we're in function entry/exit, or some such place
+ * not attached to a specific line number.
+ */
+ if (estate->err_var != NULL)
+ err_lineno = estate->err_var->lineno;
+ else if (estate->err_stmt != NULL)
+ err_lineno = estate->err_stmt->lineno;
+ else
+ err_lineno = 0;
if (estate->err_text != NULL)
{
* actually need it. Therefore, places that set up err_text should
* use gettext_noop() to ensure the strings get recorded in the
* message dictionary.
- *
- * If both err_text and err_stmt are set, use the err_text as
- * description, but report the err_stmt's line number. When err_stmt
- * is not set, we're in function entry/exit, or some such place not
- * attached to a specific line number.
*/
- if (estate->err_stmt != NULL)
+ if (err_lineno > 0)
{
/*
* translator: last %s is a phrase such as "during statement block
*/
errcontext("PL/pgSQL function %s line %d %s",
estate->func->fn_signature,
- estate->err_stmt->lineno,
+ err_lineno,
_(estate->err_text));
}
else
_(estate->err_text));
}
}
- else if (estate->err_stmt != NULL)
+ else if (estate->err_stmt != NULL && err_lineno > 0)
{
/* translator: last %s is a plpgsql statement type name */
errcontext("PL/pgSQL function %s line %d at %s",
estate->func->fn_signature,
- estate->err_stmt->lineno,
+ err_lineno,
plpgsql_stmt_typename(estate->err_stmt));
}
else
* Note that we currently don't support promise datums within blocks,
* only at a function's outermost scope, so we needn't handle those
* here.
+ *
+ * Since RECFIELD isn't a supported case either, it's okay to cast the
+ * PLpgSQL_datum to PLpgSQL_variable.
*/
+ estate->err_var = (PLpgSQL_variable *) datum;
+
switch (datum->dtype)
{
case PLPGSQL_DTYPE_VAR:
}
}
+ estate->err_var = NULL;
+
if (block->exceptions)
{
/*
estate->eval_econtext = NULL;
estate->err_stmt = NULL;
+ estate->err_var = NULL;
estate->err_text = NULL;
estate->plugin_info = NULL;
/* status information for error context reporting */
PLpgSQL_stmt *err_stmt; /* current stmt */
+ PLpgSQL_variable *err_var; /* current variable, if in a DECLARE section */
const char *err_text; /* additional state info */
void *plugin_info; /* reserved for use by optional plugin */
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(pos_int) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function doubledecrement(pos_int) 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
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(pos_int) line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function doubledecrement(pos_int) 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
LINE 1: x + 1
^
QUERY: x + 1
-CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare y int := x + 1; -- error
x int := 42;
LINE 1: x + 1
^
QUERY: x + 1
-CONTEXT: PL/pgSQL function inline_code_block line 4 during statement block local variable initialization
+CONTEXT: PL/pgSQL function inline_code_block line 2 during statement block local variable initialization
do $$
declare x int := 42;
y int := x + 1;