From 9a915e596f38a97f10e00d388f18e178136937eb Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 17 Jan 2010 22:56:23 +0000 Subject: Improve the handling of SET CONSTRAINTS commands by having them search pg_constraint before searching pg_trigger. This allows saner handling of corner cases; in particular we now say "constraint is not deferrable" rather than "constraint does not exist" when the command is applied to a constraint that's inherently non-deferrable. Per a gripe several months ago from hubert depesz lubaczewski. To make this work without breaking user-defined constraint triggers, we have to add entries for them to pg_constraint. However, in return we can remove the pgconstrname column from pg_constraint, which represents a fairly sizable space savings. I also replaced the tgisconstraint column with tgisinternal; the old meaning of tgisconstraint can now be had by testing for nonzero tgconstraint, while there is no other way to get the old meaning of nonzero tgconstraint, namely that the trigger was internally generated rather than being user-created. In passing, fix an old misstatement in the docs and comments, namely that pg_trigger.tgdeferrable is exactly redundant with pg_constraint.condeferrable. Actually, we mark RI action triggers as nondeferrable even when they belong to a nominally deferrable FK constraint. The SET CONSTRAINTS code now relies on that instead of hard-coding a list of exception OIDs. --- doc/src/sgml/catalogs.sgml | 38 +++++++++++++++++++------------------- doc/src/sgml/trigger.sgml | 4 ++-- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index ca90cd56caf..f917652a085 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,4 +1,4 @@ - + @@ -1721,6 +1721,11 @@ catalog, not here. + + User-defined constraint triggers (created with CREATE CONSTRAINT + TRIGGER) also give rise to an entry in this table. + + Check constraints on domains are stored here, too. @@ -1764,6 +1769,7 @@ f = foreign key constraint, p = primary key constraint, u = unique constraint, + t = constraint trigger, x = exclusion constraint @@ -1873,7 +1879,8 @@ conkey int2[] pg_attribute.attnum - If a table constraint (including a foreign key), list of the constrained columns + If a table constraint (including foreign keys, but not constraint + triggers), list of the constrained columns @@ -4826,17 +4833,11 @@ - tgisconstraint + tgisinternal bool - True if trigger is a constraint trigger - - - - tgconstrname - name - - Constraint name, if a constraint trigger + True if trigger is internally generated (usually, to enforce + the constraint identified by tgconstraint) @@ -4857,7 +4858,7 @@ tgconstraint oid pg_constraint.oid - The pg_constraint entry owning the trigger, if any + The pg_constraint entry associated with the trigger, if any @@ -4919,13 +4920,12 @@ When tgconstraint is nonzero, - tgisconstraint must be true, and - tgconstrname, tgconstrrelid, - tgconstrindid, - tgdeferrable, tginitdeferred are redundant - with the referenced pg_constraint entry. The reason we - keep these fields is that we support stand-alone constraint - triggers with no corresponding pg_constraint entry. + tgconstrrelid, tgconstrindid, + tgdeferrable, and tginitdeferred are + largely redundant with the referenced pg_constraint entry. + However, it is possible for a non-deferrable trigger to be associated + with a deferrable constraint: foreign key constraints can have some + deferrable and some non-deferrable triggers. diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml index 49571ca7c5c..5418f314a31 100644 --- a/doc/src/sgml/trigger.sgml +++ b/doc/src/sgml/trigger.sgml @@ -1,4 +1,4 @@ - + Triggers @@ -506,7 +506,7 @@ typedef struct Trigger Oid tgfoid; int16 tgtype; bool tgenabled; - bool tgisconstraint; + bool tgisinternal; Oid tgconstrrelid; Oid tgconstrindid; Oid tgconstraint; -- cgit v1.2.3