Allow ON UPDATE/DELETE SET DEFAULT plans to be cached.
Once upon a time, somebody was worried that cached RI plans wouldn't get remade with new default values after ALTER TABLE ... SET DEFAULT, so they didn't allow caching of plans for ON UPDATE/DELETE SET DEFAULT actions. That time is long gone, though (and even at the time I doubt this was the greatest hazard posed by ALTER TABLE...). So allow these triggers to cache their plans just like the others. The cache_plan argument to ri_PlanCheck is now vestigial, since there are no callers that don't pass "true"; but I left it alone in case there is any future need for it.
This commit is contained in:
parent
03a5ba24b0
commit
e8c9fd5fdf
|
@ -2155,12 +2155,12 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
|||
elog(ERROR, "SPI_connect failed");
|
||||
|
||||
/*
|
||||
* Prepare a plan for the set default delete operation.
|
||||
* Unfortunately we need to do it on every invocation because the
|
||||
* default value could potentially change between calls.
|
||||
* Fetch or prepare a saved plan for the set default delete
|
||||
* operation
|
||||
*/
|
||||
ri_BuildQueryKey(&qkey, &riinfo, RI_PLAN_SETDEFAULT_DEL_DOUPDATE);
|
||||
|
||||
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
|
||||
{
|
||||
StringInfoData querybuf;
|
||||
StringInfoData qualbuf;
|
||||
|
@ -2207,9 +2207,9 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
|||
}
|
||||
appendStringInfoString(&querybuf, qualbuf.data);
|
||||
|
||||
/* Prepare the plan, don't save it */
|
||||
/* Prepare and save the plan */
|
||||
qplan = ri_PlanCheck(querybuf.data, riinfo.nkeys, queryoids,
|
||||
&qkey, fk_rel, pk_rel, false);
|
||||
&qkey, fk_rel, pk_rel, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2239,7 +2239,7 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
|||
return PointerGetDatum(NULL);
|
||||
|
||||
/*
|
||||
* Handle MATCH PARTIAL set null delete.
|
||||
* Handle MATCH PARTIAL set default delete.
|
||||
*/
|
||||
case FKCONSTR_MATCH_PARTIAL:
|
||||
ereport(ERROR,
|
||||
|
@ -2348,12 +2348,12 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
|||
elog(ERROR, "SPI_connect failed");
|
||||
|
||||
/*
|
||||
* Prepare a plan for the set default delete operation.
|
||||
* Unfortunately we need to do it on every invocation because the
|
||||
* default value could potentially change between calls.
|
||||
* Fetch or prepare a saved plan for the set default update
|
||||
* operation
|
||||
*/
|
||||
ri_BuildQueryKey(&qkey, &riinfo, RI_PLAN_SETDEFAULT_UPD_DOUPDATE);
|
||||
|
||||
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
|
||||
{
|
||||
StringInfoData querybuf;
|
||||
StringInfoData qualbuf;
|
||||
|
@ -2400,9 +2400,9 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
|||
}
|
||||
appendStringInfoString(&querybuf, qualbuf.data);
|
||||
|
||||
/* Prepare the plan, don't save it */
|
||||
/* Prepare and save the plan */
|
||||
qplan = ri_PlanCheck(querybuf.data, riinfo.nkeys, queryoids,
|
||||
&qkey, fk_rel, pk_rel, false);
|
||||
&qkey, fk_rel, pk_rel, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2432,7 +2432,7 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
|||
return PointerGetDatum(NULL);
|
||||
|
||||
/*
|
||||
* Handle MATCH PARTIAL set null delete.
|
||||
* Handle MATCH PARTIAL set default update.
|
||||
*/
|
||||
case FKCONSTR_MATCH_PARTIAL:
|
||||
ereport(ERROR,
|
||||
|
|
|
@ -1319,3 +1319,39 @@ begin;
|
|||
(2 rows)
|
||||
|
||||
commit;
|
||||
--
|
||||
-- Test that SET DEFAULT actions recognize updates to default values
|
||||
--
|
||||
create temp table defp (f1 int primary key);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "defp_pkey" for table "defp"
|
||||
create temp table defc (f1 int default 0
|
||||
references defp on delete set default);
|
||||
insert into defp values (0), (1), (2);
|
||||
insert into defc values (2);
|
||||
select * from defc;
|
||||
f1
|
||||
----
|
||||
2
|
||||
(1 row)
|
||||
|
||||
delete from defp where f1 = 2;
|
||||
select * from defc;
|
||||
f1
|
||||
----
|
||||
0
|
||||
(1 row)
|
||||
|
||||
delete from defp where f1 = 0; -- fail
|
||||
ERROR: update or delete on table "defp" violates foreign key constraint "defc_f1_fkey" on table "defc"
|
||||
DETAIL: Key (f1)=(0) is still referenced from table "defc".
|
||||
alter table defc alter column f1 set default 1;
|
||||
delete from defp where f1 = 0;
|
||||
select * from defc;
|
||||
f1
|
||||
----
|
||||
1
|
||||
(1 row)
|
||||
|
||||
delete from defp where f1 = 1; -- fail
|
||||
ERROR: update or delete on table "defp" violates foreign key constraint "defc_f1_fkey" on table "defc"
|
||||
DETAIL: Key (f1)=(1) is still referenced from table "defc".
|
||||
|
|
|
@ -943,3 +943,20 @@ begin;
|
|||
update selfref set a = 456 where a = 123;
|
||||
select a, b from selfref;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Test that SET DEFAULT actions recognize updates to default values
|
||||
--
|
||||
create temp table defp (f1 int primary key);
|
||||
create temp table defc (f1 int default 0
|
||||
references defp on delete set default);
|
||||
insert into defp values (0), (1), (2);
|
||||
insert into defc values (2);
|
||||
select * from defc;
|
||||
delete from defp where f1 = 2;
|
||||
select * from defc;
|
||||
delete from defp where f1 = 0; -- fail
|
||||
alter table defc alter column f1 set default 1;
|
||||
delete from defp where f1 = 0;
|
||||
select * from defc;
|
||||
delete from defp where f1 = 1; -- fail
|
||||
|
|
Loading…
Reference in New Issue