? config.log
? config.cache
? config.status
? dropcons.diff
? GNUmakefile
? log
? unique.diff
? src/GNUmakefile
? src/Makefile.global
? src/backend/commands/command.c.diff
? src/backend/port/Makefile
? src/include/config.h
? src/include/stamp-h
Index: src/backend/catalog/heap.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/catalog/heap.c,v
retrieving revision 1.166
diff -c -r1.166 heap.c
*** src/backend/catalog/heap.c	2001/05/30 12:57:36	1.166
--- src/backend/catalog/heap.c	2001/05/31 10:57:07
***************
*** 45,50 ****
--- 45,51 ----
  #include "catalog/pg_type.h"
  #include "commands/comment.h"
  #include "commands/trigger.h"
+ #include "commands/defrem.h" /* For RemoveUniqueConstraint */
  #include "miscadmin.h"
  #include "optimizer/clauses.h"
  #include "optimizer/planmain.h"
***************
*** 65,70 ****
--- 66,72 ----
  #include "utils/relcache.h"
  #include "utils/syscache.h"
  #include "utils/temprel.h"
+ #include "utils/acl.h" /* For RemoveUniqueConstraint */
  
  
  static void AddNewRelationTuple(Relation pg_class_desc,
***************
*** 2117,2122 ****
--- 2119,2198 ----
  
  	/* Close the heap relation */
  	heap_close(rcrel, RowExclusiveLock);
+ 
+ 	/* Return the number of tuples deleted */
+ 	return all_deleted;
+ }
+ 
+ /*
+  * Removes all UNIQUE constraints on a relation that match the given name.
+  * It is the responsibility of the calling function to acquire a lock on
+  * the relation.
+  * Returns: The number of UNIQUE constraints removed.
+  */
+ int
+ RemoveUniqueConstraint(Relation rel, const char *constrName, bool inh)
+ {
+ 	Oid			relid;
+ 	Relation	inhrel;
+ 	int			all_deleted = 0;
+ 
+ 	/* Find id of the relation */
+ 	relid = RelationGetRelid(rel);
+ 
+    /* Process child tables and remove constraints of the
+       same name.  This is currently disabled as it's
+ 	  impossible to have duplicated index names anyway */
+    inh = false; /* Disable inheritance */
+    if (inh)
+    {
+ 
+       List	*child,
+ 			*children;
+ 
+       /* This routine is actually in the planner */
+       children = find_all_inheritors(relid);
+ 
+       /*
+        * find_all_inheritors does the recursive search of the
+        * inheritance hierarchy, so all we have to do is process all
+        * of the relids in the list that it returns.
+        */
+       foreach(child, children)
+       {
+          Oid	childrelid = lfirsti(child);
+ 
+          if (childrelid == relid)
+             continue;
+ 
+ 		 /* @@ What locking to use here? @@ */
+          inhrel = heap_open(childrelid, AccessExclusiveLock);
+          all_deleted += RemoveUniqueConstraint(inhrel, constrName, false);
+          heap_close(inhrel, NoLock);
+       }
+    }
+ 
+ 	/* Delete index */
+ 	if (IsIndex(constrName, rel, true, false)) {
+ 
+ 		/* Check that we own the index */
+ 		if (!pg_ownercheck(GetUserId(), constrName, RELNAME))
+ 			elog(ERROR, "ALTER TABLE / DROP CONSTRAINT: You do not own '%s'",
+ 				 constrName);
+ 	
+ 		/* Check that it's not a system relation */
+ 		if (!allowSystemTableMods && IsSystemRelationName(constrName))
+ 			elog(ERROR, "ALTER TABLE / DROP CONSTRAINT: '%s' is a system relation",
+ 				 constrName);
+ 
+ 		/* Otherwise, we go ahead and drop the index */
+ 		/* @@ It's unfortunate that this cast is required @@ */
+ 		RemoveIndex((char *)constrName);
+ 
+ 		elog(NOTICE, "ALTER TABLE / DROP CONSTRAINT will remove implicit index '%s' for table '%s'",
+ 			constrName, RelationGetRelationName(rel));
+ 		++all_deleted;
+ 	}
  
  	/* Return the number of tuples deleted */
  	return all_deleted;
Index: src/backend/commands/command.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/commands/command.c,v
retrieving revision 1.131
diff -c -r1.131 command.c
*** src/backend/commands/command.c	2001/05/30 13:00:03	1.131
--- src/backend/commands/command.c	2001/05/31 10:57:12
***************
*** 1666,1671 ****
--- 1667,1679 ----
  	 */
  
  	deleted += RemoveCheckConstraint(rel, constrName, inh);
+ 
+ 	/*
+ 	 * Second, we remove all UNIQUE constraints with the given name
+ 	 */
+ 
+ 	CommandCounterIncrement();
+ 	deleted += RemoveUniqueConstraint(rel, constrName, inh);
  
  	/*
  	 * Now we remove NULL, PRIMARY KEY and FOREIGN KEY constraints.
Index: src/backend/commands/indexcmds.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/commands/indexcmds.c,v
retrieving revision 1.48
diff -c -r1.48 indexcmds.c
*** src/backend/commands/indexcmds.c	2001/05/30 20:52:32	1.48
--- src/backend/commands/indexcmds.c	2001/05/31 10:57:14
***************
*** 41,46 ****
--- 41,47 ----
  #include "utils/builtins.h"
  #include "utils/fmgroids.h"
  #include "utils/syscache.h"
+ #include "utils/relcache.h" /* For IsIndex */
  
  #define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL)
  
***************
*** 591,596 ****
--- 592,677 ----
  
  	ReleaseSysCache(tuple);
  	return result;
+ }
+ 
+ /*
+  * IsIndex
+  * 		Determines whether or not a named index on a particular 
+  *		relation, of a specified type, exists.
+  *
+  * Params:
+  *		name: The name of the index to look for
+  *		rel: The relation the index is on
+  *		unique: Restrict search to unique indices
+  *		primary: Restrict search to primary indicies (If you specify primary,
+  *					you will also almost always want to specify unique.)
+  *
+  * Returns:
+  *		True if an index with the given name and type exists on the 
+  *		specified table, false otherwise.
+  */
+ bool
+ IsIndex(const char *name, Relation rel, bool unique, bool primary)
+ {
+ 	Relation		pg_index;
+ 	Relation		index_rel;
+ 	Oid				index_oid;
+ 	HeapScanDesc	pg_index_scan;
+ 	HeapTuple		pg_index_tup;
+ 	ScanKeyData		key[4];
+ 	bool			found;
+ 
+ 	/* Get the relation representing the index */
+ 	index_rel = RelationNameGetRelation(name);
+ 
+ 	/* Does the name exist at all? */
+ 	if (!RelationIsValid(index_rel)) return false;
+ 
+ 	/* Is the named relation an index? */
+ 	if (index_rel->rd_rel->relkind != RELKIND_INDEX) return false;
+ 
+ 	/* Open the system catalog index relation */
+ 	pg_index = heap_openr(IndexRelationName, AccessShareLock);
+ 
+ 	/* Grab the oid of the index.  The relation should be valid, as we've checked above. */
+ 	index_oid = RelationGetRelid(index_rel);
+ 
+ 	/*
+ 	 * Create three scan keys.  We need to match on the oid of
+ 	 * the index, if it's unique and if it's primary.
+ 	 */
+ 	ScanKeyEntryInitialize(&key[0], 0, Anum_pg_index_indexrelid,
+ 						   F_OIDEQ, ObjectIdGetDatum(index_oid));
+ 
+ 	ScanKeyEntryInitialize(&key[1], 0, Anum_pg_index_indrelid,
+ 						   F_OIDEQ, RelationGetRelid(rel));
+ 
+ 	ScanKeyEntryInitialize(&key[2], 0, Anum_pg_index_indisunique,
+ 						   F_BOOLEQ, BoolGetDatum(unique));
+ 
+ 	ScanKeyEntryInitialize(&key[3], 0, Anum_pg_index_indisprimary,
+ 						   F_BOOLEQ, BoolGetDatum(primary));
+ 
+ 	/* Begin scanning the heap */
+ 	pg_index_scan = heap_beginscan(pg_index, 0, SnapshotNow, 4, key);
+ 
+ 	/* Scan over the index table.  If we find anything - report success. */
+ 	found = false;
+ 	while (HeapTupleIsValid(pg_index_tup = heap_getnext(pg_index_scan, false))) {
+ 		found = true;
+ 		break;
+ 	}
+ 
+ 	/* Clean up after */
+ 	heap_endscan(pg_index_scan);
+ 	/* Should I be releasing this?  I don't think so because what if someone renames the index
+ 	 * or something before I drop it? */
+ 	heap_close(pg_index, AccessShareLock);
+ 
+ 	/* @@ Do I need this? @@ */
+ 	RelationClose(index_rel);
+ 
+ 	return found;
  }
  
  /*
Index: src/include/catalog/heap.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/catalog/heap.h,v
retrieving revision 1.36
diff -c -r1.36 heap.h
*** src/include/catalog/heap.h	2001/05/30 12:57:36	1.36
--- src/include/catalog/heap.h	2001/05/31 10:57:18
***************
*** 46,52 ****
  						  List *rawConstraints);
  
  extern int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);
! 
  
  extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno);
  
--- 46,52 ----
  						  List *rawConstraints);
  
  extern int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);
! extern int RemoveUniqueConstraint(Relation rel, const char *constrName, bool inh);
  
  extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno);
  
Index: src/include/commands/defrem.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/commands/defrem.h,v
retrieving revision 1.22
diff -c -r1.22 defrem.h
*** src/include/commands/defrem.h	2001/01/24 19:43:23	1.22
--- src/include/commands/defrem.h	2001/05/31 10:57:18
***************
*** 18,24 ****
  #include "tcop/dest.h"
  
  /*
!  * prototypes in defind.c
   */
  extern void DefineIndex(char *heapRelationName,
  			char *indexRelationName,
--- 18,24 ----
  #include "tcop/dest.h"
  
  /*
!  * prototypes in indexcmds.c
   */
  extern void DefineIndex(char *heapRelationName,
  			char *indexRelationName,
***************
*** 32,37 ****
--- 32,38 ----
  extern void ExtendIndex(char *indexRelationName,
  			Expr *predicate,
  			List *rangetable);
+ extern bool IsIndex(const char *name, Relation rel, bool unique, bool primary);
  extern void RemoveIndex(char *name);
  extern void ReindexIndex(const char *indexRelationName, bool force);
  extern void ReindexTable(const char *relationName, bool force);
