Make CREATE TABLE ... INHERITS() to correctly create explicit not null constraints.
authorBernd Helmle <[email protected]>
Wed, 27 Apr 2011 20:33:27 +0000 (22:33 +0200)
committerBernd Helmle <[email protected]>
Wed, 27 Apr 2011 20:33:27 +0000 (22:33 +0200)
Also adjust regression tests to include the referenced key of the constraint,
but not its output for debugging purposes.

src/backend/commands/tablecmds.c
src/test/regress/sql/inherit.sql

index 29b539e1851b527cb3a41fdb99bc446a88ab7e88..bc9772708cc92e1361b957eb18455f7486663f77 100644 (file)
@@ -263,7 +263,7 @@ static const struct dropmsgstrings dropmsgstringarray[] = {
 
 static void truncate_check_rel(Relation rel);
 static List *MergeAttributes(List *schema, List *supers, char relpersistence,
-                               List **supOids, List **supconstr, int *supOidCount);
+                                                        List **supOids, List **supconstr, int *supOidCount);
 static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
 static bool change_varattnos_walker(Node *node, const AttrNumber *newattno);
 static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel,
@@ -591,9 +591,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
                if (colDef->is_not_null)
                {
                        /*
-                        * Check list of NOT NULL constraints for the current
-                        * column name. There should only one Constraint node, so
-                        * we give up immediately when we've found a constraint.
+                        * Check list of explicit defined NOT NULL constraints for the
+                        * current column name. There should be only one Constraint node,
+                        * so we give up immediately when we've found a constraint.
                         */
 
                        ListCell *nnconstrptr;
@@ -614,8 +614,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
                                cooked->contype = CONSTR_NOTNULL;
                                cooked->attnum = attnum;
                                cooked->expr = NULL;
-                               cooked->is_local = colDef->is_local;
-                               cooked->inhcount = colDef->inhcount;
+                               cooked->is_local = true;
+                               cooked->inhcount = 0;
                                nnconstraints    = lappend(nnconstraints, cooked);
 
                                /*
@@ -1834,7 +1834,33 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
 
                                /* Mark the column as locally defined */
                                def->is_local = true;
+
                                /* Merge of NOT NULL constraints = OR 'em together */
+                               if (!def->is_not_null && newdef->is_not_null)
+                               {
+                                       ListCell *constrCell;
+
+                                       /*
+                                        * There must be a locally defined Constraint node attached
+                                        * to this column definition. We need to inject it to the
+                                        * list of constraints, at least to keep a possible
+                                        * assigned constraint name. We do this by adding the
+                                        * Constraint node to the column's own list of constraints.
+                                        * Such constraints are treated as locally defined and will
+                                        * be handled later when the target table get's created.
+                                        */
+                                       foreach (constrCell, newdef->constraints)
+                                       {
+                                               Constraint *newnnconstr = lfirst(constrCell);
+                                               if (newnnconstr->contype == CONSTR_NOTNULL)
+                                               {
+                                                       def->constraints = lappend(def->constraints,
+                                                                                                          newnnconstr);
+                                                       break;
+                                               }
+                                       }
+                               }
+
                                def->is_not_null |= newdef->is_not_null;
                                /* If new def has a default, override previous default */
                                if (newdef->raw_default != NULL)
@@ -9444,7 +9470,6 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode)
                                attributeTuple,
                        constraintTuple;
        List       *constraints;
-       List       *connames;
        bool            found = false;
 
        /*
index 4c143621308cca393619f324f4b6ea68197087f5..d501196ac3216a32198a78da7d94ca731bf022ba 100644 (file)
@@ -518,7 +518,7 @@ create table parent2(f2 text);
 create table child(f1 int not null, f2 text not null) inherits(parent1, parent2);
 
 -- show constraint info
-select conrelid::regclass, conname, contype, coninhcount, conislocal from pg_constraint where contype = 'n' order by 2;
+select conrelid::regclass, conname, contype, coninhcount, conislocal, conkey from pg_constraint where contype = 'n' order by 2;
 
 -- also drops child table
 drop table parent1 cascade;