Index: doc/src/sgml/ddl.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/ddl.sgml,v retrieving revision 1.30 diff -c -r1.30 ddl.sgml *** doc/src/sgml/ddl.sgml 8 Aug 2004 21:33:11 -0000 1.30 --- doc/src/sgml/ddl.sgml 5 Oct 2004 14:39:27 -0000 *************** *** 940,949 **** Restricting and cascading deletes are the two most common options. ! RESTRICT can also be written as NO ! ACTION and it's also the default if you do not specify ! anything. There are two other options for what should happen with ! the foreign key columns when a primary key is deleted: SET NULL and SET DEFAULT. Note that these do not excuse you from observing any constraints. For example, if an action specifies SET DEFAULT --- 940,951 ---- Restricting and cascading deletes are the two most common options. ! RESTRICT prevents a statement from deleting a ! referenced row. NO ACTION means that if at the ! constraint check time, any referencing rows still exist, an error ! is raised and is the default if you do not specify anything. ! There are two other options for what should happen with the foreign ! key columns when a primary key is deleted: SET NULL and SET DEFAULT. Note that these do not excuse you from observing any constraints. For example, if an action specifies SET DEFAULT Index: doc/src/sgml/ref/create_table.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/ref/create_table.sgml,v retrieving revision 1.84 diff -c -r1.84 create_table.sgml *** doc/src/sgml/ref/create_table.sgml 2 Aug 2004 04:25:31 -0000 1.84 --- doc/src/sgml/ref/create_table.sgml 5 Oct 2004 14:39:29 -0000 *************** *** 452,458 **** clause specifies the action to perform when a referenced column in the referenced table is being updated to a new value. If the row is updated, but the referenced column is not actually ! changed, no action is done. There are the following possible actions for each clause: --- 452,460 ---- clause specifies the action to perform when a referenced column in the referenced table is being updated to a new value. If the row is updated, but the referenced column is not actually ! changed, no action is done. Referential actions apart from the ! check of NO ACTION can not be deferred even if ! the constraint is deferrable. There are the following possible actions for each clause: *************** *** 460,468 **** NO ACTION ! Produce an error indicating that the deletion or update ! would create a foreign key constraint violation. This is ! the default action. --- 462,471 ---- NO ACTION ! Produce an error that the deletion or update would create a ! foreign key violation. If the constraint is deferred, this ! error will be produced at constraint check time if there still ! exist any referencing rows. This is the default action. *************** *** 471,479 **** RESTRICT ! Same as NO ACTION except that this action ! will not be deferred even if the rest of the constraint is ! deferrable and deferred. --- 474,481 ---- RESTRICT ! Produce an error that the deletion or update would create a ! foreign key constraint violation. Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/commands/tablecmds.c,v retrieving revision 1.133 diff -c -r1.133 tablecmds.c *** src/backend/commands/tablecmds.c 23 Sep 2004 23:20:24 -0000 1.133 --- src/backend/commands/tablecmds.c 5 Oct 2004 14:39:34 -0000 *************** *** 4357,4368 **** fk_trigger->actions[1] = '\0'; fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; fk_trigger->constrrel = myRel; switch (fkconstraint->fk_del_action) { case FKCONSTR_ACTION_NOACTION: fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del"); break; case FKCONSTR_ACTION_RESTRICT: --- 4357,4368 ---- fk_trigger->actions[1] = '\0'; fk_trigger->isconstraint = true; fk_trigger->constrrel = myRel; switch (fkconstraint->fk_del_action) { case FKCONSTR_ACTION_NOACTION: + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del"); break; case FKCONSTR_ACTION_RESTRICT: *************** *** 4371,4382 **** --- 4371,4388 ---- fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del"); break; case FKCONSTR_ACTION_CASCADE: + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del"); break; case FKCONSTR_ACTION_SETNULL: + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del"); break; case FKCONSTR_ACTION_SETDEFAULT: + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del"); break; default: *************** *** 4421,4432 **** fk_trigger->actions[0] = 'u'; fk_trigger->actions[1] = '\0'; fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; fk_trigger->constrrel = myRel; switch (fkconstraint->fk_upd_action) { case FKCONSTR_ACTION_NOACTION: fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd"); break; case FKCONSTR_ACTION_RESTRICT: --- 4427,4438 ---- fk_trigger->actions[0] = 'u'; fk_trigger->actions[1] = '\0'; fk_trigger->isconstraint = true; fk_trigger->constrrel = myRel; switch (fkconstraint->fk_upd_action) { case FKCONSTR_ACTION_NOACTION: + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd"); break; case FKCONSTR_ACTION_RESTRICT: *************** *** 4435,4446 **** --- 4441,4458 ---- fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd"); break; case FKCONSTR_ACTION_CASCADE: + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd"); break; case FKCONSTR_ACTION_SETNULL: + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd"); break; case FKCONSTR_ACTION_SETDEFAULT: + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd"); break; default: Index: src/backend/commands/trigger.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/commands/trigger.c,v retrieving revision 1.172 diff -c -r1.172 trigger.c *** src/backend/commands/trigger.c 10 Sep 2004 18:39:56 -0000 1.172 --- src/backend/commands/trigger.c 5 Oct 2004 14:39:37 -0000 *************** *** 2729,2739 **** /* * If we found some, check that they fit the deferrability ! * but skip ON RESTRICT ones, since they are * silently never deferrable. */ if (pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD && ! pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL) { if (stmt->deferred && !pg_trigger->tgdeferrable) ereport(ERROR, --- 2729,2745 ---- /* * If we found some, check that they fit the deferrability ! * but skip referential action ones, since they are * silently never deferrable. */ if (pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD && ! pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL && ! pg_trigger->tgfoid != F_RI_FKEY_CASCADE_UPD && ! pg_trigger->tgfoid != F_RI_FKEY_CASCADE_DEL && ! pg_trigger->tgfoid != F_RI_FKEY_SETNULL_UPD && ! pg_trigger->tgfoid != F_RI_FKEY_SETNULL_DEL && ! pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_UPD && ! pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_DEL) { if (stmt->deferred && !pg_trigger->tgdeferrable) ereport(ERROR,