Skip to content

Commit 674877e

Browse files
committed
Need to do SPI_push/SPI_pop around expression evaluation in plpgsql.
We must do this in case the expression evaluation results in calling another plpgsql function (or, really, anything using SPI). I missed the need for this when I converted exec_cast_value() from doing a simple InputFunctionCall() to doing ExecEvalExpr() in commit 1345cc6. There is a SPI_push_conditional in InputFunctionCall(), so that there was no bug before that. Per bug #14414 from Marcos Castedo. Add a regression test based on his example, which was that a plpgsql function in a domain check constraint didn't work when assigning to a domain-type variable within plpgsql. Report: <20161106010947.1387.66380@wrigleys.postgresql.org>
1 parent 6e377ef commit 674877e

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

src/pl/plpgsql/src/pl_exec.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6015,6 +6015,8 @@ exec_cast_value(PLpgSQL_execstate *estate,
60156015
ExprContext *econtext = estate->eval_econtext;
60166016
MemoryContext oldcontext;
60176017

6018+
SPI_push();
6019+
60186020
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
60196021

60206022
econtext->caseValue_datum = value;
@@ -6028,6 +6030,8 @@ exec_cast_value(PLpgSQL_execstate *estate,
60286030
cast_entry->cast_in_use = false;
60296031

60306032
MemoryContextSwitchTo(oldcontext);
6033+
6034+
SPI_pop();
60316035
}
60326036
}
60336037

src/test/regress/expected/plpgsql.out

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5611,3 +5611,22 @@ end;
56115611
$$;
56125612
ERROR: unhandled assertion
56135613
CONTEXT: PL/pgSQL function inline_code_block line 3 at ASSERT
5614+
-- Test use of plpgsql in a domain check constraint (cf. bug #14414)
5615+
create function plpgsql_domain_check(val int) returns boolean as $$
5616+
begin return val > 0; end
5617+
$$ language plpgsql immutable;
5618+
create domain plpgsql_domain as integer check(plpgsql_domain_check(value));
5619+
do $$
5620+
declare v_test plpgsql_domain;
5621+
begin
5622+
v_test := 1;
5623+
end;
5624+
$$;
5625+
do $$
5626+
declare v_test plpgsql_domain := 1;
5627+
begin
5628+
v_test := 0; -- fail
5629+
end;
5630+
$$;
5631+
ERROR: value for domain plpgsql_domain violates check constraint "plpgsql_domain_check"
5632+
CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment

src/test/regress/sql/plpgsql.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4390,3 +4390,25 @@ exception when others then
43904390
null; -- do nothing
43914391
end;
43924392
$$;
4393+
4394+
-- Test use of plpgsql in a domain check constraint (cf. bug #14414)
4395+
4396+
create function plpgsql_domain_check(val int) returns boolean as $$
4397+
begin return val > 0; end
4398+
$$ language plpgsql immutable;
4399+
4400+
create domain plpgsql_domain as integer check(plpgsql_domain_check(value));
4401+
4402+
do $$
4403+
declare v_test plpgsql_domain;
4404+
begin
4405+
v_test := 1;
4406+
end;
4407+
$$;
4408+
4409+
do $$
4410+
declare v_test plpgsql_domain := 1;
4411+
begin
4412+
v_test := 0; -- fail
4413+
end;
4414+
$$;

0 commit comments

Comments
 (0)