mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 21:51:19 +02:00
Apply RI trigger skipping tests also for DELETE
The tests added in cfa0f4255b
to skip
firing an RI trigger if any old key value is NULL can also be applied
for DELETE. This should give a performance gain in those cases, and it
also saves a lot of duplicate code in the actual RI triggers. (That
code was already dead code for the UPDATE cases.)
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
This commit is contained in:
parent
34479d9a36
commit
69ee2ff930
@ -5950,12 +5950,12 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
|
||||
* certain cases where we can skip queueing the event because we can
|
||||
* tell by inspection that the FK constraint will still pass.
|
||||
*/
|
||||
if (TRIGGER_FIRED_BY_UPDATE(event))
|
||||
if (TRIGGER_FIRED_BY_UPDATE(event) || TRIGGER_FIRED_BY_DELETE(event))
|
||||
{
|
||||
switch (RI_FKey_trigger_type(trigger->tgfoid))
|
||||
{
|
||||
case RI_TRIGGER_PK:
|
||||
/* Update on trigger's PK table */
|
||||
/* Update or delete on trigger's PK table */
|
||||
if (!RI_FKey_pk_upd_check_required(trigger, rel,
|
||||
oldtup, newtup))
|
||||
{
|
||||
|
@ -724,25 +724,6 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
|
||||
*/
|
||||
case FKCONSTR_MATCH_SIMPLE:
|
||||
case FKCONSTR_MATCH_FULL:
|
||||
switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true))
|
||||
{
|
||||
case RI_KEYS_ALL_NULL:
|
||||
case RI_KEYS_SOME_NULL:
|
||||
|
||||
/*
|
||||
* No check needed - there cannot be any reference to old
|
||||
* key if it contains a NULL
|
||||
*/
|
||||
heap_close(fk_rel, RowShareLock);
|
||||
return PointerGetDatum(NULL);
|
||||
|
||||
case RI_KEYS_NONE_NULL:
|
||||
|
||||
/*
|
||||
* Have a full qualified key - continue below
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If another PK row now exists providing the old key values, we
|
||||
@ -900,26 +881,6 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
case FKCONSTR_MATCH_SIMPLE:
|
||||
case FKCONSTR_MATCH_FULL:
|
||||
switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true))
|
||||
{
|
||||
case RI_KEYS_ALL_NULL:
|
||||
case RI_KEYS_SOME_NULL:
|
||||
|
||||
/*
|
||||
* No check needed - there cannot be any reference to old
|
||||
* key if it contains a NULL
|
||||
*/
|
||||
heap_close(fk_rel, RowExclusiveLock);
|
||||
return PointerGetDatum(NULL);
|
||||
|
||||
case RI_KEYS_NONE_NULL:
|
||||
|
||||
/*
|
||||
* Have a full qualified key - continue below
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPI_connect() != SPI_OK_CONNECT)
|
||||
elog(ERROR, "SPI_connect failed");
|
||||
|
||||
@ -1064,26 +1025,6 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
case FKCONSTR_MATCH_SIMPLE:
|
||||
case FKCONSTR_MATCH_FULL:
|
||||
switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true))
|
||||
{
|
||||
case RI_KEYS_ALL_NULL:
|
||||
case RI_KEYS_SOME_NULL:
|
||||
|
||||
/*
|
||||
* No check needed - there cannot be any reference to old
|
||||
* key if it contains a NULL
|
||||
*/
|
||||
heap_close(fk_rel, RowExclusiveLock);
|
||||
return PointerGetDatum(NULL);
|
||||
|
||||
case RI_KEYS_NONE_NULL:
|
||||
|
||||
/*
|
||||
* Have a full qualified key - continue below
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPI_connect() != SPI_OK_CONNECT)
|
||||
elog(ERROR, "SPI_connect failed");
|
||||
|
||||
@ -1273,26 +1214,6 @@ ri_setnull(TriggerData *trigdata)
|
||||
*/
|
||||
case FKCONSTR_MATCH_SIMPLE:
|
||||
case FKCONSTR_MATCH_FULL:
|
||||
switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true))
|
||||
{
|
||||
case RI_KEYS_ALL_NULL:
|
||||
case RI_KEYS_SOME_NULL:
|
||||
|
||||
/*
|
||||
* No check needed - there cannot be any reference to old
|
||||
* key if it contains a NULL
|
||||
*/
|
||||
heap_close(fk_rel, RowExclusiveLock);
|
||||
return PointerGetDatum(NULL);
|
||||
|
||||
case RI_KEYS_NONE_NULL:
|
||||
|
||||
/*
|
||||
* Have a full qualified key - continue below
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPI_connect() != SPI_OK_CONNECT)
|
||||
elog(ERROR, "SPI_connect failed");
|
||||
|
||||
@ -1479,26 +1400,6 @@ ri_setdefault(TriggerData *trigdata)
|
||||
*/
|
||||
case FKCONSTR_MATCH_SIMPLE:
|
||||
case FKCONSTR_MATCH_FULL:
|
||||
switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true))
|
||||
{
|
||||
case RI_KEYS_ALL_NULL:
|
||||
case RI_KEYS_SOME_NULL:
|
||||
|
||||
/*
|
||||
* No check needed - there cannot be any reference to old
|
||||
* key if it contains a NULL
|
||||
*/
|
||||
heap_close(fk_rel, RowExclusiveLock);
|
||||
return PointerGetDatum(NULL);
|
||||
|
||||
case RI_KEYS_NONE_NULL:
|
||||
|
||||
/*
|
||||
* Have a full qualified key - continue below
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPI_connect() != SPI_OK_CONNECT)
|
||||
elog(ERROR, "SPI_connect failed");
|
||||
|
||||
@ -1617,11 +1518,13 @@ ri_setdefault(TriggerData *trigdata)
|
||||
/* ----------
|
||||
* RI_FKey_pk_upd_check_required -
|
||||
*
|
||||
* Check if we really need to fire the RI trigger for an update to a PK
|
||||
* Check if we really need to fire the RI trigger for an update or delete to a PK
|
||||
* relation. This is called by the AFTER trigger queue manager to see if
|
||||
* it can skip queuing an instance of an RI trigger. Returns true if the
|
||||
* trigger must be fired, false if we can prove the constraint will still
|
||||
* be satisfied.
|
||||
*
|
||||
* new_row will be NULL if this is called for a delete.
|
||||
* ----------
|
||||
*/
|
||||
bool
|
||||
@ -1648,7 +1551,7 @@ RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel,
|
||||
return false;
|
||||
|
||||
/* If all old and new key values are equal, no check is needed */
|
||||
if (ri_KeysEqual(pk_rel, old_row, new_row, riinfo, true))
|
||||
if (new_row && ri_KeysEqual(pk_rel, old_row, new_row, riinfo, true))
|
||||
return false;
|
||||
|
||||
/* Else we need to fire the trigger. */
|
||||
|
Loading…
Reference in New Issue
Block a user