Minor efficiency improvements in keeping track of trigger deferred

status.  In particular, I see no reason for deferredTriggerCheckState
to make an explicit entry to note that a particular trigger has its
default state --- that just clutters a list that should normally be
empty or very short.  I have plans to revise this module much more
heavily, but this is a simple separable improvement.
This commit is contained in:
Tom Lane 2004-09-08 23:47:58 +00:00
parent b1c4bdae74
commit f62901ca81

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.170 2004/09/07 21:48:30 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.171 2004/09/08 23:47:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1772,7 +1772,7 @@ static DeferredTriggerState DeferredTriggerStateAddItem(DeferredTriggerState sta
static bool static bool
deferredTriggerCheckState(Oid tgoid, int32 itemstate) deferredTriggerCheckState(Oid tgoid, int32 itemstate)
{ {
bool tgisdeferred; DeferredTriggerState state = deferredTriggers->state;
int i; int i;
/* /*
@ -1783,32 +1783,24 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
return false; return false;
/* /*
* Lookup if we know an individual state for this trigger * Check if SET CONSTRAINTS has been executed for this specific trigger.
*/ */
for (i = 0; i < deferredTriggers->state->numstates; i++) for (i = 0; i < state->numstates; i++)
{ {
if (deferredTriggers->state->trigstates[i].dts_tgoid == tgoid) if (state->trigstates[i].dts_tgoid == tgoid)
return deferredTriggers->state->trigstates[i].dts_tgisdeferred; return state->trigstates[i].dts_tgisdeferred;
} }
/* /*
* No individual state known - so if the user issued a SET CONSTRAINT * Check if SET CONSTRAINTS ALL has been executed; if so use that.
* ALL ..., we return that instead of the triggers default state.
*/ */
if (deferredTriggers->state->all_isset) if (state->all_isset)
return deferredTriggers->state->all_isdeferred; return state->all_isdeferred;
/* /*
* No ALL state known either, remember the default state as the * Otherwise return the default state for the trigger.
* current and return that. (XXX why do we bother making a state
* entry?)
*/ */
tgisdeferred = ((itemstate & TRIGGER_DEFERRED_INITDEFERRED) != 0); return ((itemstate & TRIGGER_DEFERRED_INITDEFERRED) != 0);
deferredTriggers->state =
DeferredTriggerStateAddItem(deferredTriggers->state,
tgoid, tgisdeferred);
return tgisdeferred;
} }
@ -2486,8 +2478,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
if (stmt->constraints == NIL) if (stmt->constraints == NIL)
{ {
/* /*
* Drop all per-transaction information about individual trigger * Forget any previous SET CONSTRAINTS commands in this transaction.
* states.
*/ */
deferredTriggers->state->numstates = 0; deferredTriggers->state->numstates = 0;
@ -2545,23 +2536,22 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
while (HeapTupleIsValid(htup = systable_getnext(tgscan))) while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
{ {
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup); Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
Oid constr_oid;
/* /*
* If we found some, check that they fit the deferrability * If we found some, check that they fit the deferrability
* but skip ON <event> RESTRICT ones, since they are * but skip ON <event> RESTRICT ones, since they are
* silently never deferrable. * silently never deferrable.
*/ */
if (stmt->deferred && !pg_trigger->tgdeferrable && if (pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL) pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL)
ereport(ERROR, {
(errcode(ERRCODE_WRONG_OBJECT_TYPE), if (stmt->deferred && !pg_trigger->tgdeferrable)
errmsg("constraint \"%s\" is not deferrable", ereport(ERROR,
cname))); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("constraint \"%s\" is not deferrable",
constr_oid = HeapTupleGetOid(htup); cname)));
oidlist = lappend_oid(oidlist, constr_oid); oidlist = lappend_oid(oidlist, HeapTupleGetOid(htup));
}
found = true; found = true;
} }
@ -2573,7 +2563,8 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
if (!found) if (!found)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("constraint \"%s\" does not exist", cname))); errmsg("constraint \"%s\" does not exist",
cname)));
} }
heap_close(tgrel, AccessShareLock); heap_close(tgrel, AccessShareLock);
@ -2584,14 +2575,15 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
foreach(l, oidlist) foreach(l, oidlist)
{ {
Oid tgoid = lfirst_oid(l); Oid tgoid = lfirst_oid(l);
DeferredTriggerState state = deferredTriggers->state;
bool found = false; bool found = false;
int i; int i;
for (i = 0; i < deferredTriggers->state->numstates; i++) for (i = 0; i < state->numstates; i++)
{ {
if (deferredTriggers->state->trigstates[i].dts_tgoid == tgoid) if (state->trigstates[i].dts_tgoid == tgoid)
{ {
deferredTriggers->state->trigstates[i].dts_tgisdeferred = stmt->deferred; state->trigstates[i].dts_tgisdeferred = stmt->deferred;
found = true; found = true;
break; break;
} }
@ -2599,8 +2591,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
if (!found) if (!found)
{ {
deferredTriggers->state = deferredTriggers->state =
DeferredTriggerStateAddItem(deferredTriggers->state, DeferredTriggerStateAddItem(state, tgoid, stmt->deferred);
tgoid, stmt->deferred);
} }
} }
} }