Index: src/backend/catalog/heap.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/catalog/heap.c,v
retrieving revision 1.332
diff -c -r1.332 heap.c
*** src/backend/catalog/heap.c	27 Mar 2008 03:57:33 -0000	1.332
--- src/backend/catalog/heap.c	1 Apr 2008 07:32:15 -0000
***************
*** 77,83 ****
  				   char new_rel_kind,
  				   Oid new_array_type);
  static void RelationRemoveInheritance(Oid relid);
! static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
  static void StoreConstraints(Relation rel, TupleDesc tupdesc);
  static void SetRelationNumChecks(Relation rel, int numchecks);
  static List *insert_ordered_unique_oid(List *list, Oid datum);
--- 77,83 ----
  				   char new_rel_kind,
  				   Oid new_array_type);
  static void RelationRemoveInheritance(Oid relid);
! static void StoreRelCheck(Relation rel, char *ccname, char *ccbin, const bool is_local, const int inhcount);
  static void StoreConstraints(Relation rel, TupleDesc tupdesc);
  static void SetRelationNumChecks(Relation rel, int numchecks);
  static List *insert_ordered_unique_oid(List *list, Oid datum);
***************
*** 1531,1537 ****
   * in the pg_class entry for the relation.
   */
  static void
! StoreRelCheck(Relation rel, char *ccname, char *ccbin)
  {
  	Node	   *expr;
  	char	   *ccsrc;
--- 1531,1537 ----
   * in the pg_class entry for the relation.
   */
  static void
! StoreRelCheck(Relation rel, char *ccname, char *ccbin, const bool is_local, const int inhcount)
  {
  	Node	   *expr;
  	char	   *ccsrc;
***************
*** 1608,1614 ****
  						  InvalidOid,	/* no associated index */
  						  expr, /* Tree form check constraint */
  						  ccbin,	/* Binary form check constraint */
! 						  ccsrc);		/* Source form check constraint */
  
  	pfree(ccsrc);
  }
--- 1608,1616 ----
  						  InvalidOid,	/* no associated index */
  						  expr, /* Tree form check constraint */
  						  ccbin,	/* Binary form check constraint */
! 						  ccsrc, /* Source form check constraint */
! 						  is_local, /* islocal */
! 						  inhcount); /* coninhcount */
  
  	pfree(ccsrc);
  }
***************
*** 1643,1649 ****
  
  	for (i = 0; i < constr->num_check; i++)
  		StoreRelCheck(rel, constr->check[i].ccname,
! 					  constr->check[i].ccbin);
  
  	if (constr->num_check > 0)
  		SetRelationNumChecks(rel, constr->num_check);
--- 1645,1653 ----
  
  	for (i = 0; i < constr->num_check; i++)
  		StoreRelCheck(rel, constr->check[i].ccname,
! 					  constr->check[i].ccbin,
! 					  constr->check[i].is_local,
! 					  constr->check[i].inhcount);
  
  	if (constr->num_check > 0)
  		SetRelationNumChecks(rel, constr->num_check);
***************
*** 1863,1869 ****
  		/*
  		 * OK, store it.
  		 */
! 		StoreRelCheck(rel, ccname, nodeToString(expr));
  
  		numchecks++;
  
--- 1867,1873 ----
  		/*
  		 * OK, store it.
  		 */
! 		StoreRelCheck(rel, ccname, nodeToString(expr), cdef->is_local, cdef->inhcount);
  
  		numchecks++;
  
Index: src/backend/catalog/index.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/catalog/index.c,v
retrieving revision 1.296
diff -c -r1.296 index.c
*** src/backend/catalog/index.c	26 Mar 2008 21:10:37 -0000	1.296
--- src/backend/catalog/index.c	1 Apr 2008 07:32:15 -0000
***************
*** 716,722 ****
  										   InvalidOid,	/* no associated index */
  										   NULL,		/* no check constraint */
  										   NULL,
! 										   NULL);
  
  			referenced.classId = ConstraintRelationId;
  			referenced.objectId = conOid;
--- 716,724 ----
  										   InvalidOid,	/* no associated index */
  										   NULL,		/* no check constraint */
  										   NULL,
! 										   NULL,
! 										   true, /* islocal */
! 										   0); /* inhcount */
  
  			referenced.classId = ConstraintRelationId;
  			referenced.objectId = conOid;
Index: src/backend/catalog/pg_constraint.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/catalog/pg_constraint.c,v
retrieving revision 1.40
diff -c -r1.40 pg_constraint.c
*** src/backend/catalog/pg_constraint.c	26 Mar 2008 21:10:37 -0000	1.40
--- src/backend/catalog/pg_constraint.c	1 Apr 2008 07:32:15 -0000
***************
*** 60,66 ****
  					  Oid indexRelId,
  					  Node *conExpr,
  					  const char *conBin,
! 					  const char *conSrc)
  {
  	Relation	conDesc;
  	Oid			conOid;
--- 60,68 ----
  					  Oid indexRelId,
  					  Node *conExpr,
  					  const char *conBin,
! 					  const char *conSrc,
! 					  const bool conIsLocal,
! 					  const int conInhCount)
  {
  	Relation	conDesc;
  	Oid			conOid;
***************
*** 171,176 ****
--- 173,181 ----
  	else
  		nulls[Anum_pg_constraint_conffeqop - 1] = 'n';
  
+ 	values[Anum_pg_constraint_conislocal - 1] = BoolGetDatum(conIsLocal);
+ 	values[Anum_pg_constraint_coninhcount - 1] = Int32GetDatum(conInhCount);
+ 
  	/*
  	 * initialize the binary form of the check constraint.
  	 */
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.250
diff -c -r1.250 tablecmds.c
*** src/backend/commands/tablecmds.c	31 Mar 2008 03:34:27 -0000	1.250
--- src/backend/commands/tablecmds.c	1 Apr 2008 07:32:15 -0000
***************
*** 170,175 ****
--- 170,177 ----
  static List *MergeAttributes(List *schema, List *supers, bool istemp,
  				List **supOids, List **supconstr, int *supOidCount);
  static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
+ static void MergeInheritedConstraints(Relation rel, List *old_constraints,
+ 									List *new_constriants);
  static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
  static void add_nonduplicate_constraint(Constraint *cdef,
  							ConstrCheck *check, int *ncheck);
***************
*** 232,245 ****
  				 bool recurse, bool recursing);
  static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
  			   IndexStmt *stmt, bool is_rebuild);
  static void ATExecAddConstraint(AlteredTableInfo *tab, Relation rel,
  					Node *newConstraint);
  static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
  						  FkConstraint *fkconstraint);
- static void ATPrepDropConstraint(List **wqueue, Relation rel,
- 					 bool recurse, AlterTableCmd *cmd);
  static void ATExecDropConstraint(Relation rel, const char *constrName,
! 					 DropBehavior behavior, bool quiet);
  static void ATPrepAlterColumnType(List **wqueue,
  					  AlteredTableInfo *tab, Relation rel,
  					  bool recurse, bool recursing,
--- 234,248 ----
  				 bool recurse, bool recursing);
  static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
  			   IndexStmt *stmt, bool is_rebuild);
+ static void ATPrepAddConstraint(List **wqueue, Relation rel, bool recurse,
+ 				AlterTableCmd *cmd);
  static void ATExecAddConstraint(AlteredTableInfo *tab, Relation rel,
  					Node *newConstraint);
  static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
  						  FkConstraint *fkconstraint);
  static void ATExecDropConstraint(Relation rel, const char *constrName,
! 					 DropBehavior behavior, 
! 					 bool recurse, bool recursing);
  static void ATPrepAlterColumnType(List **wqueue,
  					  AlteredTableInfo *tab, Relation rel,
  					  bool recurse, bool recursing,
***************
*** 263,269 ****
  static void ATExecAddInherit(Relation rel, RangeVar *parent);
  static void ATExecDropInherit(Relation rel, RangeVar *parent);
  static void copy_relation_data(Relation rel, SMgrRelation dst);
! 
  
  /* ----------------------------------------------------------------
   *		DefineRelation
--- 266,276 ----
  static void ATExecAddInherit(Relation rel, RangeVar *parent);
  static void ATExecDropInherit(Relation rel, RangeVar *parent);
  static void copy_relation_data(Relation rel, SMgrRelation dst);
! static bool ConstraintIsEquiv(const HeapTuple a, const HeapTuple b,
! 							  const TupleDesc tupleDesc);
! static char *decompile_conbin(HeapTuple contup, TupleDesc tupdesc);
! static void change_opfuncid(Node *node, Oid opfuncid);
! static bool change_opfuncid_walker(Node *node, void *opfuncid);
  
  /* ----------------------------------------------------------------
   *		DefineRelation
***************
*** 488,493 ****
--- 495,505 ----
  		}
  	}
  
+ 	if (old_constraints && stmt->constraints)
+ 	{
+ 		MergeInheritedConstraints(rel, old_constraints, stmt->constraints);
+ 	}
+ 
  	/*
  	 * Parse and add the defaults/constraints, if any.
  	 */
***************
*** 1059,1064 ****
--- 1071,1078 ----
  				Constraint *cdef = makeNode(Constraint);
  				Node	   *expr;
  
+ 				cdef->is_local = false;
+ 				cdef->inhcount = check[i].inhcount + 1;
  				cdef->contype = CONSTR_CHECK;
  				cdef->name = pstrdup(check[i].ccname);
  				cdef->raw_expr = NULL;
***************
*** 1181,1186 ****
--- 1195,1286 ----
  	return schema;
  }
  
+ /*
+  * Go through constraints in new constraints
+  * if we have a matching constraint in old_constraints and they have a
+  * matching definition, then remove the constraint from new_constraints
+  */
+ static void
+ MergeInheritedConstraints(Relation rel,
+ 						  List *old_constraints,
+ 						  List *new_constraints)
+ {
+ 	ListCell *cur_item;
+ 	ListCell *prev_item;
+ 	ListCell *listptr;
+ 
+ 	prev_item = NULL;
+ 	cur_item = list_head(new_constraints);
+ 
+ 	while (cur_item != NULL)
+ 	{
+ 		bool get_next = true;
+ 		Constraint *cdef = (Constraint *) lfirst(cur_item);
+ 
+ 		if (cdef->contype == CONSTR_CHECK &&
+ 			cdef->cooked_expr == NULL &&
+ 			cdef->name &&
+ 			cdef->raw_expr)
+ 		{
+ 			foreach(listptr, old_constraints)
+ 			{
+ 				Constraint *cdef1 = (Constraint *) lfirst(listptr);
+ 
+ 				if (cdef1->contype == CONSTR_CHECK &&
+ 					cdef1->name &&
+ 					strcmp(cdef->name, cdef1->name) == 0)
+ 				{
+ 					ParseState		*pstate;
+ 					RangeTblEntry	*rte;
+ 					Node			*expr;
+ 					char 			*cooked;
+ 
+ 					pstate = make_parsestate(NULL);
+ 					rte = addRangeTableEntryForRelation(pstate,
+ 														rel,
+ 														NULL,
+ 														false,
+ 														true);
+ 					addRTEtoQuery(pstate, rte, true, true, true);
+ 
+ 					expr = transformExpr(pstate, cdef->raw_expr);
+ 					expr = coerce_to_boolean(pstate, expr, "CHECK");
+ 					change_opfuncid(expr, 0);
+ 
+ 					cooked = nodeToString(expr);
+ 
+ 					if (strcmp(cooked, cdef1->cooked_expr) == 0)
+ 					{
+ 						ereport(NOTICE,
+ 							(errmsg("merging constraint \"%s\" with inherited definition",
+ 							cdef->name)));
+ 
+ 						list_delete_cell(new_constraints, cur_item, prev_item);
+ 						pfree(cdef);
+ 						get_next = false;
+ 						if(prev_item)
+ 							cur_item = lnext(prev_item);
+ 						else
+ 							cur_item = list_head(new_constraints);
+ 					}else
+ 					{
+ 						ereport(ERROR,
+ 								(errmsg("constraint \"%s\" does not match inherited definition",
+ 								cdef->name)));
+ 					}
+ 
+ 					break;
+ 				}
+ 			}
+ 		}
+ 
+ 		if(get_next)
+ 		{
+ 			prev_item = cur_item;
+ 			cur_item = lnext(prev_item);
+ 		}
+ 	}
+ }
  
  /*
   * In multiple-inheritance situations, it's possible to inherit
***************
*** 1214,1219 ****
--- 1314,1321 ----
  	/* No match on name, so add it to array */
  	check[*ncheck].ccname = cdef->name;
  	check[*ncheck].ccbin = pstrdup(cdef->cooked_expr);
+ 	check[*ncheck].inhcount = cdef->inhcount;
+ 	check[*ncheck].is_local = cdef->is_local;
  	(*ncheck)++;
  }
  
***************
*** 1312,1317 ****
--- 1414,1451 ----
  	return attmap;
  }
  
+ /*
+  * change an opfuncid of a Node
+  *
+  * Note that the passed node tree is modified in-place!
+  */
+ static void
+ change_opfuncid(Node *node, Oid opfuncid)
+ {
+ 	Oid *o = palloc(sizeof(Oid));
+ 	*o = opfuncid;
+ 	(void) change_opfuncid_walker(node, (void*)o);
+ 	pfree(o);
+ }
+ 
+ static bool
+ change_opfuncid_walker(Node *node, void *opfuncid)
+ {
+ 	if (node == NULL)
+ 		return false;
+ 
+ 	if (IsA(node, OpExpr))
+ 	{
+ 		Oid		*o = (Oid*)opfuncid;
+ 		OpExpr	*op = (OpExpr *) node;
+ 
+ 		op->opfuncid = *o;
+ 		return false;
+ 	}
+ 	return expression_tree_walker(node, change_opfuncid_walker,
+ 								  opfuncid);
+ 
+ }
  
  /*
   * StoreCatalogInheritance
***************
*** 2044,2070 ****
  			break;
  		case AT_AddConstraint:	/* ADD CONSTRAINT */
  			ATSimplePermissions(rel, false);
! 
! 			/*
! 			 * Currently we recurse only for CHECK constraints, never for
! 			 * foreign-key constraints.  UNIQUE/PKEY constraints won't be seen
! 			 * here.
! 			 */
! 			if (IsA(cmd->def, Constraint))
! 				ATSimpleRecursion(wqueue, rel, cmd, recurse);
! 			/* No command-specific prep needed */
  			pass = AT_PASS_ADD_CONSTR;
  			break;
  		case AT_DropConstraint:	/* DROP CONSTRAINT */
  			ATSimplePermissions(rel, false);
! 			/* Performs own recursion */
! 			ATPrepDropConstraint(wqueue, rel, recurse, cmd);
! 			pass = AT_PASS_DROP;
! 			break;
! 		case AT_DropConstraintQuietly:	/* DROP CONSTRAINT for child */
! 			ATSimplePermissions(rel, false);
! 			ATSimpleRecursion(wqueue, rel, cmd, recurse);
! 			/* No command-specific prep needed */
  			pass = AT_PASS_DROP;
  			break;
  		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
--- 2178,2193 ----
  			break;
  		case AT_AddConstraint:	/* ADD CONSTRAINT */
  			ATSimplePermissions(rel, false);
! 			ATPrepAddConstraint(wqueue, rel, recurse, cmd);
  			pass = AT_PASS_ADD_CONSTR;
  			break;
  		case AT_DropConstraint:	/* DROP CONSTRAINT */
  			ATSimplePermissions(rel, false);
! 			/* we follow AT_DropColumns example for better or for worse so
! 			 * Recursion occurs during execution phase
! 			 * No command-specific prep needed except saving recurse flag */
! 			if (recurse)
! 				cmd->subtype = AT_DropConstraintRecurse;
  			pass = AT_PASS_DROP;
  			break;
  		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
***************
*** 2253,2262 ****
  			ATExecAddConstraint(tab, rel, cmd->def);
  			break;
  		case AT_DropConstraint:	/* DROP CONSTRAINT */
! 			ATExecDropConstraint(rel, cmd->name, cmd->behavior, false);
  			break;
! 		case AT_DropConstraintQuietly:	/* DROP CONSTRAINT for child */
! 			ATExecDropConstraint(rel, cmd->name, cmd->behavior, true);
  			break;
  		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
  			ATExecAlterColumnType(tab, rel, cmd->name, (TypeName *) cmd->def);
--- 2376,2385 ----
  			ATExecAddConstraint(tab, rel, cmd->def);
  			break;
  		case AT_DropConstraint:	/* DROP CONSTRAINT */
! 			ATExecDropConstraint(rel, cmd->name, cmd->behavior, false, false);
  			break;
! 		case AT_DropConstraintRecurse:	/* DROP CONSTRAINT for child */
! 			ATExecDropConstraint(rel, cmd->name, cmd->behavior, true, false);
  			break;
  		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
  			ATExecAlterColumnType(tab, rel, cmd->name, (TypeName *) cmd->def);
***************
*** 3931,3936 ****
--- 4054,4108 ----
   * ALTER TABLE ADD CONSTRAINT
   */
  static void
+ ATPrepAddConstraint(List **wqueue, Relation rel, bool recurse,
+ 				AlterTableCmd *cmd)
+ {
+ 	/*
+ 	 * Currently we recurse only for CHECK constraints, never for
+ 	 * foreign-key constraints.  UNIQUE/PKEY constraints won't be seen
+ 	 * here.
+ 	 */
+ 	if (!IsA(cmd->def, Constraint))
+ 	{
+ 		return;
+ 	}
+ 
+ 	/*
+ 	 * Recurse to add the column to child classes, if requested.
+ 	 *
+ 	 * We must recurse one level at a time, so that multiply-inheriting
+ 	 * children are visited the right number of times and end up with the
+ 	 * right coninhcount.
+ 	 */
+ 	if (recurse)
+ 	{
+ 		AlterTableCmd	*childCmd = copyObject(cmd);
+ 		Constraint		*constr = (Constraint *) childCmd->def;
+ 
+ 		/* child should see column as singly inherited */
+ 		constr->inhcount = 1;
+ 		constr->is_local = false;
+ 
+ 		ATOneLevelRecursion(wqueue, rel, childCmd);
+ 	}
+ 	else
+ 	{
+ 		/*
+ 		 * If we are told not to recurse, there had better not be any child
+ 		 * tables; else the addition would put them out of step.
+ 		 */
+ 		if (find_inheritance_children(RelationGetRelid(rel)) != NIL)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ 					 errmsg("constraint must be added to children tables too")));
+ 	}
+ }
+ 
+ 
+ /*
+  * ALTER TABLE ADD CONSTRAINT
+  */
+ static void
  ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint)
  {
  	switch (nodeTag(newConstraint))
***************
*** 4290,4296 ****
  									  indexOid,
  									  NULL,		/* no check constraint */
  									  NULL,
! 									  NULL);
  
  	/*
  	 * Create the triggers that will enforce the constraint.
--- 4462,4470 ----
  									  indexOid,
  									  NULL,		/* no check constraint */
  									  NULL,
! 									  NULL,
! 									  true, /* islocal */
! 									  0); /* inhcount */
  
  	/*
  	 * Create the triggers that will enforce the constraint.
***************
*** 4810,4853 ****
   * ALTER TABLE DROP CONSTRAINT
   */
  static void
! ATPrepDropConstraint(List **wqueue, Relation rel,
! 					 bool recurse, AlterTableCmd *cmd)
  {
  	/*
! 	 * We don't want errors or noise from child tables, so we have to pass
! 	 * down a modified command.
  	 */
! 	if (recurse)
  	{
! 		AlterTableCmd *childCmd = copyObject(cmd);
  
! 		childCmd->subtype = AT_DropConstraintQuietly;
! 		ATSimpleRecursion(wqueue, rel, childCmd, recurse);
! 	}
! }
  
! static void
! ATExecDropConstraint(Relation rel, const char *constrName,
! 					 DropBehavior behavior, bool quiet)
! {
! 	int			deleted;
  
! 	deleted = RemoveRelConstraints(rel, constrName, behavior);
  
! 	if (!quiet)
! 	{
! 		/* If zero constraints deleted, complain */
! 		if (deleted == 0)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_UNDEFINED_OBJECT),
! 					 errmsg("constraint \"%s\" does not exist",
! 							constrName)));
! 		/* Otherwise if more than one constraint deleted, notify */
! 		else if (deleted > 1)
! 			ereport(NOTICE,
! 					(errmsg("multiple constraints named \"%s\" were dropped",
! 							constrName)));
  	}
  }
  
  /*
--- 4984,5101 ----
   * ALTER TABLE DROP CONSTRAINT
   */
  static void
! ATExecDropConstraint(Relation rel, const char *constrName,
! 					 DropBehavior behavior,
! 					 bool recurse, bool recursing)
  {
+ 	HeapTuple	tuple;
+ 	List		*children;
+ 	Relation	conrel;
+ 	TupleDesc	tupdesc;
+ 	Oid		relid;
+ 	Form_pg_constraint con;
+ 
+ 	relid = RelationGetRelid(rel);
+ 	conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
+ 	tupdesc = RelationGetDescr(conrel);
+ 
+ 	if (recursing)
+ 		ATSimplePermissions(rel, false);
+ 
+ 	tuple = SearchSysCache(CONSTRNAME,
+ 						   ObjectIdGetDatum(relid),
+ 						   CStringGetDatum(constrName),
+ 						   0, 0);
+ 
+ 	if (!HeapTupleIsValid(tuple))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_COLUMN),
+ 				 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
+ 						constrName, RelationGetRelationName(rel))));
+ 
+ 	con = (Form_pg_constraint) GETSTRUCT(tuple);
+ 
+ 	/* Don't drop inherited constraints */
+ 	if (con->coninhcount > 0 && !recursing)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ 				 errmsg("cannot drop inherited constraint \"%s\" of relation \"%s\"",
+ 						constrName,
+ 						RelationGetRelationName(rel))));
+ 
+ 	ReleaseSysCache(tuple);
+ 
  	/*
! 	 * Propagate to children as appropriate.  Unlike most other ALTER
! 	 * routines, we have to do this one level of recursion at a time; we can't
! 	 * use find_all_inheritors to do it in one pass.
  	 */
! 	children = find_inheritance_children(RelationGetRelid(rel));
! 
! 	if (children)
  	{
! 		ListCell   *child;
  
! 		foreach(child, children)
! 		{
! 			Oid			childrelid = lfirst_oid(child);
! 			Relation	childrel;
! 			Form_pg_constraint childcon;
  
! 			childrel = heap_open(childrelid, AccessExclusiveLock);
! 			CheckTableNotInUse(childrel, "ALTER TABLE");
  
! 			tuple = SearchSysCacheCopy(CONSTRNAME,
! 								   ObjectIdGetDatum(childrelid),
! 								   CStringGetDatum(constrName),
! 								   0, 0);
! 			if (!HeapTupleIsValid(tuple))
! 				elog(ERROR, "cache lookup failed for constraint \"%s\" of relation %u",
! 					 constrName, childrelid);
! 
! 			childcon = (Form_pg_constraint) GETSTRUCT(tuple);
! 
! 			if (childcon->coninhcount <= 0)
! 				elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
! 					 childrelid, constrName);
  
! 			if (recurse)
! 			{
! 				if (childcon->coninhcount == 1 && !childcon->conislocal)
! 				{
! 					ATExecDropConstraint(childrel, constrName, behavior, true, true);
! 				}
! 				else
! 				{
! 					childcon->coninhcount--;
! 
! 					simple_heap_update(conrel, &tuple->t_self, tuple);
! 					CatalogUpdateIndexes(conrel, tuple);
! 				}
! 			}
! 			else
! 			{
! 				/*
! 				 * If we were told to drop ONLY in this table (no recursion),
! 				 * we need to mark the inheritors' attribute as locally
! 				 * defined rather than inherited.
! 				 */
! 
! 				childcon->coninhcount--;
! 				childcon->conislocal = true;
! 
! 				simple_heap_update(conrel, &tuple->t_self, tuple);
! 				CatalogUpdateIndexes(conrel, tuple);
! 			}
! 
! 			heap_freetuple(tuple);
! 			heap_close(childrel, AccessExclusiveLock);
! 		}
  	}
+ 
+ 	RemoveRelConstraints(rel, constrName, behavior);
+ 
+ 	heap_close(conrel, RowExclusiveLock);
  }
  
  /*
***************
*** 6255,6260 ****
--- 6503,6525 ----
  }
  
  /*
+  * See if two constraints are "functionally" equivalent, but not necessarily equal
+  */
+ static bool
+ ConstraintIsEquiv(const HeapTuple a, const HeapTuple b, const TupleDesc tupleDesc)
+ {
+ 	const Form_pg_constraint acon = (Form_pg_constraint) GETSTRUCT(a);
+ 	const Form_pg_constraint bcon = (Form_pg_constraint) GETSTRUCT(b);
+ 
+ 	if (acon->condeferrable != bcon->condeferrable ||
+ 		acon->condeferred != bcon->condeferred ||
+ 			strcmp(decompile_conbin(a, tupleDesc),
+ 				   decompile_conbin(b, tupleDesc)) != 0)
+ 		return 0;
+ 	else
+ 		return 1;
+ }
+ /*
   * Check columns in child table match up with columns in parent, and increment
   * their attinhcount.
   *
***************
*** 6348,6356 ****
   * make it possible to ensure no records are mistakenly inserted into the
   * master in partitioned tables rather than the appropriate child.
   *
-  * XXX This is O(N^2) which may be an issue with tables with hundreds of
-  * constraints. As long as tables have more like 10 constraints it shouldn't be
-  * a problem though. Even 100 constraints ought not be the end of the world.
   */
  static void
  MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
--- 6613,6618 ----
***************
*** 6360,6445 ****
  	SysScanDesc scan;
  	ScanKeyData key;
  	HeapTuple	constraintTuple;
- 	ListCell   *elem;
- 	List	   *constraints;
  
! 	/* First gather up the child's constraint definitions */
! 	catalogRelation = heap_open(ConstraintRelationId, AccessShareLock);
  	tupleDesc = RelationGetDescr(catalogRelation);
  
  	ScanKeyInit(&key,
  				Anum_pg_constraint_conrelid,
  				BTEqualStrategyNumber, F_OIDEQ,
! 				ObjectIdGetDatum(RelationGetRelid(child_rel)));
  	scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
  							  true, SnapshotNow, 1, &key);
  
- 	constraints = NIL;
- 	while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
- 	{
- 		Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
- 
- 		if (con->contype != CONSTRAINT_CHECK)
- 			continue;
- 
- 		constraints = lappend(constraints, heap_copytuple(constraintTuple));
- 	}
- 
- 	systable_endscan(scan);
- 
- 	/* Then scan through the parent's constraints looking for matches */
- 	ScanKeyInit(&key,
- 				Anum_pg_constraint_conrelid,
- 				BTEqualStrategyNumber, F_OIDEQ,
- 				ObjectIdGetDatum(RelationGetRelid(parent_rel)));
- 	scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId, true,
- 							  SnapshotNow, 1, &key);
- 
  	while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
  	{
  		Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
- 		bool		found = false;
- 		Form_pg_constraint child_con = NULL;
- 		HeapTuple	child_contuple = NULL;
  
  		if (parent_con->contype != CONSTRAINT_CHECK)
  			continue;
  
! 		foreach(elem, constraints)
! 		{
! 			child_contuple = (HeapTuple) lfirst(elem);
! 			child_con = (Form_pg_constraint) GETSTRUCT(child_contuple);
! 			if (strcmp(NameStr(parent_con->conname),
! 					   NameStr(child_con->conname)) == 0)
! 			{
! 				found = true;
! 				break;
! 			}
! 		}
  
! 		if (!found)
  			ereport(ERROR,
  					(errcode(ERRCODE_DATATYPE_MISMATCH),
  					 errmsg("child table is missing constraint \"%s\"",
  							NameStr(parent_con->conname))));
  
! 		if (parent_con->condeferrable != child_con->condeferrable ||
! 			parent_con->condeferred != child_con->condeferred ||
! 			strcmp(decompile_conbin(constraintTuple, tupleDesc),
! 				   decompile_conbin(child_contuple, tupleDesc)) != 0)
  			ereport(ERROR,
  					(errcode(ERRCODE_DATATYPE_MISMATCH),
  					 errmsg("constraint definition for check constraint \"%s\" does not match",
  							NameStr(parent_con->conname))));
  
! 		/*
! 		 * TODO: add conislocal,coninhcount to constraints. This is where we
! 		 * would have to bump them just like attributes
! 		 */
  	}
  
  	systable_endscan(scan);
! 	heap_close(catalogRelation, AccessShareLock);
  }
  
  /*
--- 6622,6675 ----
  	SysScanDesc scan;
  	ScanKeyData key;
  	HeapTuple	constraintTuple;
  
! 	catalogRelation = heap_open(ConstraintRelationId, RowExclusiveLock);
  	tupleDesc = RelationGetDescr(catalogRelation);
  
  	ScanKeyInit(&key,
  				Anum_pg_constraint_conrelid,
  				BTEqualStrategyNumber, F_OIDEQ,
! 				ObjectIdGetDatum(RelationGetRelid(parent_rel)));
  	scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
  							  true, SnapshotNow, 1, &key);
  
  	while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
  	{
+ 		HeapTuple childTuple;
+ 		Form_pg_constraint child_con;
  		Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
  
  		if (parent_con->contype != CONSTRAINT_CHECK)
  			continue;
  
! 		childTuple = SearchSysCacheCopy(CONSTRNAME,
! 									ObjectIdGetDatum(RelationGetRelid(child_rel)),
! 									CStringGetDatum(NameStr(parent_con->conname)),
! 									0, 0);
  
! 		if (!HeapTupleIsValid(childTuple))
  			ereport(ERROR,
  					(errcode(ERRCODE_DATATYPE_MISMATCH),
  					 errmsg("child table is missing constraint \"%s\"",
  							NameStr(parent_con->conname))));
  
! 		child_con = (Form_pg_constraint) GETSTRUCT(childTuple);
! 
! 		if (!ConstraintIsEquiv(constraintTuple, childTuple, tupleDesc))
  			ereport(ERROR,
  					(errcode(ERRCODE_DATATYPE_MISMATCH),
  					 errmsg("constraint definition for check constraint \"%s\" does not match",
  							NameStr(parent_con->conname))));
  
! 		/* increment coninhcount */
! 		child_con->coninhcount++;
! 		simple_heap_update(catalogRelation, &childTuple->t_self, childTuple);
! 		CatalogUpdateIndexes(catalogRelation, childTuple);
! 		heap_freetuple(childTuple);
  	}
  
  	systable_endscan(scan);
! 	heap_close(catalogRelation, RowExclusiveLock);
  }
  
  /*
***************
*** 6464,6471 ****
--- 6694,6703 ----
  	ScanKeyData key[3];
  	HeapTuple	inheritsTuple,
  				attributeTuple,
+ 				constraintTuple,
  				depTuple;
  	bool		found = false;
+ 	TupleDesc	tupdesc;
  
  	/*
  	 * AccessShareLock on the parent is probably enough, seeing that DROP
***************
*** 6553,6558 ****
--- 6785,6825 ----
  	systable_endscan(scan);
  	heap_close(catalogRelation, RowExclusiveLock);
  
+ 	catalogRelation = heap_open(ConstraintRelationId, RowExclusiveLock);
+ 	ScanKeyInit(&key[0],
+ 				Anum_pg_constraint_conrelid,
+ 				BTEqualStrategyNumber, F_OIDEQ,
+ 				ObjectIdGetDatum(RelationGetRelid(rel)));
+ 	scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
+ 							  true, SnapshotNow, 1, key);
+ 
+ 	tupdesc = RelationGetDescr(catalogRelation);
+ 
+ 	while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
+ 	{
+ 		Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
+ 
+ 		if (con->contype != CONSTRAINT_CHECK)
+ 			continue;
+ 
+ 		if (con->coninhcount > 0)
+ 		{
+ 			HeapTuple	copyTuple = heap_copytuple(constraintTuple);
+ 			Form_pg_constraint copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
+ 
+ 			copy_con->coninhcount--;
+ 			if (copy_con->coninhcount == 0)
+ 				copy_con->conislocal = true;
+ 
+ 			simple_heap_update(catalogRelation, &copyTuple->t_self, copyTuple);
+ 			CatalogUpdateIndexes(catalogRelation, copyTuple);
+ 			heap_freetuple(copyTuple);
+ 		}
+ 	}
+ 
+ 	systable_endscan(scan);
+ 	heap_close(catalogRelation, RowExclusiveLock);
+ 
  	/*
  	 * Drop the dependency
  	 *
Index: src/backend/commands/typecmds.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/commands/typecmds.c,v
retrieving revision 1.117
diff -c -r1.117 typecmds.c
*** src/backend/commands/typecmds.c	27 Mar 2008 03:57:33 -0000	1.117
--- src/backend/commands/typecmds.c	1 Apr 2008 07:32:15 -0000
***************
*** 2206,2212 ****
  						  InvalidOid,
  						  expr, /* Tree form check constraint */
  						  ccbin,	/* Binary form check constraint */
! 						  ccsrc);		/* Source form check constraint */
  
  	/*
  	 * Return the compiled constraint expression so the calling routine can
--- 2206,2214 ----
  						  InvalidOid,
  						  expr, /* Tree form check constraint */
  						  ccbin,	/* Binary form check constraint */
! 						  ccsrc,	/* Source form check constraint */
! 						  true, /* is local */
! 						  0); /* inhcount */
  
  	/*
  	 * Return the compiled constraint expression so the calling routine can
Index: src/backend/nodes/copyfuncs.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.390
diff -c -r1.390 copyfuncs.c
*** src/backend/nodes/copyfuncs.c	21 Mar 2008 22:41:48 -0000	1.390
--- src/backend/nodes/copyfuncs.c	1 Apr 2008 07:32:15 -0000
***************
*** 1814,1819 ****
--- 1814,1821 ----
  	COPY_NODE_FIELD(keys);
  	COPY_NODE_FIELD(options);
  	COPY_STRING_FIELD(indexspace);
+ 	COPY_SCALAR_FIELD(inhcount);
+ 	COPY_SCALAR_FIELD(is_local);
  
  	return newnode;
  }
Index: src/backend/nodes/equalfuncs.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.320
diff -c -r1.320 equalfuncs.c
*** src/backend/nodes/equalfuncs.c	21 Mar 2008 22:41:48 -0000	1.320
--- src/backend/nodes/equalfuncs.c	1 Apr 2008 07:32:15 -0000
***************
*** 1839,1844 ****
--- 1839,1846 ----
  	COMPARE_NODE_FIELD(keys);
  	COMPARE_NODE_FIELD(options);
  	COMPARE_STRING_FIELD(indexspace);
+ 	COMPARE_SCALAR_FIELD(inhcount);
+ 	COMPARE_SCALAR_FIELD(is_local);
  
  	return true;
  }
Index: src/backend/nodes/outfuncs.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/nodes/outfuncs.c,v
retrieving revision 1.324
diff -c -r1.324 outfuncs.c
*** src/backend/nodes/outfuncs.c	21 Mar 2008 22:41:48 -0000	1.324
--- src/backend/nodes/outfuncs.c	1 Apr 2008 07:32:15 -0000
***************
*** 2033,2038 ****
--- 2033,2041 ----
  			appendStringInfo(str, "<unrecognized_constraint>");
  			break;
  	}
+ 
+ 	WRITE_INT_FIELD(inhcount);
+ 	WRITE_BOOL_FIELD(is_local);
  }
  
  static void
Index: src/backend/parser/gram.y
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.611
diff -c -r2.611 gram.y
*** src/backend/parser/gram.y	28 Mar 2008 00:21:55 -0000	2.611
--- src/backend/parser/gram.y	1 Apr 2008 07:32:15 -0000
***************
*** 2068,2073 ****
--- 2068,2075 ----
  					n->cooked_expr = NULL;
  					n->keys = NULL;
  					n->indexspace = NULL;
+ 					n->is_local = true;
+ 					n->inhcount = 0;
  					$$ = (Node *)n;
  				}
  			| DEFAULT b_expr
***************
*** 2208,2213 ****
--- 2210,2217 ----
  					n->raw_expr = $3;
  					n->cooked_expr = NULL;
  					n->indexspace = NULL;
+ 					n->is_local = true;
+ 					n->inhcount = 0;
  					$$ = (Node *)n;
  				}
  			| UNIQUE '(' columnList ')' opt_definition OptConsTableSpace
Index: src/backend/parser/parse_utilcmd.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/parser/parse_utilcmd.c,v
retrieving revision 2.11
diff -c -r2.11 parse_utilcmd.c
*** src/backend/parser/parse_utilcmd.c	25 Mar 2008 22:42:43 -0000	2.11
--- src/backend/parser/parse_utilcmd.c	1 Apr 2008 07:32:15 -0000
***************
*** 685,690 ****
--- 685,692 ----
  			n->cooked_expr = nodeToString(ccbin_node);
  			n->indexspace = NULL;
  			cxt->ckconstraints = lappend(cxt->ckconstraints, (Node *) n);
+ 			n->is_local = true;
+ 			n->inhcount = 0;
  		}
  	}
  
Index: src/backend/utils/cache/catcache.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/utils/cache/catcache.c,v
retrieving revision 1.142
diff -c -r1.142 catcache.c
*** src/backend/utils/cache/catcache.c	26 Mar 2008 21:10:39 -0000	1.142
--- src/backend/utils/cache/catcache.c	1 Apr 2008 07:32:16 -0000
***************
*** 962,968 ****
  		else
  		{
  			if (cache->cc_key[i] != ObjectIdAttributeNumber)
! 				elog(FATAL, "only sys attr supported in caches is OID");
  			keytype = OIDOID;
  		}
  
--- 962,968 ----
  		else
  		{
  			if (cache->cc_key[i] != ObjectIdAttributeNumber)
! 				elog(FATAL, "only sys attr supported in caches is OID for relation: %s", cache->cc_relname);
  			keytype = OIDOID;
  		}
  
Index: src/backend/utils/cache/syscache.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/backend/utils/cache/syscache.c,v
retrieving revision 1.114
diff -c -r1.114 syscache.c
*** src/backend/utils/cache/syscache.c	1 Jan 2008 19:45:53 -0000	1.114
--- src/backend/utils/cache/syscache.c	1 Apr 2008 07:32:16 -0000
***************
*** 305,310 ****
--- 305,322 ----
  		},
  		128
  	},
+ 	{ConstraintRelationId,		// CONSTRNAME
+ 		ConstraintRelidNameIndexId,
+ 		Anum_pg_constraint_conrelid,
+ 		2,
+ 		{
+ 			Anum_pg_constraint_conrelid,
+ 			Anum_pg_constraint_conname,
+ 			0,
+ 			0
+ 		},
+ 		256,
+ 	},
  	{ConstraintRelationId,		/* CONSTROID */
  		ConstraintOidIndexId,
  		0,
Index: src/bin/pg_dump/common.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/bin/pg_dump/common.c,v
retrieving revision 1.103
diff -c -r1.103 common.c
*** src/bin/pg_dump/common.c	27 Mar 2008 03:57:33 -0000	1.103
--- src/bin/pg_dump/common.c	1 Apr 2008 07:32:16 -0000
***************
*** 62,69 ****
  
  static void flagInhTables(TableInfo *tbinfo, int numTables,
  			  InhInfo *inhinfo, int numInherits);
! static void flagInhAttrs(TableInfo *tbinfo, int numTables,
! 			 InhInfo *inhinfo, int numInherits);
  static DumpableObject **buildIndexArray(void *objArray, int numObjs,
  				Size objSize);
  static int	DOCatalogIdCompare(const void *p1, const void *p2);
--- 62,70 ----
  
  static void flagInhTables(TableInfo *tbinfo, int numTables,
  			  InhInfo *inhinfo, int numInherits);
! static void flagInhAttrs(TableInfo *tblinfo, int numTables,
! 			 InhInfo *inhinfo, int numInherits,
! 			 int remoteVersion);
  static DumpableObject **buildIndexArray(void *objArray, int numObjs,
  				Size objSize);
  static int	DOCatalogIdCompare(const void *p1, const void *p2);
***************
*** 77,83 ****
   *	  Collect information about all potentially dumpable objects
   */
  TableInfo *
! getSchemaData(int *numTablesPtr)
  {
  	NamespaceInfo *nsinfo;
  	AggInfo    *agginfo;
--- 78,84 ----
   *	  Collect information about all potentially dumpable objects
   */
  TableInfo *
! getSchemaData(int *numTablesPtr, int remoteVersion)
  {
  	NamespaceInfo *nsinfo;
  	AggInfo    *agginfo;
***************
*** 191,197 ****
  
  	if (g_verbose)
  		write_msg(NULL, "flagging inherited columns in subtables\n");
! 	flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
  
  	if (g_verbose)
  		write_msg(NULL, "reading indexes\n");
--- 192,198 ----
  
  	if (g_verbose)
  		write_msg(NULL, "flagging inherited columns in subtables\n");
! 	flagInhAttrs(tblinfo, numTables, inhinfo, numInherits, remoteVersion);
  
  	if (g_verbose)
  		write_msg(NULL, "reading indexes\n");
***************
*** 258,264 ****
   */
  static void
  flagInhAttrs(TableInfo *tblinfo, int numTables,
! 			 InhInfo *inhinfo, int numInherits)
  {
  	int			i,
  				j,
--- 259,266 ----
   */
  static void
  flagInhAttrs(TableInfo *tblinfo, int numTables,
! 			 InhInfo *inhinfo, int numInherits,
! 			 int remoteVersion)
  {
  	int			i,
  				j,
***************
*** 423,454 ****
  		 * different schemas, because reverse-listing of function calls may
  		 * produce different text (schema-qualified or not) depending on
  		 * search path.  We really need a more bulletproof way of detecting
! 		 * inherited constraints --- pg_constraint should record this
  		 * explicitly!
  		 */
! 		for (j = 0; j < tbinfo->ncheck; j++)
  		{
! 			ConstraintInfo *constr;
! 
! 			constr = &(tbinfo->checkexprs[j]);
! 
! 			for (k = 0; k < numParents; k++)
  			{
! 				int			l;
  
! 				parent = parents[k];
! 				for (l = 0; l < parent->ncheck; l++)
  				{
! 					ConstraintInfo *pconstr = &(parent->checkexprs[l]);
  
! 					if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0)
  					{
! 						constr->coninherited = true;
! 						break;
  					}
  				}
- 				if (constr->coninherited)
- 					break;
  			}
  		}
  	}
--- 425,460 ----
  		 * different schemas, because reverse-listing of function calls may
  		 * produce different text (schema-qualified or not) depending on
  		 * search path.  We really need a more bulletproof way of detecting
! 		 * inherited constraints 
! 		 * The above is pre-80300 behaviour, now pg_constraint records this
  		 * explicitly!
  		 */
! 		if (remoteVersion <= 80300)
  		{
! 			for (j = 0; j < tbinfo->ncheck; j++)
  			{
! 				ConstraintInfo *constr;
  
! 				constr = &(tbinfo->checkexprs[j]);
! 
! 				for (k = 0; k < numParents; k++)
  				{
! 					int			l;
  
! 					parent = parents[k];
! 					for (l = 0; l < parent->ncheck; l++)
  					{
! 						ConstraintInfo *pconstr = &(parent->checkexprs[l]);
! 
! 						if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0)
! 						{
! 							constr->coninherited = true;
! 							break;
! 						}
  					}
+ 					if (constr->coninherited)
+ 						break;
  				}
  			}
  		}
  	}
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.486
diff -c -r1.486 pg_dump.c
*** src/bin/pg_dump/pg_dump.c	28 Mar 2008 00:21:56 -0000	1.486
--- src/bin/pg_dump/pg_dump.c	1 Apr 2008 07:32:16 -0000
***************
*** 631,637 ****
  	 * Now scan the database and create DumpableObject structs for all the
  	 * objects we intend to dump.
  	 */
! 	tblinfo = getSchemaData(&numTables);
  
  	if (!schemaOnly)
  		getTableData(tblinfo, numTables, oids);
--- 631,637 ----
  	 * Now scan the database and create DumpableObject structs for all the
  	 * objects we intend to dump.
  	 */
! 	tblinfo = getSchemaData(&numTables, g_fout->remoteVersion);
  
  	if (!schemaOnly)
  		getTableData(tblinfo, numTables, oids);
***************
*** 4575,4584 ****
  						  tbinfo->dobj.name);
  
  			resetPQExpBuffer(q);
! 			if (g_fout->remoteVersion >= 70400)
  			{
  				appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
! 							"pg_catalog.pg_get_constraintdef(oid) AS consrc "
  								  "FROM pg_catalog.pg_constraint "
  								  "WHERE conrelid = '%u'::pg_catalog.oid "
  								  "   AND contype = 'c' "
--- 4575,4597 ----
  						  tbinfo->dobj.name);
  
  			resetPQExpBuffer(q);
! 			if (g_fout->remoteVersion > 80300)
  			{
+ 				/* 8.3 did not have conislocal attribute in pg_constraint */
  				appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
! 							"pg_catalog.pg_get_constraintdef(oid) AS consrc, "
! 							"conislocal "
! 								  "FROM pg_catalog.pg_constraint "
! 								  "WHERE conrelid = '%u'::pg_catalog.oid "
! 								  "   AND contype = 'c' "
! 								  "ORDER BY conname",
! 								  tbinfo->dobj.catId.oid);
! 			}
! 			else if (g_fout->remoteVersion >= 70400)
! 			{
! 				appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
! 							"pg_catalog.pg_get_constraintdef(oid) AS consrc, "
! 						  	"false as conislocal "
  								  "FROM pg_catalog.pg_constraint "
  								  "WHERE conrelid = '%u'::pg_catalog.oid "
  								  "   AND contype = 'c' "
***************
*** 4589,4595 ****
  			{
  				/* no pg_get_constraintdef, must use consrc */
  				appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
! 								  "'CHECK (' || consrc || ')' AS consrc "
  								  "FROM pg_catalog.pg_constraint "
  								  "WHERE conrelid = '%u'::pg_catalog.oid "
  								  "   AND contype = 'c' "
--- 4602,4609 ----
  			{
  				/* no pg_get_constraintdef, must use consrc */
  				appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
! 								  "'CHECK (' || consrc || ')' AS consrc, "
! 								  "false as conislocal "
  								  "FROM pg_catalog.pg_constraint "
  								  "WHERE conrelid = '%u'::pg_catalog.oid "
  								  "   AND contype = 'c' "
***************
*** 4601,4607 ****
  				/* 7.2 did not have OIDs in pg_relcheck */
  				appendPQExpBuffer(q, "SELECT tableoid, 0 as oid, "
  								  "rcname AS conname, "
! 								  "'CHECK (' || rcsrc || ')' AS consrc "
  								  "FROM pg_relcheck "
  								  "WHERE rcrelid = '%u'::oid "
  								  "ORDER BY rcname",
--- 4615,4622 ----
  				/* 7.2 did not have OIDs in pg_relcheck */
  				appendPQExpBuffer(q, "SELECT tableoid, 0 as oid, "
  								  "rcname AS conname, "
! 								  "'CHECK (' || rcsrc || ')' AS consrc, "
! 								  "false as conislocal "
  								  "FROM pg_relcheck "
  								  "WHERE rcrelid = '%u'::oid "
  								  "ORDER BY rcname",
***************
*** 4611,4617 ****
  			{
  				appendPQExpBuffer(q, "SELECT tableoid, oid, "
  								  "rcname AS conname, "
! 								  "'CHECK (' || rcsrc || ')' AS consrc "
  								  "FROM pg_relcheck "
  								  "WHERE rcrelid = '%u'::oid "
  								  "ORDER BY rcname",
--- 4626,4633 ----
  			{
  				appendPQExpBuffer(q, "SELECT tableoid, oid, "
  								  "rcname AS conname, "
! 								  "'CHECK (' || rcsrc || ')' AS consrc, "
! 								  "false as conislocal "
  								  "FROM pg_relcheck "
  								  "WHERE rcrelid = '%u'::oid "
  								  "ORDER BY rcname",
***************
*** 4623,4629 ****
  				appendPQExpBuffer(q, "SELECT "
  								  "(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
  								  "oid, rcname AS conname, "
! 								  "'CHECK (' || rcsrc || ')' AS consrc "
  								  "FROM pg_relcheck "
  								  "WHERE rcrelid = '%u'::oid "
  								  "ORDER BY rcname",
--- 4639,4646 ----
  				appendPQExpBuffer(q, "SELECT "
  								  "(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
  								  "oid, rcname AS conname, "
! 								  "'CHECK (' || rcsrc || ')' AS consrc, "
! 								  " false as conislocal"
  								  "FROM pg_relcheck "
  								  "WHERE rcrelid = '%u'::oid "
  								  "ORDER BY rcname",
***************
*** 4657,4664 ****
  				constrs[j].contype = 'c';
  				constrs[j].condef = strdup(PQgetvalue(res, j, 3));
  				constrs[j].conindex = 0;
- 				constrs[j].coninherited = false;
  				constrs[j].separate = false;
  
  				constrs[j].dobj.dump = tbinfo->dobj.dump;
  
--- 4674,4682 ----
  				constrs[j].contype = 'c';
  				constrs[j].condef = strdup(PQgetvalue(res, j, 3));
  				constrs[j].conindex = 0;
  				constrs[j].separate = false;
+ 				/* depending on conislocal value, set coninherited */
+ 				constrs[j].coninherited = (PQgetvalue(res, j, 4)[0] == 't');
  
  				constrs[j].dobj.dump = tbinfo->dobj.dump;
  
***************
*** 4673,4680 ****
  
  				/*
  				 * If the constraint is inherited, this will be detected
! 				 * later.  We also detect later if the constraint must be
! 				 * split out from the table definition.
  				 */
  			}
  			PQclear(res);
--- 4691,4698 ----
  
  				/*
  				 * If the constraint is inherited, this will be detected
! 				 * later for pre-80300 case. We also detect later if the constraint
! 				 * must be split out from the table definition.
  				 */
  			}
  			PQclear(res);
Index: src/bin/pg_dump/pg_dump.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/bin/pg_dump/pg_dump.h,v
retrieving revision 1.139
diff -c -r1.139 pg_dump.h
*** src/bin/pg_dump/pg_dump.h	1 Jan 2008 19:45:55 -0000	1.139
--- src/bin/pg_dump/pg_dump.h	1 Apr 2008 07:32:16 -0000
***************
*** 429,435 ****
   *	common utility functions
   */
  
! extern TableInfo *getSchemaData(int *numTablesPtr);
  
  typedef enum _OidOptions
  {
--- 429,435 ----
   *	common utility functions
   */
  
! extern TableInfo *getSchemaData(int *numTablesPtr, int remoteVersion);
  
  typedef enum _OidOptions
  {
Index: src/include/access/tupdesc.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/include/access/tupdesc.h,v
retrieving revision 1.53
diff -c -r1.53 tupdesc.h
*** src/include/access/tupdesc.h	1 Jan 2008 19:45:56 -0000	1.53
--- src/include/access/tupdesc.h	1 Apr 2008 07:32:16 -0000
***************
*** 27,34 ****
  
  typedef struct constrCheck
  {
! 	char	   *ccname;
! 	char	   *ccbin;			/* nodeToString representation of expr */
  } ConstrCheck;
  
  /* This structure contains constraints of a tuple */
--- 27,36 ----
  
  typedef struct constrCheck
  {
! 	char	*ccname;
! 	char	*ccbin;			/* nodeToString representation of expr */
! 	bool	is_local;
! 	int		inhcount;
  } ConstrCheck;
  
  /* This structure contains constraints of a tuple */
Index: src/include/catalog/catversion.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/include/catalog/catversion.h,v
retrieving revision 1.444
diff -c -r1.444 catversion.h
*** src/include/catalog/catversion.h	23 Mar 2008 00:24:19 -0000	1.444
--- src/include/catalog/catversion.h	1 Apr 2008 07:32:16 -0000
***************
*** 53,58 ****
   */
  
  /*							yyyymmddN */
! #define CATALOG_VERSION_NO	200803222
  
  #endif
--- 53,58 ----
   */
  
  /*							yyyymmddN */
! #define CATALOG_VERSION_NO	200803290
  
  #endif
Index: src/include/catalog/indexing.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/include/catalog/indexing.h,v
retrieving revision 1.102
diff -c -r1.102 indexing.h
*** src/include/catalog/indexing.h	1 Jan 2008 19:45:56 -0000	1.102
--- src/include/catalog/indexing.h	1 Apr 2008 07:32:16 -0000
***************
*** 121,126 ****
--- 121,128 ----
  #define ConstraintTypidIndexId	2666
  DECLARE_UNIQUE_INDEX(pg_constraint_oid_index, 2667, on pg_constraint using btree(oid oid_ops));
  #define ConstraintOidIndexId  2667
+ DECLARE_UNIQUE_INDEX(pg_constraint_relid_coname_index, 2700, on pg_constraint using btree(conrelid oid_ops, conname name_ops));
+ #define ConstraintRelidNameIndexId  2700
  
  DECLARE_UNIQUE_INDEX(pg_conversion_default_index, 2668, on pg_conversion using btree(connamespace oid_ops, conforencoding int4_ops, contoencoding int4_ops, oid oid_ops));
  #define ConversionDefaultIndexId  2668
Index: src/include/catalog/pg_constraint.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/include/catalog/pg_constraint.h,v
retrieving revision 1.28
diff -c -r1.28 pg_constraint.h
*** src/include/catalog/pg_constraint.h	27 Mar 2008 03:57:34 -0000	1.28
--- src/include/catalog/pg_constraint.h	1 Apr 2008 07:32:16 -0000
***************
*** 71,76 ****
--- 71,82 ----
  	char		confdeltype;	/* foreign key's ON DELETE action */
  	char		confmatchtype;	/* foreign key's match type */
  
+ 	/* Has a local definition (hence, do not drop when coninhcount is 0) */
+ 	bool 		conislocal;
+ 
+ 	/* Number of times inherited from direct parent relation(s) */
+ 	int4 		coninhcount;
+ 
  	/*
  	 * VARIABLE LENGTH FIELDS start here.  These fields may be NULL, too.
  	 */
***************
*** 125,150 ****
   *		compiler constants for pg_constraint
   * ----------------
   */
! #define Natts_pg_constraint					18
! #define Anum_pg_constraint_conname			1
! #define Anum_pg_constraint_connamespace		2
! #define Anum_pg_constraint_contype			3
! #define Anum_pg_constraint_condeferrable	4
! #define Anum_pg_constraint_condeferred		5
! #define Anum_pg_constraint_conrelid			6
! #define Anum_pg_constraint_contypid			7
! #define Anum_pg_constraint_confrelid		8
! #define Anum_pg_constraint_confupdtype		9
! #define Anum_pg_constraint_confdeltype		10
! #define Anum_pg_constraint_confmatchtype	11
! #define Anum_pg_constraint_conkey			12
! #define Anum_pg_constraint_confkey			13
! #define Anum_pg_constraint_conpfeqop		14
! #define Anum_pg_constraint_conppeqop		15
! #define Anum_pg_constraint_conffeqop		16
! #define Anum_pg_constraint_conbin			17
! #define Anum_pg_constraint_consrc			18
! 
  
  /* Valid values for contype */
  #define CONSTRAINT_CHECK			'c'
--- 131,157 ----
   *		compiler constants for pg_constraint
   * ----------------
   */
! #define Natts_pg_constraint					20
! #define	Anum_pg_constraint_conname			1
! #define	Anum_pg_constraint_connamespace		2
! #define	Anum_pg_constraint_contype			3
! #define	Anum_pg_constraint_condeferrable	4
! #define	Anum_pg_constraint_condeferred		5
! #define	Anum_pg_constraint_conrelid			6
! #define	Anum_pg_constraint_contypid			7
! #define	Anum_pg_constraint_confrelid		8
! #define	Anum_pg_constraint_confupdtype		9
! #define	Anum_pg_constraint_confdeltype		10
! #define	Anum_pg_constraint_confmatchtype	11
! #define	Anum_pg_constraint_conislocal		12
! #define	Anum_pg_constraint_coninhcount		13
! #define	Anum_pg_constraint_conkey			14
! #define	Anum_pg_constraint_confkey			15
! #define	Anum_pg_constraint_conpfeqop		16
! #define	Anum_pg_constraint_conppeqop		17
! #define	Anum_pg_constraint_conffeqop		18
! #define	Anum_pg_constraint_conbin			19
! #define	Anum_pg_constraint_consrc			20
  
  /* Valid values for contype */
  #define CONSTRAINT_CHECK			'c'
***************
*** 192,198 ****
  					  Oid indexRelId,
  					  Node *conExpr,
  					  const char *conBin,
! 					  const char *conSrc);
  
  extern void RemoveConstraintById(Oid conId);
  extern void RenameConstraintById(Oid conId, const char *newname);
--- 199,207 ----
  					  Oid indexRelId,
  					  Node *conExpr,
  					  const char *conBin,
! 					  const char *conSrc,
! 					  const bool conIsLocal,
! 					  const int conInhCout);
  
  extern void RemoveConstraintById(Oid conId);
  extern void RenameConstraintById(Oid conId, const char *newname);
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.361
diff -c -r1.361 parsenodes.h
*** src/include/nodes/parsenodes.h	21 Mar 2008 22:41:48 -0000	1.361
--- src/include/nodes/parsenodes.h	1 Apr 2008 07:32:16 -0000
***************
*** 902,908 ****
  	AT_ProcessedConstraint,		/* pre-processed add constraint (local in
  								 * parser/parse_utilcmd.c) */
  	AT_DropConstraint,			/* drop constraint */
! 	AT_DropConstraintQuietly,	/* drop constraint, no error/warning (local in
  								 * commands/tablecmds.c) */
  	AT_AlterColumnType,			/* alter column type */
  	AT_ChangeOwner,				/* change owner */
--- 902,908 ----
  	AT_ProcessedConstraint,		/* pre-processed add constraint (local in
  								 * parser/parse_utilcmd.c) */
  	AT_DropConstraint,			/* drop constraint */
! 	AT_DropConstraintRecurse,	/* drop constraint recursion (local in
  								 * commands/tablecmds.c) */
  	AT_AlterColumnType,			/* alter column type */
  	AT_ChangeOwner,				/* change owner */
***************
*** 1165,1170 ****
--- 1165,1172 ----
  	List	   *options;		/* options from WITH clause */
  	char	   *indexspace;		/* index tablespace for PKEY/UNIQUE
  								 * constraints; NULL for default */
+ 	bool is_local;
+ 	int inhcount;
  } Constraint;
  
  /* ----------
Index: src/include/utils/syscache.h
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/include/utils/syscache.h,v
retrieving revision 1.71
diff -c -r1.71 syscache.h
*** src/include/utils/syscache.h	1 Jan 2008 19:45:59 -0000	1.71
--- src/include/utils/syscache.h	1 Apr 2008 07:32:16 -0000
***************
*** 28,81 ****
   *		Keep them in alphabetical order.
   */
  
! #define AGGFNOID			0
! #define AMNAME				1
! #define AMOID				2
! #define AMOPOPID			3
! #define AMOPSTRATEGY		4
! #define AMPROCNUM			5
! #define ATTNAME				6
! #define ATTNUM				7
! #define AUTHMEMMEMROLE		8
! #define AUTHMEMROLEMEM		9
! #define AUTHNAME			10
! #define AUTHOID				11
! #define CASTSOURCETARGET	12
! #define CLAAMNAMENSP		13
! #define CLAOID				14
! #define CONDEFAULT			15
! #define CONNAMENSP			16
! #define CONSTROID			17
! #define CONVOID				18
! #define DATABASEOID			19
! #define ENUMOID				20
! #define ENUMTYPOIDNAME		21
! #define INDEXRELID			22
! #define LANGNAME			23
! #define LANGOID				24
! #define NAMESPACENAME		25
! #define NAMESPACEOID		26
! #define OPERNAMENSP			27
! #define OPEROID				28
! #define OPFAMILYAMNAMENSP	29
! #define OPFAMILYOID			30
! #define PROCNAMEARGSNSP		31
! #define PROCOID				32
! #define RELNAMENSP			33
! #define RELOID				34
! #define RULERELNAME			35
! #define STATRELATT			36
! #define TSCONFIGMAP			37
! #define TSCONFIGNAMENSP		38
! #define TSCONFIGOID			39
! #define TSDICTNAMENSP		40
! #define TSDICTOID			41
! #define TSPARSERNAMENSP		42
! #define TSPARSEROID			43
! #define TSTEMPLATENAMENSP	44
! #define TSTEMPLATEOID		45
! #define TYPENAMENSP			46
! #define TYPEOID				47
  
  extern void InitCatalogCache(void);
  extern void InitCatalogCachePhase2(void);
--- 28,84 ----
   *		Keep them in alphabetical order.
   */
  
! enum SysCacheIdent {
! 	AGGFNOID = 0,
! 	AMNAME,
! 	AMOID,
! 	AMOPOPID,
! 	AMOPSTRATEGY,
! 	AMPROCNUM,
! 	ATTNAME,
! 	ATTNUM,
! 	AUTHMEMMEMROLE,
! 	AUTHMEMROLEMEM,
! 	AUTHNAME,
! 	AUTHOID,
! 	CASTSOURCETARGET,
! 	CLAAMNAMENSP,
! 	CLAOID,
! 	CONDEFAULT,
! 	CONNAMENSP,
! 	CONSTRNAME,
! 	CONSTROID,
! 	CONVOID,
! 	DATABASEOID,
! 	ENUMOID,
! 	ENUMTYPOIDNAME,
! 	INDEXRELID,
! 	LANGNAME,
! 	LANGOID,
! 	NAMESPACENAME,
! 	NAMESPACEOID,
! 	OPERNAMENSP,
! 	OPEROID,
! 	OPFAMILYAMNAMENSP,
! 	OPFAMILYOID,
! 	PROCNAMEARGSNSP,
! 	PROCOID,
! 	RELNAMENSP,
! 	RELOID,
! 	RULERELNAME,
! 	STATRELATT,
! 	TSCONFIGMAP,
! 	TSCONFIGNAMENSP,
! 	TSCONFIGOID,
! 	TSDICTNAMENSP,
! 	TSDICTOID,
! 	TSPARSERNAMENSP,
! 	TSPARSEROID,
! 	TSTEMPLATENAMENSP,
! 	TSTEMPLATEOID,
! 	TYPENAMENSP,
! 	TYPEOID,
! };
  
  extern void InitCatalogCache(void);
  extern void InitCatalogCachePhase2(void);
Index: src/test/regress/expected/alter_table.out
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/test/regress/expected/alter_table.out,v
retrieving revision 1.104
diff -c -r1.104 alter_table.out
*** src/test/regress/expected/alter_table.out	29 Oct 2007 21:31:28 -0000	1.104
--- src/test/regress/expected/alter_table.out	1 Apr 2008 07:32:16 -0000
***************
*** 383,391 ****
  create table atacc2 (test2 int);
  create table atacc3 (test3 int) inherits (atacc1, atacc2);
  alter table only atacc2 add constraint foo check (test2>0);
  -- fail and then succeed on atacc2
  insert into atacc2 (test2) values (-3);
- ERROR:  new row for relation "atacc2" violates check constraint "foo"
  insert into atacc2 (test2) values (3);
  -- both succeed on atacc3
  insert into atacc3 (test2) values (-3);
--- 383,391 ----
  create table atacc2 (test2 int);
  create table atacc3 (test3 int) inherits (atacc1, atacc2);
  alter table only atacc2 add constraint foo check (test2>0);
+ ERROR:  constraint must be added to children tables too
  -- fail and then succeed on atacc2
  insert into atacc2 (test2) values (-3);
  insert into atacc2 (test2) values (3);
  -- both succeed on atacc3
  insert into atacc3 (test2) values (-3);
Index: src/test/regress/expected/inherit.out
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/test/regress/expected/inherit.out,v
retrieving revision 1.23
diff -c -r1.23 inherit.out
*** src/test/regress/expected/inherit.out	1 Dec 2007 23:44:44 -0000	1.23
--- src/test/regress/expected/inherit.out	1 Apr 2008 07:32:16 -0000
***************
*** 692,694 ****
--- 692,770 ----
  drop table c1;
  drop table p2;
  drop table p1;
+ CREATE TABLE ac (aa TEXT);
+ alter table ac add constraint ac_check check (aa is not null);
+ CREATE TABLE bc (bb TEXT) INHERITS (ac);
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname  | contype | conislocal | coninhcount |      consrc      
+ ----------+---------+------------+-------------+------------------
+  ac_check | c       | t          |           0 | (aa IS NOT NULL)
+  ac_check | c       | f          |           1 | (aa IS NOT NULL)
+ (2 rows)
+ 
+ alter table bc drop constraint ac_check;
+ ERROR:  cannot drop inherited constraint "ac_check" of relation "bc"
+ alter table ac drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname | contype | conislocal | coninhcount | consrc 
+ ---------+---------+------------+-------------+--------
+ (0 rows)
+ 
+ alter table ac add constraint ac_check check (aa is not null);
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname  | contype | conislocal | coninhcount |      consrc      
+ ----------+---------+------------+-------------+------------------
+  ac_check | c       | t          |           0 | (aa IS NOT NULL)
+  ac_check | c       | f          |           1 | (aa IS NOT NULL)
+ (2 rows)
+ 
+ insert into ac (aa) values (NULL);
+ ERROR:  new row for relation "ac" violates check constraint "ac_check"
+ insert into bc (aa) values (NULL);
+ ERROR:  new row for relation "bc" violates check constraint "ac_check"
+ alter table bc drop constraint ac_check;
+ ERROR:  cannot drop inherited constraint "ac_check" of relation "bc"
+ alter table ac drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname | contype | conislocal | coninhcount | consrc 
+ ---------+---------+------------+-------------+--------
+ (0 rows)
+ 
+ alter table ac add constraint ac_check check (aa is not null);
+ alter table bc no inherit ac;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname  | contype | conislocal | coninhcount |      consrc      
+ ----------+---------+------------+-------------+------------------
+  ac_check | c       | t          |           0 | (aa IS NOT NULL)
+  ac_check | c       | t          |           0 | (aa IS NOT NULL)
+ (2 rows)
+ 
+ alter table bc drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname  | contype | conislocal | coninhcount |      consrc      
+ ----------+---------+------------+-------------+------------------
+  ac_check | c       | t          |           0 | (aa IS NOT NULL)
+ (1 row)
+ 
+ alter table ac drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname | contype | conislocal | coninhcount | consrc 
+ ---------+---------+------------+-------------+--------
+ (0 rows)
+ 
+ drop table bc;
+ drop table ac;
+ create table ac (a int constraint check_a check (a <> 0));
+ create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac);
+ NOTICE:  merging column "a" with inherited definition
+ NOTICE:  merging constraint "check_a" with inherited definition
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+  conname | contype | conislocal | coninhcount |  consrc  
+ ---------+---------+------------+-------------+----------
+  check_a | c       | t          |           0 | (a <> 0)
+  check_a | c       | f          |           1 | (a <> 0)
+  check_b | c       | t          |           0 | (b <> 0)
+ (3 rows)
+ 
+ drop table bc;
+ drop table ac;
Index: src/test/regress/sql/inherit.sql
===================================================================
RCS file: /repositories/postgreshome/cvs/pgsql/src/test/regress/sql/inherit.sql,v
retrieving revision 1.11
diff -c -r1.11 inherit.sql
*** src/test/regress/sql/inherit.sql	17 Jul 2007 05:02:03 -0000	1.11
--- src/test/regress/sql/inherit.sql	1 Apr 2008 07:32:16 -0000
***************
*** 196,198 ****
--- 196,236 ----
  drop table c1;
  drop table p2;
  drop table p1;
+ 
+ CREATE TABLE ac (aa TEXT);
+ alter table ac add constraint ac_check check (aa is not null);
+ CREATE TABLE bc (bb TEXT) INHERITS (ac);
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ 
+ alter table bc drop constraint ac_check;
+ alter table ac drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ 
+ alter table ac add constraint ac_check check (aa is not null);
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ 
+ insert into ac (aa) values (NULL);
+ insert into bc (aa) values (NULL);
+ 
+ alter table bc drop constraint ac_check;
+ alter table ac drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ 
+ alter table ac add constraint ac_check check (aa is not null);
+ alter table bc no inherit ac;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ alter table bc drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ alter table ac drop constraint ac_check;
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ 
+ drop table bc;
+ drop table ac;
+ 
+ create table ac (a int constraint check_a check (a <> 0));
+ create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac);
+ select pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by pc.relname;
+ 
+ 
+ drop table bc;
+ drop table ac;
