pk_rel = heap_open(riinfo.pk_relid, RowShareLock);
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 2) a):
+ * SQL:2008 4.17.3 <Table constraints>
* If Rf and Rt are empty (no columns to compare given)
* constraint is true if 0 < (SELECT COUNT(*) FROM T)
*
* Note: The special case that no columns are given cannot
- * occur up to now in Postgres, it's just there for
- * future enhancements.
+ * occur at present in Postgres (and is disallowed by the
+ * standard too); it's just there for future enhancements.
* ----------
*/
if (riinfo.nkeys == 0)
case RI_KEYS_ALL_NULL:
/*
- * No check - if NULLs are allowed at all is already checked by
- * NOT NULL constraint.
- *
- * This is true for MATCH FULL, MATCH PARTIAL, and MATCH SIMPLE.
+ * No further check needed - an all-NULL key passes every type of
+ * foreign key constraint.
*/
heap_close(pk_rel, RowShareLock);
return PointerGetDatum(NULL);
case FKCONSTR_MATCH_SIMPLE:
/*
- * MATCH SIMPLE - if ANY column is null, we have a match.
+ * MATCH SIMPLE - if ANY column is null, the key passes
+ * the constraint.
*/
heap_close(pk_rel, RowShareLock);
return PointerGetDatum(NULL);
case FKCONSTR_MATCH_SIMPLE:
/*
- * MATCH SIMPLE/FULL - if ANY column is null, we
- * can't be matching to this row already.
+ * MATCH SIMPLE/FULL - if ANY column is null, nothing
+ * could have been referencing this row.
*/
return true;
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 6) a) iv):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 9) a) iv):
* MATCH SIMPLE/FULL
- * ... ON DELETE CASCADE
+ * ... ON DELETE NO ACTION
* ----------
*/
case FKCONSTR_MATCH_SIMPLE:
case RI_KEYS_SOME_NULL:
/*
- * No check - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 6) a) iv):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 10) a) iv):
* MATCH SIMPLE/FULL
- * ... ON DELETE CASCADE
+ * ... ON UPDATE NO ACTION
* ----------
*/
case FKCONSTR_MATCH_SIMPLE:
case RI_KEYS_SOME_NULL:
/*
- * No check - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 6) a) i):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 9) a) i):
* MATCH SIMPLE/FULL
* ... ON DELETE CASCADE
* ----------
case RI_KEYS_SOME_NULL:
/*
- * No check - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
/* ----------
* RI_FKey_cascade_upd -
*
- * Cascaded update/delete foreign key references at update event on PK table.
+ * Cascaded update foreign key references at update event on PK table.
* ----------
*/
Datum
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 7) a) i):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 10) a) i):
* MATCH SIMPLE/FULL
* ... ON UPDATE CASCADE
* ----------
case RI_KEYS_SOME_NULL:
/*
- * No update - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
*
* Restrict delete from PK table to rows unreferenced by foreign key.
*
- * SQL3 intends that this referential action occur BEFORE the
- * update is performed, rather than after. This appears to be
- * the only difference between "NO ACTION" and "RESTRICT".
- *
- * For now, however, we treat "RESTRICT" and "NO ACTION" as
- * equivalent.
+ * The SQL standard intends that this referential action occur BEFORE
+ * the delete is performed, rather than after. This appears to be
+ * the only difference between "NO ACTION" and "RESTRICT". In Postgres
+ * we still implement this as an AFTER trigger, but it's non-deferrable.
* ----------
*/
Datum
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 6) a) iv):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 9) a) iv):
* MATCH SIMPLE/FULL
- * ... ON DELETE CASCADE
+ * ... ON DELETE RESTRICT
* ----------
*/
case FKCONSTR_MATCH_SIMPLE:
case RI_KEYS_SOME_NULL:
/*
- * No check - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
*
* Restrict update of PK to rows unreferenced by foreign key.
*
- * SQL3 intends that this referential action occur BEFORE the
- * update is performed, rather than after. This appears to be
- * the only difference between "NO ACTION" and "RESTRICT".
- *
- * For now, however, we treat "RESTRICT" and "NO ACTION" as
- * equivalent.
+ * The SQL standard intends that this referential action occur BEFORE
+ * the update is performed, rather than after. This appears to be
+ * the only difference between "NO ACTION" and "RESTRICT". In Postgres
+ * we still implement this as an AFTER trigger, but it's non-deferrable.
* ----------
*/
Datum
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 6) a) iv):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 10) a) iv):
* MATCH SIMPLE/FULL
- * ... ON DELETE CASCADE
+ * ... ON UPDATE RESTRICT
* ----------
*/
case FKCONSTR_MATCH_SIMPLE:
case RI_KEYS_SOME_NULL:
/*
- * No check - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 6) a) ii):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 9) a) ii):
* MATCH SIMPLE/FULL
* ... ON DELETE SET NULL
* ----------
case RI_KEYS_SOME_NULL:
/*
- * No update - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 7) a) ii) 2):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 10) a) ii):
* MATCH SIMPLE/FULL
* ... ON UPDATE SET NULL
* ----------
case RI_KEYS_SOME_NULL:
/*
- * No update - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 6) a) iii):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 9) a) iii):
* MATCH SIMPLE/FULL
* ... ON DELETE SET DEFAULT
* ----------
case RI_KEYS_SOME_NULL:
/*
- * No update - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);
switch (riinfo.confmatchtype)
{
/* ----------
- * SQL3 11.9 <referential constraint definition>
- * General rules 7) a) iii):
+ * SQL:2008 15.17 <Execution of referential actions>
+ * General rules 10) a) iii):
* MATCH SIMPLE/FULL
* ... ON UPDATE SET DEFAULT
* ----------
case RI_KEYS_SOME_NULL:
/*
- * No update - MATCH FULL means there cannot be any
- * reference to old key if it contains 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);