Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
connoinherit may be true only for CHECK constraints
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 20 Jul 2012 16:33:34 +0000 (12:33 -0400)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 20 Jul 2012 18:07:09 +0000 (14:07 -0400)
The code was setting it true for other constraints, which is
bogus.  Doing so caused bogus catalog entries for such constraints, and
in particular caused an error to be raised when trying to drop a
constraint of types other than CHECK from a table that has children,
such as reported in bug #6712.

In 9.2, additionally ignore connoinherit=true for other constraint
types, to avoid having to force initdb; existing databases might already
contain bogus catalog entries.

Includes a catversion bump (in HEAD only).

Bug report from Miroslav Ć ulc
Analysis from Amit Kapila and Noah Misch; Amit also contributed the patch.

src/backend/catalog/index.c
src/backend/commands/tablecmds.c
src/backend/commands/trigger.c
src/test/regress/expected/inherit.out
src/test/regress/sql/inherit.sql

index 9e8b1cc49bc0cbd4d94e3cc4fa802ca59395a68b..339f27840f8a8948fa600730b9792663fe55bb07 100644 (file)
@@ -1156,7 +1156,7 @@ index_constraint_create(Relation heapRelation,
                                   NULL,
                                   true,        /* islocal */
                                   0,   /* inhcount */
-                                  false);      /* noinherit */
+                                  true);       /* noinherit */
 
    /*
     * Register the index as internally dependent on the constraint.
index 70e408cb6ea1fc6a80b943f22d3a91d226226bb8..6ff08a29cc15bcd99af86dc701c7dcb49b678af3 100644 (file)
@@ -6039,7 +6039,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
                                      NULL,
                                      true,     /* islocal */
                                      0,        /* inhcount */
-                                     false);   /* isnoinherit */
+                                     true);    /* isnoinherit */
 
    /*
     * Create the triggers that will enforce the constraint.
@@ -6947,6 +6947,16 @@ ATExecDropConstraint(Relation rel, const char *constrName,
 
        is_no_inherit_constraint = con->connoinherit;
 
+       /*
+        * XXX as a special hack, we turn on no-inherit here unconditionally
+        * except for CHECK constraints.  This is because 9.2 until beta2
+        * contained a bug that marked it false for all constraints, even
+        * though it was only supported false for CHECK constraints.
+        * See bug #6712.
+        */
+       if (con->contype != CONSTRAINT_CHECK)
+           is_no_inherit_constraint = true;
+
        /*
         * Perform the actual constraint deletion
         */
index 4399a274465cf4a5e653604bdd8ea92b83ee1937..70721a272d071225b7bfeba47b3840450f8e2b35 100644 (file)
@@ -459,7 +459,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
                                              NULL,
                                              true,     /* islocal */
                                              0,        /* inhcount */
-                                             false);   /* isnoinherit */
+                                             true);    /* isnoinherit */
    }
 
    /*
index 6613fea84ac9604a939405de173e38b4227775a1..d1c2eec9d08198659d7e9084b1302f765c0e5dbf 100644 (file)
@@ -970,6 +970,126 @@ DETAIL:  drop cascades to table inht2
 drop cascades to table inhts
 drop cascades to table inht3
 drop cascades to table inht4
+-- Test non-inheritable indices [UNIQUE, EXCLUDE] contraints
+CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE(val1, val2));
+NOTICE:  CREATE TABLE / UNIQUE will create implicit index "test_constraints_val1_val2_key" for table "test_constraints"
+CREATE TABLE test_constraints_inh () INHERITS (test_constraints);
+\d+ test_constraints
+                        Table "public.test_constraints"
+ Column |       Type        | Modifiers | Storage  | Stats target | Description 
+--------+-------------------+-----------+----------+--------------+-------------
+ id     | integer           |           | plain    |              | 
+ val1   | character varying |           | extended |              | 
+ val2   | integer           |           | plain    |              | 
+Indexes:
+    "test_constraints_val1_val2_key" UNIQUE CONSTRAINT, btree (val1, val2)
+Child tables: test_constraints_inh
+Has OIDs: no
+
+ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key;
+\d+ test_constraints
+                        Table "public.test_constraints"
+ Column |       Type        | Modifiers | Storage  | Stats target | Description 
+--------+-------------------+-----------+----------+--------------+-------------
+ id     | integer           |           | plain    |              | 
+ val1   | character varying |           | extended |              | 
+ val2   | integer           |           | plain    |              | 
+Child tables: test_constraints_inh
+Has OIDs: no
+
+\d+ test_constraints_inh
+                      Table "public.test_constraints_inh"
+ Column |       Type        | Modifiers | Storage  | Stats target | Description 
+--------+-------------------+-----------+----------+--------------+-------------
+ id     | integer           |           | plain    |              | 
+ val1   | character varying |           | extended |              | 
+ val2   | integer           |           | plain    |              | 
+Inherits: test_constraints
+Has OIDs: no
+
+DROP TABLE test_constraints_inh;
+DROP TABLE test_constraints;
+CREATE TABLE circles (
+    c circle,
+    EXCLUDE USING gist (c WITH &&)
+);
+NOTICE:  CREATE TABLE / EXCLUDE will create implicit index "circles_c_excl" for table "circles"
+CREATE TABLE circles_inh () INHERITS (circles);
+\d+ circles
+                       Table "public.circles"
+ Column |  Type  | Modifiers | Storage | Stats target | Description 
+--------+--------+-----------+---------+--------------+-------------
+ c      | circle |           | plain   |              | 
+Indexes:
+    "circles_c_excl" EXCLUDE USING gist (c WITH &&)
+Child tables: circles_inh
+Has OIDs: no
+
+ALTER TABLE circles DROP CONSTRAINT circles_c_excl;
+\d+ circles
+                       Table "public.circles"
+ Column |  Type  | Modifiers | Storage | Stats target | Description 
+--------+--------+-----------+---------+--------------+-------------
+ c      | circle |           | plain   |              | 
+Child tables: circles_inh
+Has OIDs: no
+
+\d+ circles_inh
+                     Table "public.circles_inh"
+ Column |  Type  | Modifiers | Storage | Stats target | Description 
+--------+--------+-----------+---------+--------------+-------------
+ c      | circle |           | plain   |              | 
+Inherits: circles
+Has OIDs: no
+
+DROP TABLE circles_inh;
+DROP TABLE circles;
+-- Test non-inheritable foreign key contraints
+CREATE TABLE test_primary_constraints(id int PRIMARY KEY);
+NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "test_primary_constraints_pkey" for table "test_primary_constraints"
+CREATE TABLE test_foreign_constraints(id1 int REFERENCES test_primary_constraints(id));
+CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints);
+\d+ test_primary_constraints
+               Table "public.test_primary_constraints"
+ Column |  Type   | Modifiers | Storage | Stats target | Description 
+--------+---------+-----------+---------+--------------+-------------
+ id     | integer | not null  | plain   |              | 
+Indexes:
+    "test_primary_constraints_pkey" PRIMARY KEY, btree (id)
+Referenced by:
+    TABLE "test_foreign_constraints" CONSTRAINT "test_foreign_constraints_id1_fkey" FOREIGN KEY (id1) REFERENCES test_primary_constraints(id)
+Has OIDs: no
+
+\d+ test_foreign_constraints
+               Table "public.test_foreign_constraints"
+ Column |  Type   | Modifiers | Storage | Stats target | Description 
+--------+---------+-----------+---------+--------------+-------------
+ id1    | integer |           | plain   |              | 
+Foreign-key constraints:
+    "test_foreign_constraints_id1_fkey" FOREIGN KEY (id1) REFERENCES test_primary_constraints(id)
+Child tables: test_foreign_constraints_inh
+Has OIDs: no
+
+ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey;
+\d+ test_foreign_constraints
+               Table "public.test_foreign_constraints"
+ Column |  Type   | Modifiers | Storage | Stats target | Description 
+--------+---------+-----------+---------+--------------+-------------
+ id1    | integer |           | plain   |              | 
+Child tables: test_foreign_constraints_inh
+Has OIDs: no
+
+\d+ test_foreign_constraints_inh
+             Table "public.test_foreign_constraints_inh"
+ Column |  Type   | Modifiers | Storage | Stats target | Description 
+--------+---------+-----------+---------+--------------+-------------
+ id1    | integer |           | plain   |              | 
+Inherits: test_foreign_constraints
+Has OIDs: no
+
+DROP TABLE test_foreign_constraints_inh;
+DROP TABLE test_foreign_constraints;
+DROP TABLE test_primary_constraints;
 --
 -- Test parameterized append plans for inheritance trees
 --
index 6e6921aa9cda0332e1bb9ebad132ebfe5f2047c5..5f607603252af530e33d34789cd59b5d9442d078 100644 (file)
@@ -291,6 +291,42 @@ SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected
 
 DROP TABLE inht1, inhs1 CASCADE;
 
+
+-- Test non-inheritable indices [UNIQUE, EXCLUDE] contraints
+CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE(val1, val2));
+CREATE TABLE test_constraints_inh () INHERITS (test_constraints);
+\d+ test_constraints
+ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key;
+\d+ test_constraints
+\d+ test_constraints_inh
+DROP TABLE test_constraints_inh;
+DROP TABLE test_constraints;
+
+CREATE TABLE circles (
+    c circle,
+    EXCLUDE USING gist (c WITH &&)
+);
+CREATE TABLE circles_inh () INHERITS (circles);
+\d+ circles
+ALTER TABLE circles DROP CONSTRAINT circles_c_excl;
+\d+ circles
+\d+ circles_inh
+DROP TABLE circles_inh;
+DROP TABLE circles;
+
+-- Test non-inheritable foreign key contraints
+CREATE TABLE test_primary_constraints(id int PRIMARY KEY);
+CREATE TABLE test_foreign_constraints(id1 int REFERENCES test_primary_constraints(id));
+CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints);
+\d+ test_primary_constraints
+\d+ test_foreign_constraints
+ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey;
+\d+ test_foreign_constraints
+\d+ test_foreign_constraints_inh
+DROP TABLE test_foreign_constraints_inh;
+DROP TABLE test_foreign_constraints;
+DROP TABLE test_primary_constraints;
+
 --
 -- Test parameterized append plans for inheritance trees
 --