? src/backend/access/common/.deps
? src/backend/access/gist/.deps
? src/backend/access/hash/.deps
? src/backend/access/heap/.deps
? src/backend/access/index/.deps
? src/backend/access/nbtree/.deps
? src/backend/access/rtree/.deps
? src/backend/access/transam/.deps
? src/backend/bootstrap/.deps
? src/backend/catalog/.deps
? src/backend/catalog/pg_constraint.c
? src/backend/catalog/pg_depend.c
? src/backend/commands/.deps
? src/backend/executor/.deps
? src/backend/lib/.deps
? src/backend/libpq/.deps
? src/backend/main/.deps
? src/backend/nodes/.deps
? src/backend/optimizer/geqo/.deps
? src/backend/optimizer/path/.deps
? src/backend/optimizer/plan/.deps
? src/backend/optimizer/prep/.deps
? src/backend/optimizer/util/.deps
? src/backend/parser/.deps
? src/backend/port/.deps
? src/backend/postmaster/.deps
? src/backend/regex/.deps
? src/backend/rewrite/.deps
? src/backend/storage/buffer/.deps
? src/backend/storage/file/.deps
? src/backend/storage/freespace/.deps
? src/backend/storage/ipc/.deps
? src/backend/storage/large_object/.deps
? src/backend/storage/lmgr/.deps
? src/backend/storage/page/.deps
? src/backend/storage/smgr/.deps
? src/backend/tcop/.deps
? src/backend/utils/.deps
? src/backend/utils/adt/.deps
? src/backend/utils/cache/.deps
? src/backend/utils/error/.deps
? src/backend/utils/fmgr/.deps
? src/backend/utils/hash/.deps
? src/backend/utils/init/.deps
? src/backend/utils/mb/.deps
? src/backend/utils/misc/.deps
? src/backend/utils/mmgr/.deps
? src/backend/utils/sort/.deps
? src/backend/utils/time/.deps
? src/bin/pg_dump/.deps
? src/bin/pg_encoding/.deps
? src/bin/pg_id/.deps
? src/bin/pg_passwd/pg_passwd
? src/bin/psql/.deps
? src/include/catalog/pg_constraint.h
? src/include/catalog/pg_depend.h
? src/interfaces/ecpg/lib/.deps
? src/interfaces/ecpg/preproc/.deps
? src/interfaces/libpgeasy/.deps
? src/interfaces/libpq/.deps
? src/pl/plpgsql/src/.deps
? src/test/regress/expected/drop.out
? src/test/regress/sql/.alter_table.sql.swo
? src/test/regress/sql/.alter_table.sql.swp
Index: doc/src/sgml/catalogs.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v
retrieving revision 2.43
diff -c -r2.43 catalogs.sgml
*** doc/src/sgml/catalogs.sgml	2002/04/21 00:26:42	2.43
--- doc/src/sgml/catalogs.sgml	2002/06/15 16:37:46
***************
*** 72,82 ****
--- 72,92 ----
       </row>
  
       <row>
+       <entry>pg_constraint</entry>
+       <entry>check constraints, unique / primary key constraints, foreign key constraints</entry>
+      </row>
+ 
+      <row>
        <entry>pg_database</entry>
        <entry>databases within this database cluster</entry>
       </row>
  
       <row>
+       <entry>pg_depend</entry>
+       <entry>dependencies between database objects</entry>
+      </row>
+ 
+      <row>
        <entry>pg_description</entry>
        <entry>descriptions or comments on database objects</entry>
       </row>
***************
*** 132,142 ****
       </row>
  
       <row>
-       <entry>pg_relcheck</entry>
-       <entry>check constraints</entry>
-      </row>
- 
-      <row>
        <entry>pg_rewrite</entry>
        <entry>query rewriter rules</entry>
       </row>
--- 142,147 ----
***************
*** 680,686 ****
        <entry></entry>
        <entry>
         Number of check constraints on the table; see
!        <structname>pg_relcheck</structname> catalog
        </entry>
       </row>
  
--- 685,691 ----
        <entry></entry>
        <entry>
         Number of check constraints on the table; see
!        <structname>pg_constraint</structname> catalog
        </entry>
       </row>
  
***************
*** 764,770 ****
--- 769,908 ----
    </table>
   </sect1>
  
+  <sect1 id="catalog-pg-constraint">
+   <title>pg_constraint</title>
+ 
+   <para>
+    This system catalog stores CHECK, PRIMARY KEY, UNIQUE, and FOREIGN KEY
+    constraints on tables.  (Column
+    constraints are not treated specially.  Every column constraint is
+    equivalent to some table constraint.)  See under <command>CREATE
+    TABLE</command> for more information.
+    <note>
+      NOT NULL Constraints are handled by the <link linkend="catalog-pg-attribute">pg_attribute</link> table.
+    </note>
+   </para>
+ 
+   <table>
+    <title>pg_constraint Columns</title>
+ 
+    <tgroup cols=4>
+     <thead>
+      <row>
+       <entry>Name</entry>
+       <entry>Type</entry>
+       <entry>References</entry>
+       <entry>Description</entry>
+      </row>
+     </thead>
+ 
+     <tbody>
+      <row>
+       <entry>conrelid</entry>
+       <entry><type>oid</type></entry>
+       <entry>pg_class.oid</entry>
+       <entry>The table this constraint is on</entry>
+      </row>
+ 
+      <row>
+       <entry>conname</entry>
+       <entry><type>name</type></entry>
+       <entry></entry>
+       <entry>Constraint name</entry>
+      </row>
+ 
+      <row>
+       <entry>contype</entry>
+       <entry><type>char</type></entry>
+       <entry></entry>
+       <entry>
+         'u' = unique constraint, 'p' = primary key, 'f' = foreign key constraint,
+         'c' = check constraint
+       </entry>
+      </row>
+ 
+      <row>
+       <entry>condeferrable</entry>
+       <entry><type>boolean</type></entry>
+       <entry></entry>
+       <entry>Is the constraint is deferrable?</entry>
+      </row>
+ 
+      <row>
+       <entry>condeferred</entry>
+       <entry><type>boolean</type></entry>
+       <entry></entry>
+       <entry>Is the constraint deferred by default?</entry>
+      </row>
+ 
+      <row>
+       <entry>conkey</entry>
+       <entry><type>smallint[]</type></entry>
+       <entry>pg_attribute.attnum</entry>
+       <entry>List of columns to which the constraint is applied</entry>
+      </row>
+ 
+      <row>
+       <entry>confrelid</entry>
+       <entry><type>oid</type></entry>
+       <entry>pg_class.oid</entry>
+       <entry>The table to which the foreign key refers to</entry>
+      </row>
+ 
+      <row>
+       <entry>confkey</entry>
+       <entry><type>smallint[]</type></entry>
+       <entry>pg_attribute.attnum</entry>
+       <entry>List of columns which the foreign key constraint refers to</entry>
+      </row>
+ 
+      <row>
+       <entry>confupdtype</entry>
+       <entry><type>char</type></entry>
+       <entry></entry>
+       <entry>Foreign key update type</entry>
+      </row>
+ 
+      <row>
+       <entry>confdeltype</entry>
+       <entry><type>char</type></entry>
+       <entry></entry>
+       <entry>Foreign key deletion type</entry>
+      </row>
  
+      <row>
+       <entry>confmatchtype</entry>
+       <entry><type>oid</type></entry>
+       <entry>pg_class.oid</entry>
+       <entry>Foreign key match type.  </entry>
+      </row>
+ 
+      <row>
+       <entry>conbin</entry>
+       <entry><type>text</type></entry>
+       <entry></entry>
+       <entry>An internal representation of the check constraint expression</entry>
+      </row>
+ 
+      <row>
+       <entry>consrc</entry>
+       <entry><type>text</type></entry>
+       <entry></entry>
+       <entry>A human-readable representation of the check constraint expression</entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </table>
+ 
+   <note>
+    <para>
+     <structname>pg_class</structname>.<structfield>relchecks</structfield>
+     needs to match up with the entries in this table.
+    </para>
+   </note>
+ 
+  </sect1>
+ 
   <sect1 id="catalog-pg-database">
    <title>pg_database</title>
  
***************
*** 903,908 ****
--- 1041,1133 ----
   </sect1>
  
  
+  <sect1 id="catalog-pg-depend">
+   <title>pg_depend</title>
+ 
+   <para>
+    The pg_depend table stores the dependency tree between database
+    objects which enables RESTRICT and CASCADE on <command>DROP</command> statements to
+    function properly.
+   </para>
+ 
+   <table>
+    <title>pg_depend Columns</title>
+ 
+    <tgroup cols=4>
+     <thead>
+      <row>
+       <entry>Name</entry>
+       <entry>Type</entry>
+       <entry>References</entry>
+       <entry>Description</entry>
+      </row>
+     </thead>
+ 
+     <tbody>
+      <row>
+       <entry>classid</entry>
+       <entry><type>oid</type></entry>
+       <entry>pg_class.oid</entry>
+       <entry>The oid of the system catalog this depender is in.</entry>
+      </row>
+ 
+      <row>
+       <entry>objid</entry>
+       <entry><type>oid</type></entry>
+       <entry>any oid attribute</entry>
+       <entry>The oid of the object this depender pertains to</entry>
+      </row>
+ 
+      <row>
+       <entry>objsubid</entry>
+       <entry><type>integer</type></entry>
+       <entry></entry>
+       <entry>For a dependency on a table attribute, this is the attribute's
+        column number (the objid and classid refer to the table itself).
+        For all other object types, this field is presently zero.
+       </entry>
+      </row>
+ 
+      <row>
+       <entry>depclassid</entry>
+       <entry><type>oid</type></entry>
+       <entry>pg_class.oid</entry>
+       <entry>The oid of the system catalog this dependee is in.</entry>
+      </row>
+ 
+      <row>
+       <entry>depobjid</entry>
+       <entry><type>oid</type></entry>
+       <entry>any oid attribute</entry>
+       <entry>The oid of the object this dependee pertains to</entry>
+      </row>
+ 
+      <row>
+       <entry>depobjsubid</entry>
+       <entry><type>integer</type></entry>
+       <entry></entry>
+       <entry>For a dependee of a table attribute, this is the attribute's
+        column number (the objid and classid refer to the table itself).
+        For all other object types, this field is presently zero.
+       </entry>
+      </row>
+ 
+      <row>
+       <entry>alwayscascade</entry>
+       <entry><type>boolean</type></entry>
+       <entry></entry>
+       <entry>For implicit dependencies which should ignore the RESTRICT keyword
+         and be cascaded to anyway. A table to its complex type, or a primary key 
+         constraint to the index which enforces the uniqueness portion</entry>
+      </row>
+ 
+     </tbody>
+    </tgroup>
+   </table>
+ 
+  </sect1>
+ 
+ 
   <sect1 id="catalog-pg-description">
    <title>pg_description</title>
  
***************
*** 1853,1924 ****
    </para>
  
   </sect1>
- 
- 
-  <sect1 id="catalog-pg-relcheck">
-   <title>pg_relcheck</title>
- 
-   <para>
-    This system catalog stores CHECK constraints on tables.  (Column
-    constraints are not treated specially.  Every column constraint is
-    equivalent to some table constraint.)  See under <command>CREATE
-    TABLE</command> for more information.
-   </para>
- 
-   <table>
-    <title>pg_relcheck Columns</title>
- 
-    <tgroup cols=4>
-     <thead>
-      <row>
-       <entry>Name</entry>
-       <entry>Type</entry>
-       <entry>References</entry>
-       <entry>Description</entry>
-      </row>
-     </thead>
- 
-     <tbody>
-      <row>
-       <entry>rcrelid</entry>
-       <entry><type>oid</type></entry>
-       <entry>pg_class.oid</entry>
-       <entry>The table this check constraint is on</entry>
-      </row>
- 
-      <row>
-       <entry>rcname</entry>
-       <entry><type>name</type></entry>
-       <entry></entry>
-       <entry>Constraint name</entry>
-      </row>
- 
-      <row>
-       <entry>rcbin</entry>
-       <entry><type>text</type></entry>
-       <entry></entry>
-       <entry>An internal representation of the constraint expression</entry>
-      </row>
- 
-      <row>
-       <entry>rcsrc</entry>
-       <entry><type>text</type></entry>
-       <entry></entry>
-       <entry>A human-readable representation of the constraint expression</entry>
-      </row>
-     </tbody>
-    </tgroup>
-   </table>
- 
-   <note>
-    <para>
-     <structname>pg_class</structname>.<structfield>relchecks</structfield>
-     needs to match up with the entries in this table.
-    </para>
-   </note>
- 
-  </sect1>
- 
  
   <sect1 id="catalog-pg-rewrite">
    <title>pg_rewrite</title>
--- 2078,2083 ----
Index: doc/src/sgml/ref/comment.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v
retrieving revision 1.19
diff -c -r1.19 comment.sgml
*** doc/src/sgml/ref/comment.sgml	2002/05/13 17:45:30	1.19
--- doc/src/sgml/ref/comment.sgml	2002/06/15 16:37:46
***************
*** 26,31 ****
--- 26,32 ----
    TABLE <replaceable class="PARAMETER">object_name</replaceable> |
    COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
    AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable>) |
+   CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
    DATABASE <replaceable class="PARAMETER">object_name</replaceable> |
    DOMAIN <replaceable class="PARAMETER">object_name</replaceable> |
    FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1_type</replaceable>, <replaceable class="PARAMETER">arg2_type</replaceable>, ...) |
Index: doc/src/sgml/ref/drop_aggregate.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_aggregate.sgml,v
retrieving revision 1.18
diff -c -r1.18 drop_aggregate.sgml
*** doc/src/sgml/ref/drop_aggregate.sgml	2002/05/18 15:44:47	1.18
--- doc/src/sgml/ref/drop_aggregate.sgml	2002/06/15 16:37:46
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP AGGREGATE <replaceable class="PARAMETER">name</replaceable> ( <replaceable class="PARAMETER">type</replaceable> )
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPAGGREGATE-1">
--- 21,27 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP AGGREGATE <replaceable class="PARAMETER">name</replaceable> ( <replaceable class="PARAMETER">type</replaceable> ) [ CASCADE | RESTRICT ]
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPAGGREGATE-1">
***************
*** 51,56 ****
--- 51,76 ----
  	further information about data types.)
  	<comment>This should become a cross-reference rather than a
  	 hard-coded chapter number</comment>
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only an aggregate with no dependent database objects
+         can be destroyed.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing database objects
+         will also be dropped.
         </para>
        </listitem>
       </varlistentry>
Index: doc/src/sgml/ref/drop_function.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_function.sgml,v
retrieving revision 1.20
diff -c -r1.20 drop_function.sgml
*** doc/src/sgml/ref/drop_function.sgml	2002/05/18 15:44:47	1.20
--- doc/src/sgml/ref/drop_function.sgml	2002/06/15 16:37:46
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">type</replaceable> [, ...] ] )
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPFUNCTION-1">
--- 21,27 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">type</replaceable> [, ...] ] ) [ CASCADE | RESTRICT ]
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPFUNCTION-1">
***************
*** 46,51 ****
--- 46,71 ----
        <listitem>
         <para>
  	The type of a parameter of the function.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only a function with no dependent types or operators
+         can be destroyed.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing types or operators
+         will also be dropped.
         </para>
        </listitem>
       </varlistentry>
Index: doc/src/sgml/ref/drop_index.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_index.sgml,v
retrieving revision 1.15
diff -c -r1.15 drop_index.sgml
*** doc/src/sgml/ref/drop_index.sgml	2002/05/18 15:44:47	1.15
--- doc/src/sgml/ref/drop_index.sgml	2002/06/15 16:37:46
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP INDEX <replaceable class="PARAMETER">index_name</replaceable> [, ...]
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPINDEX-1">
--- 21,27 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP INDEX <replaceable class="PARAMETER">index_name</replaceable> [, ...] [ CASCADE | RESTRICT ]
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPINDEX-1">
Index: doc/src/sgml/ref/drop_language.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_language.sgml,v
retrieving revision 1.14
diff -c -r1.14 drop_language.sgml
*** doc/src/sgml/ref/drop_language.sgml	2002/05/18 15:44:47	1.14
--- doc/src/sgml/ref/drop_language.sgml	2002/06/15 16:37:46
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP [ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">name</replaceable>
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPLANGUAGE-1">
--- 21,27 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP [ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">name</replaceable> [ CASCADE | RESTRICT ]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPLANGUAGE-1">
***************
*** 44,49 ****
--- 44,70 ----
        </listitem>
       </varlistentry>
      </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only a language with no dependent functions
+         can be destroyed.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing functions
+         will also be dropped.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+ 
     </para>
    </refsect2>
    
Index: doc/src/sgml/ref/drop_operator.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_operator.sgml,v
retrieving revision 1.16
diff -c -r1.16 drop_operator.sgml
*** doc/src/sgml/ref/drop_operator.sgml	2002/05/18 15:44:47	1.16
--- doc/src/sgml/ref/drop_operator.sgml	2002/06/15 16:37:47
***************
*** 22,28 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP OPERATOR <replaceable class="PARAMETER">id</replaceable> ( <replaceable class="PARAMETER">lefttype</replaceable> | NONE , <replaceable class="PARAMETER">righttype</replaceable> | NONE )
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPOPERATOR-1">
--- 22,28 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP OPERATOR <replaceable class="PARAMETER">id</replaceable> ( <replaceable class="PARAMETER">lefttype</replaceable> | NONE , <replaceable class="PARAMETER">righttype</replaceable> | NONE ) [ CASCADE | RESTRICT ]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPOPERATOR-1">
Index: doc/src/sgml/ref/drop_rule.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_rule.sgml,v
retrieving revision 1.15
diff -c -r1.15 drop_rule.sgml
*** doc/src/sgml/ref/drop_rule.sgml	2002/05/18 15:44:47	1.15
--- doc/src/sgml/ref/drop_rule.sgml	2002/06/15 16:37:51
***************
*** 21,27 ****
     <date>1998-09-22</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">relation</replaceable>
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPRULE-1">
--- 21,27 ----
     <date>1998-09-22</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">relation</replaceable> [ CASCADE | RESTRICT ]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPRULE-1">
***************
*** 51,56 ****
--- 51,77 ----
        </listitem>
       </varlistentry>
      </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only a rule with no dependent database objects
+         can be destroyed.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing database objects
+         will also be dropped.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+ 
     </para>
    </refsect2>
  
Index: doc/src/sgml/ref/drop_sequence.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_sequence.sgml,v
retrieving revision 1.14
diff -c -r1.14 drop_sequence.sgml
*** doc/src/sgml/ref/drop_sequence.sgml	2002/05/18 15:44:47	1.14
--- doc/src/sgml/ref/drop_sequence.sgml	2002/06/15 16:37:51
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP SEQUENCE <replaceable class="PARAMETER">name</replaceable> [, ...]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPSEQUENCE-1">
--- 21,28 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP SEQUENCE <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
! 
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPSEQUENCE-1">
***************
*** 76,81 ****
--- 77,102 ----
        </listitem>
       </varlistentry>
      </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only a sequence dependent tables can be destroyed.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing tables
+         will also be dropped.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+ 
     </para>
    </refsect2>
   </refsynopsisdiv>
Index: doc/src/sgml/ref/drop_table.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_table.sgml,v
retrieving revision 1.15
diff -c -r1.15 drop_table.sgml
*** doc/src/sgml/ref/drop_table.sgml	2002/05/18 15:44:47	1.15
--- doc/src/sgml/ref/drop_table.sgml	2002/06/15 16:37:51
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP TABLE <replaceable class="PARAMETER">name</replaceable> [, ...]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPTABLE-1">
--- 21,28 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP TABLE <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
! 
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPTABLE-1">
***************
*** 42,47 ****
--- 43,73 ----
        </listitem>
       </varlistentry>
      </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only a table with no dependent views or
+         integrity constraints can be destroyed.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing views or integrity constraints
+         will also be dropped.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+    </refsect2>
+  </refsect1>
+ </refentry>
+ 
+ 
     </para>
    </refsect2>
  
***************
*** 135,182 ****
     Compatibility
    </title>
    
-   <refsect2 id="R2-SQL-DROPTABLE-4">
-    <refsect2info>
-     <date>1998-09-22</date>
-    </refsect2info>
-    <title>
-     SQL92
-    </title>
-    <para>
-     SQL92 specifies some additional capabilities for DROP TABLE:
-    </para>
-    <synopsis>
- DROP TABLE <replaceable class="parameter">table</replaceable> { RESTRICT | CASCADE }
-    </synopsis>
-    <variablelist>
-     <varlistentry>
-      <term>RESTRICT</term>
-      <listitem>
-       <para>
-        Ensures that only a table with no dependent views or
-        integrity constraints can be destroyed.
-       </para>
-      </listitem>
-     </varlistentry>
-     <varlistentry>
-      <term>CASCADE</term>
-      <listitem>
-       <para>
-        Any referencing views or integrity constraints
-        will also be dropped.
-       </para>
-      </listitem>
-     </varlistentry>
-    </variablelist>
-     <tip>
-     <para>
-      At present, to remove a referencing view you must drop
-      it explicitly.
-     </para>
-    </tip>
-    </refsect2>
-  </refsect1>
- </refentry>
  
  <!-- Keep this comment at the end of the file
  Local variables:
--- 161,166 ----
Index: doc/src/sgml/ref/drop_trigger.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_trigger.sgml,v
retrieving revision 1.12
diff -c -r1.12 drop_trigger.sgml
*** doc/src/sgml/ref/drop_trigger.sgml	2002/05/18 15:44:47	1.12
--- doc/src/sgml/ref/drop_trigger.sgml	2002/06/15 16:37:51
***************
*** 21,27 ****
     <date>1998-09-22</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP TRIGGER <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table</replaceable>
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPTRIGGER-1">
--- 21,27 ----
     <date>1998-09-22</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP TRIGGER <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table</replaceable> [ CASCADE | RESTRICT ]
    </synopsis>
  
    <refsect2 id="R2-SQL-DROPTRIGGER-1">
***************
*** 47,52 ****
--- 47,72 ----
        <listitem>
         <para>
  	The name (optionally schema-qualified) of a table.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only a trigger with no dependent database objects
+         can be destroyed.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing system objects
+         will also be dropped.
         </para>
        </listitem>
       </varlistentry>
Index: doc/src/sgml/ref/drop_type.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_type.sgml,v
retrieving revision 1.17
diff -c -r1.17 drop_type.sgml
*** doc/src/sgml/ref/drop_type.sgml	2002/05/18 15:44:47	1.17
--- doc/src/sgml/ref/drop_type.sgml	2002/06/15 16:37:51
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP TYPE <replaceable class="PARAMETER">typename</replaceable> [, ...]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPTYPE-1">
--- 21,28 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP TYPE <replaceable class="PARAMETER">typename</replaceable> [, ...] [ CASCADE | RESTRICT ]
! 
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPTYPE-1">
***************
*** 75,80 ****
--- 76,102 ----
        </listitem>
       </varlistentry>
      </variablelist>
+     <variablelist>
+      <varlistentry>
+       <term>RESTRICT</term>
+       <listitem>
+        <para>
+         Ensures that only a type which is not used in tables, views, domains, functions, etc. 
+         will be allowed to be dropped.
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>CASCADE</term>
+       <listitem>
+        <para>
+         Any referencing tables, views, domains, functions, etc.
+         will also be dropped.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+ 
     </para>
    </refsect2>
   </refsynopsisdiv>
***************
*** 131,149 ****
  
   <refsect1 id="SQL-DROPTYPE-compatibility">
    <title>Compatibility</title>
- 
-   <para>
-    A <command>DROP TYPE</command> statement exists in SQL99.  As with
-    most other <quote>drop</quote> commands, <command>DROP
-    TYPE</command> in SQL99 requires a <quote>drop behavior</quote>
-    clause to select between dropping all dependent objects or refusing
-    to drop if dependent objects exist:
- <synopsis>
- DROP TYPE <replaceable>name</replaceable> { CASCADE | RESTRICT }
- </synopsis>
-    <productname>PostgreSQL</productname> currently ignores
-    dependencies altogether.
-   </para>
  
    <para>
     Note that the <command>CREATE TYPE</command> command and the data
--- 153,158 ----
Index: doc/src/sgml/ref/drop_view.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/drop_view.sgml,v
retrieving revision 1.14
diff -c -r1.14 drop_view.sgml
*** doc/src/sgml/ref/drop_view.sgml	2002/05/18 15:44:47	1.14
--- doc/src/sgml/ref/drop_view.sgml	2002/06/15 16:37:51
***************
*** 21,27 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP VIEW <replaceable class="PARAMETER">name</replaceable> [, ...]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPVIEW-1">
--- 21,27 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! DROP VIEW <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
    </synopsis>
    
    <refsect2 id="R2-SQL-DROPVIEW-1">
***************
*** 43,48 ****
--- 43,70 ----
        </listitem>
       </varlistentry>
      </variablelist>
+      <variablelist>
+       <varlistentry>
+        <term>RESTRICT</term>
+        <listitem>
+ 	<para>
+ 	 Ensures that only a view with no dependent views or
+ 	 integrity constraints can be destroyed.
+ 	</para>
+        </listitem>
+       </varlistentry>
+       <varlistentry>
+        <term>CASCADE</term>
+        <listitem>
+ 	<para>
+ 	 Any referencing views and integrity constraints
+ 	 will be dropped as well.
+ 	</para>
+        </listitem>
+       </varlistentry>
+      </variablelist>
+     </variablelist>
+ 
     </para>
    </refsect2>
  
***************
*** 133,178 ****
     <title>
      SQL92
     </title>
!    <para>
!     <acronym>SQL92</acronym> specifies some additional capabilities for
!     <command>DROP VIEW</command>:
!    
!     <synopsis>
! DROP VIEW <replaceable class="parameter">view</replaceable> { RESTRICT | CASCADE }
!     </synopsis>
!    </para>
! 
!    <refsect3 id="R3-SQL-DROPVIEW-1">
!     <refsect3info>
!      <date>1998-09-22</date>
!     </refsect3info>
!     <title>
!      Inputs
!     </title>
!     <para>
!      <variablelist>
!       <varlistentry>
!        <term>RESTRICT</term>
!        <listitem>
! 	<para>
! 	 Ensures that only a view with no dependent views or
! 	 integrity constraints can be destroyed.
! 	</para>
!        </listitem>
!       </varlistentry>
!       <varlistentry>
!        <term>CASCADE</term>
!        <listitem>
! 	<para>
! 	 Any referencing views and integrity constraints
! 	 will be dropped as well.
! 	</para>
!        </listitem>
!       </varlistentry>
!      </variablelist>
!     </para>
!    </refsect3>
! 
    <refsect3 id="R3-SQL-DROPVIEW-2">
     <refsect3info>
      <date>1998-09-22</date>
--- 155,161 ----
     <title>
      SQL92
     </title>
!  
    <refsect3 id="R3-SQL-DROPVIEW-2">
     <refsect3info>
      <date>1998-09-22</date>
Index: src/backend/catalog/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/Makefile,v
retrieving revision 1.39
diff -c -r1.39 Makefile
*** src/backend/catalog/Makefile	2002/03/26 19:15:22	1.39
--- src/backend/catalog/Makefile	2002/06/15 16:37:51
***************
*** 12,18 ****
  
  OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \
         pg_aggregate.o pg_largeobject.o pg_namespace.o \
!        pg_operator.o pg_proc.o pg_type.o
  
  BKIFILES = postgres.bki postgres.description
  
--- 12,18 ----
  
  OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \
         pg_aggregate.o pg_largeobject.o pg_namespace.o \
!        pg_operator.o pg_proc.o pg_type.o pg_depend.o pg_constraint.o
  
  BKIFILES = postgres.bki postgres.description
  
***************
*** 26,33 ****
  # indexing.h had better be last.
  
  POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
! 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
! 	pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \
  	pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
  	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
  	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h \
--- 26,33 ----
  # indexing.h had better be last.
  
  POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
! 	pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_depend.h \
! 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h \
  	pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
  	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
  	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h \
Index: src/backend/catalog/genbki.sh
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/genbki.sh,v
retrieving revision 1.27
diff -c -r1.27 genbki.sh
*** src/backend/catalog/genbki.sh	2002/04/27 21:24:33	1.27
--- src/backend/catalog/genbki.sh	2002/06/15 16:37:51
***************
*** 224,229 ****
--- 224,233 ----
  	comment_level = 0;
  	nextbkioid = ENVIRON["BKIOBJECTID"];
  	oid = 0;
+ 	pin = "";
+ 	pindata[-1] = "";
+ 	pinoid = 0;
+ 	pinwrite = "";
  }
  
  # ----------------
***************
*** 251,256 ****
--- 255,264 ----
  #	stripping off the DATA( and the ) on the end.  However,
  #	if we see "OID = 0" then we should assign an oid from nextbkioid.
  #	Remember any explicit or assigned OID for use by DESCR().
+ #
+ #	If this is a base table with a PIN id recorded, dump the dependency
+ #	information to a depend file which will be appended onto the data
+ #	for the pg_depend table.
  # ----------------
  /^DATA\(/ {
  	data = substr($0, 6, length($0) - 6);
***************
*** 265,270 ****
--- 273,285 ----
  			nextbkioid++;
  			sub("OID *= *0", "OID = " oid, data);
  		}
+ 
+ 		if (pin != "")
+ 		{
+ 			pinoid = pincount;
+ 			pindata[pinoid] = sprintf("insert (%d %d 0 0 0 0 f)", pin, oid);
+ 			pincount++;
+ 		}
  	}
  	print data;
  	next;
***************
*** 285,290 ****
--- 300,306 ----
  #  end any prior catalog data insertions before starting a define index
  # ----
  	if (reln_open == 1) {
+ 		pinwritedata(pinwrite);
  #		print "show";
  		print "close " catalog;
  		reln_open = 0;
***************
*** 299,304 ****
--- 315,321 ----
  #  end any prior catalog data insertions before starting a define unique index
  # ----
  	if (reln_open == 1) {
+ 		pinwritedata(pinwrite);
  #		print "show";
  		print "close " catalog;
  		reln_open = 0;
***************
*** 309,315 ****
  }
  
  /^BUILD_INDICES/	{ print "build indices"; }
! 	
  # ----------------
  #	CATALOG() definitions take some more work.
  # ----------------
--- 326,340 ----
  }
  
  /^BUILD_INDICES/	{ print "build indices"; }
! 
! /^PINTABLE\(/ {
! 	ret = match($0, /[0-9]+/);
! 	pin = substr($0, RSTART, RLENGTH);
! 
! 	pinwrite = "";
! 	next;
! }
! 
  # ----------------
  #	CATALOG() definitions take some more work.
  # ----------------
***************
*** 318,323 ****
--- 343,349 ----
  #  end any prior catalog data insertions before starting a new one..
  # ----
  	if (reln_open == 1) {
+ 		pinwritedata(pinwrite);
  #		print "show";
  		print "close " catalog;
  		reln_open = 0;
***************
*** 339,344 ****
--- 365,378 ----
  		without_oids = "without_oids ";
  	}
  
+ 	if ($0 ~ /BKI_PINWRITE/) {
+ 		pinwrite = "pinwrite";
+ 	} else {
+ 		pinwrite = "";
+ 	}
+ 
+ 	pin = "";
+ 
          i = 1;
  	inside = 1;
          nc++;
***************
*** 402,410 ****
--- 436,456 ----
  
  END {
  	if (reln_open == 1) {
+ 		pinwritedata(pinwrite);
  #		print "show";
  		print "close " catalog;
  		reln_open = 0;
+ 	}
+ }
+ 
+ ##
+ # write out PINd records
+ function pinwritedata(pinwrite)
+ {
+ 	if (pinwrite == "pinwrite") {
+ 		for (i=0; i < pincount; i++) {
+ 			print pindata[i];
+ 		}
  	}
  }
  ' "descriptionfile=${OUTPUT_PREFIX}.description.$$" > $TMPFILE || exit
Index: src/backend/catalog/heap.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/heap.c,v
retrieving revision 1.203
diff -c -r1.203 heap.c
*** src/backend/catalog/heap.c	2002/05/22 15:35:43	1.203
--- src/backend/catalog/heap.c	2002/06/15 16:37:54
***************
*** 36,47 ****
  #include "catalog/heap.h"
  #include "catalog/index.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_attrdef.h"
  #include "catalog/pg_inherits.h"
! #include "catalog/pg_relcheck.h"
  #include "catalog/pg_statistic.h"
  #include "catalog/pg_type.h"
- #include "commands/comment.h"
  #include "commands/trigger.h"
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
--- 36,49 ----
  #include "catalog/heap.h"
  #include "catalog/index.h"
  #include "catalog/indexing.h"
+ #include "catalog/namespace.h"
  #include "catalog/pg_attrdef.h"
+ #include "catalog/pg_constraint.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_inherits.h"
! #include "catalog/pg_namespace.h"
  #include "catalog/pg_statistic.h"
  #include "catalog/pg_type.h"
  #include "commands/trigger.h"
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
***************
*** 69,76 ****
  					char relkind, bool relhasoids);
  static void DeleteAttributeTuples(Relation rel);
  static void DeleteRelationTuple(Relation rel);
- static void DeleteTypeTuple(Relation rel);
- static void RelationRemoveIndexes(Relation relation);
  static void RelationRemoveInheritance(Relation relation);
  static void AddNewRelationType(const char *typeName,
  							   Oid typeNamespace,
--- 71,76 ----
***************
*** 220,225 ****
--- 220,227 ----
  	bool		nailme = false;
  	RelFileNode	rnode;
  	Relation	rel;
+ 	ObjectAddress	myself,
+ 					dependee;
  
  	/*
  	 * sanity checks
***************
*** 302,307 ****
--- 304,327 ----
  	if (storage_create)
  		heap_storage_create(rel);
  
+ 	/*
+ 	 * Store constraints which the entire table, not strictly 
+ 	 * a column, depends on.  Currently this is only the namespace
+ 	 * within which the relation resides.
+ 	 */
+ 	myself.classId = RelOid_pg_class;
+ 	myself.objectId = relid;
+ 	myself.objectSubId = 0;
+ 
+ 	dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 									  CStringGetDatum(NamespaceRelationName),
+ 									  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									  0, 0);
+ 
+ 	dependee.objectId = relnamespace;
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, true);
+ 
  	return rel;
  }
  
***************
*** 835,861 ****
  	heap_close(catalogRelation, RowExclusiveLock);
  }
  
- /*
-  *		RelationRemoveIndexes
-  */
- static void
- RelationRemoveIndexes(Relation relation)
- {
- 	List	   *indexoidlist,
- 			   *indexoidscan;
- 
- 	indexoidlist = RelationGetIndexList(relation);
  
- 	foreach(indexoidscan, indexoidlist)
- 	{
- 		Oid			indexoid = lfirsti(indexoidscan);
- 
- 		index_drop(indexoid);
- 	}
- 
- 	freeList(indexoidlist);
- }
- 
  /* --------------------------------
   *		DeleteRelationTuple
   *
--- 855,861 ----
***************
*** 1049,1172 ****
  	heap_close(pg_attribute_desc, RowExclusiveLock);
  }
  
- /* --------------------------------
-  *		DeleteTypeTuple
-  *
-  *		If the user attempts to destroy a relation and there
-  *		exists attributes in other relations of type
-  *		"relation we are deleting", then we have to do something
-  *		special.  presently we disallow the destroy.
-  * --------------------------------
-  */
- static void
- DeleteTypeTuple(Relation rel)
- {
- 	Relation	pg_type_desc;
- 	HeapScanDesc pg_type_scan;
- 	Relation	pg_attribute_desc;
- 	HeapScanDesc pg_attribute_scan;
- 	ScanKeyData key;
- 	ScanKeyData attkey;
- 	HeapTuple	tup;
- 	HeapTuple	atttup;
- 	Oid			typoid;
- 
- 	/*
- 	 * open pg_type
- 	 */
- 	pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
- 
- 	/*
- 	 * create a scan key to locate the type tuple corresponding to this
- 	 * relation.
- 	 */
- 	ScanKeyEntryInitialize(&key, 0,
- 						   Anum_pg_type_typrelid,
- 						   F_OIDEQ,
- 						   ObjectIdGetDatum(RelationGetRelid(rel)));
- 
- 	pg_type_scan = heap_beginscan(pg_type_desc,
- 								  SnapshotNow,
- 								  1,
- 								  &key);
- 
- 	/*
- 	 * use heap_getnext() to fetch the pg_type tuple.  If this tuple is
- 	 * not valid then something's wrong.
- 	 */
- 	tup = heap_getnext(pg_type_scan, ForwardScanDirection);
- 
- 	if (!HeapTupleIsValid(tup))
- 	{
- 		heap_endscan(pg_type_scan);
- 		heap_close(pg_type_desc, RowExclusiveLock);
- 		elog(ERROR, "DeleteTypeTuple: type \"%s\" does not exist",
- 			 RelationGetRelationName(rel));
- 	}
- 
- 	/*
- 	 * now scan pg_attribute.  if any other relations have attributes of
- 	 * the type of the relation we are deleteing then we have to disallow
- 	 * the deletion.  should talk to stonebraker about this.  -cim 6/19/90
- 	 */
- 	typoid = tup->t_data->t_oid;
- 
- 	pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
- 
- 	ScanKeyEntryInitialize(&attkey,
- 						   0,
- 						   Anum_pg_attribute_atttypid,
- 						   F_OIDEQ,
- 						   ObjectIdGetDatum(typoid));
- 
- 	pg_attribute_scan = heap_beginscan(pg_attribute_desc,
- 									   SnapshotNow,
- 									   1,
- 									   &attkey);
- 
- 	/*
- 	 * try and get a pg_attribute tuple.  if we succeed it means we can't
- 	 * delete the relation because something depends on the schema.
- 	 */
- 	atttup = heap_getnext(pg_attribute_scan, ForwardScanDirection);
- 
- 	if (HeapTupleIsValid(atttup))
- 	{
- 		Oid			relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid;
- 
- 		heap_endscan(pg_attribute_scan);
- 		heap_close(pg_attribute_desc, RowExclusiveLock);
- 		heap_endscan(pg_type_scan);
- 		heap_close(pg_type_desc, RowExclusiveLock);
- 
- 		elog(ERROR, "DeleteTypeTuple: column of type %s exists in relation %u",
- 			 RelationGetRelationName(rel), relid);
- 	}
- 	heap_endscan(pg_attribute_scan);
- 	heap_close(pg_attribute_desc, RowExclusiveLock);
- 
- 	/*
- 	 * Ok, it's safe so we delete the relation tuple from pg_type and
- 	 * finish up.
- 	 */
- 	simple_heap_delete(pg_type_desc, &tup->t_self);
- 
- 	heap_endscan(pg_type_scan);
- 	heap_close(pg_type_desc, RowExclusiveLock);
- }
- 
  /* ----------------------------------------------------------------
   *		heap_drop_with_catalog	- removes all record of named relation from catalogs
   *
   *		1)	open relation, check for existence, etc.
   *		2)	remove inheritance information
!  *		3)	remove indexes
!  *		4)	remove pg_class tuple
!  *		5)	remove pg_attribute tuples and related descriptions
!  *		6)	remove pg_description tuples
!  *		7)	remove pg_type tuples
!  *		8)	RemoveConstraints ()
!  *		9)	unlink relation
   *
   * old comments
   *		Except for vital relations, removes relation from
--- 1049,1064 ----
  	heap_close(pg_attribute_desc, RowExclusiveLock);
  }
  
  /* ----------------------------------------------------------------
   *		heap_drop_with_catalog	- removes all record of named relation from catalogs
   *
   *		1)	open relation, check for existence, etc.
   *		2)	remove inheritance information
!  *		3)	remove pg_class tuple
!  *		4)	remove pg_attribute tuples and related descriptions
!  *		5)	remove pg_description tuples
!  *		6)  Let dependDelete() do it's work.
!  *		7)	unlink relation
   *
   * old comments
   *		Except for vital relations, removes relation from
***************
*** 1187,1203 ****
   */
  void
  heap_drop_with_catalog(Oid rid,
! 					   bool allow_system_table_mods)
  {
  	Relation	rel;
- 	Oid			toasttableOid;
  	int			i;
  
  	/*
  	 * Open and lock the relation.
  	 */
  	rel = heap_open(rid, AccessExclusiveLock);
- 	toasttableOid = rel->rd_rel->reltoastrelid;
  
  	/*
  	 * prevent deletion of system relations
--- 1079,1098 ----
   */
  void
  heap_drop_with_catalog(Oid rid,
! 					   bool allow_system_table_mods,
! 					   int behavior)
  {
  	Relation	rel;
  	int			i;
+ 	HeapTuple	tuple;
+ 	int			natts;
+ 	Oid			relHasOids;
+ 	ObjectAddress	myself;
  
  	/*
  	 * Open and lock the relation.
  	 */
  	rel = heap_open(rid, AccessExclusiveLock);
  
  	/*
  	 * prevent deletion of system relations
***************
*** 1217,1260 ****
  			 i);
  
  	/*
- 	 * remove rules if necessary
- 	 */
- 	if (rel->rd_rules != NULL)
- 		RelationRemoveRules(rid);
- 
- 	/* triggers */
- 	RelationRemoveTriggers(rel);
- 
- 	/*
  	 * remove inheritance information
  	 */
  	RelationRemoveInheritance(rel);
  
  	/*
! 	 * remove indexes if necessary
  	 */
! 	RelationRemoveIndexes(rel);
  
  	/*
! 	 * delete attribute tuples
  	 */
! 	DeleteAttributeTuples(rel);
  
  	/*
! 	 * delete comments, statistics, and constraints
  	 */
! 	DeleteComments(rid, RelOid_pg_class);
  
  	RemoveStatistics(rel);
  
  	RemoveConstraints(rel);
  
  	/*
- 	 * delete type tuple
- 	 */
- 	DeleteTypeTuple(rel);
- 
- 	/*
  	 * delete relation tuple
  	 */
  	DeleteRelationTuple(rel);
--- 1112,1167 ----
  			 i);
  
  	/*
  	 * remove inheritance information
  	 */
  	RelationRemoveInheritance(rel);
  
  	/*
! 	 * Deal with dependencies
! 	 *
! 	 * Take care of any attributes first, then the main object
! 	 * last when objectSubId = 0.  Ignore system attributes.
  	 */
! 	tuple = SearchSysCache(RELOID, rid, 0, 0, 0);
! 	if (!HeapTupleIsValid(tuple))
! 		elog(ERROR, "Relation %s doesn't exist", RelationGetRelationName(rel));
! 
! 	natts = ((Form_pg_class) GETSTRUCT(tuple))->relnatts;
! 	relHasOids = ((Form_pg_class) GETSTRUCT(tuple))->relnatts;
  
+ 	/* Must free before calling dependDelete */
+ 	ReleaseSysCache(tuple);
+ 
  	/*
! 	 * Drop in decending order so the table is handled after all
! 	 * of its columns.
! 	 *
! 	 * Oid column first due to abilities like Primary Key on Oid.
  	 */
! 	myself.classId = RelOid_pg_class;
! 	myself.objectId = rid;
! 	if (relHasOids)
! 	{
! 		myself.objectSubId = ObjectIdAttributeNumber;
! 		dependDelete(&myself, behavior);
! 	}
! 
! 	for (i = natts; i >= 0; i--)
! 	{
! 		myself.objectSubId = i;
! 		dependDelete(&myself, behavior);
! 	}
  
  	/*
! 	 * delete attribute tuples
  	 */
! 	DeleteAttributeTuples(rel);
  
  	RemoveStatistics(rel);
  
  	RemoveConstraints(rel);
  
  	/*
  	 * delete relation tuple
  	 */
  	DeleteRelationTuple(rel);
***************
*** 1276,1285 ****
  	 * flush the relation from the relcache
  	 */
  	RelationForgetRelation(rid);
- 
- 	/* If it has a toast table, recurse to get rid of that too */
- 	if (OidIsValid(toasttableOid))
- 		heap_drop_with_catalog(toasttableOid, true);
  }
  
  
--- 1183,1188 ----
***************
*** 1374,1384 ****
  {
  	Node	   *expr;
  	char	   *ccsrc;
! 	Relation	rcrel;
! 	Relation	idescs[Num_pg_relcheck_indices];
! 	HeapTuple	tuple;
! 	Datum		values[4];
! 	static char nulls[4] = {' ', ' ', ' ', ' '};
  
  	/*
  	 * Convert condition to a normal boolean expression tree.
--- 1277,1287 ----
  {
  	Node	   *expr;
  	char	   *ccsrc;
! 	List	   *varList;
! 	List	   *vl;
! 	int			i = 0;
! 	int			keycount = 0;
! 	AttrNumber *attNos;
  
  	/*
  	 * Convert condition to a normal boolean expression tree.
***************
*** 1394,1420 ****
  											RelationGetRelid(rel)),
  							   false);
  
! 	values[Anum_pg_relcheck_rcrelid - 1] = RelationGetRelid(rel);
! 	values[Anum_pg_relcheck_rcname - 1] = DirectFunctionCall1(namein,
! 												CStringGetDatum(ccname));
! 	values[Anum_pg_relcheck_rcbin - 1] = DirectFunctionCall1(textin,
! 												 CStringGetDatum(ccbin));
! 	values[Anum_pg_relcheck_rcsrc - 1] = DirectFunctionCall1(textin,
! 												 CStringGetDatum(ccsrc));
! 	rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
! 	tuple = heap_formtuple(rcrel->rd_att, values, nulls);
! 	simple_heap_insert(rcrel, tuple);
! 	CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices,
! 					   idescs);
! 	CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
! 	CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
! 	heap_close(rcrel, RowExclusiveLock);
! 
! 	pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
! 	pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
! 	pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
! 	heap_freetuple(tuple);
  	pfree(ccsrc);
  }
  
  /*
--- 1297,1334 ----
  											RelationGetRelid(rel)),
  							   false);
  
! 	/* Find columns of rel that are used in ccbin */
! 	varList = pull_var_clause(expr, false);
! 	foreach(vl, varList)
! 		keycount++;
! 
! 	attNos = (AttrNumber *) palloc(keycount * sizeof(AttrNumber));
! 	foreach(vl, varList)
! 	{
! 		Var *var = (Var *) lfirsti(vl);
! 
! 		attNos[i++] = var->varattno;
! 	}
! 
! 	/* Create the Check Constraint */
! 	constraintCreate(RelationGetRelid(rel), /* Relation the constraint is on */
! 					 ccname, 	/* Constraint Name */
! 					 CONSTRAINT_CHECK, /* Constraint Type */
! 					 false, 	/* Is Derrerable */
! 					 false,		/* Is Deferred */
! 					 attNos,	/* List of attrributes in the constraint */
! 					 keycount,	/* Number of attributes in the constraint */
! 					 NULL,		/* Foreign Key fields (6) */
! 					 NULL,
! 					 NULL,
! 					 NULL,
! 					 NULL,
! 					 NULL,
! 					 ccbin,		/* Binary form check constraint */
! 					 ccsrc);	/* Source form check constraint */
! 
  	pfree(ccsrc);
+ 	pfree(attNos);
  }
  
  /*
***************
*** 1539,1683 ****
  	numchecks = numoldchecks;
  	foreach(listptr, rawConstraints)
  	{
! 		Constraint *cdef = (Constraint *) lfirst(listptr);
! 		char	   *ccname;
! 
! 		if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
! 			continue;
! 		Assert(cdef->cooked_expr == NULL);
  
! 		/* Check name uniqueness, or generate a new name */
! 		if (cdef->name != NULL)
  		{
! 			int			i;
! 			List	   *listptr2;
  
! 			ccname = cdef->name;
! 			/* Check against old constraints */
! 			for (i = 0; i < numoldchecks; i++)
! 			{
! 				if (strcmp(oldchecks[i].ccname, ccname) == 0)
! 					elog(ERROR, "Duplicate CHECK constraint name: '%s'",
! 						 ccname);
! 			}
! 			/* Check against other new constraints */
! 			foreach(listptr2, rawConstraints)
! 			{
! 				Constraint *cdef2 = (Constraint *) lfirst(listptr2);
  
! 				if (cdef2 == cdef ||
! 					cdef2->contype != CONSTR_CHECK ||
! 					cdef2->raw_expr == NULL ||
! 					cdef2->name == NULL)
! 					continue;
! 				if (strcmp(cdef2->name, ccname) == 0)
! 					elog(ERROR, "Duplicate CHECK constraint name: '%s'",
! 						 ccname);
! 			}
! 		}
! 		else
! 		{
! 			int			i;
! 			int			j;
! 			bool		success;
! 			List	   *listptr2;
! 
! 			ccname = (char *) palloc(NAMEDATALEN);
! 
! 			/* Loop until we find a non-conflicting constraint name */
! 			/* What happens if this loops forever? */
! 			j = numchecks + 1;
! 			do
! 			{
! 				success = true;
! 				snprintf(ccname, NAMEDATALEN, "$%d", j);
  
! 				/* Check against old constraints */
! 				for (i = 0; i < numoldchecks; i++)
  				{
! 					if (strcmp(oldchecks[i].ccname, ccname) == 0)
  					{
! 						success = false;
! 						break;
  					}
- 				}
  
! 				/*
! 				 * Check against other new constraints, if the check
! 				 * hasn't already failed
! 				 */
! 				if (success)
! 				{
! 					foreach(listptr2, rawConstraints)
  					{
! 						Constraint *cdef2 = (Constraint *) lfirst(listptr2);
  
! 						if (cdef2 == cdef ||
! 							cdef2->contype != CONSTR_CHECK ||
! 							cdef2->raw_expr == NULL ||
! 							cdef2->name == NULL)
! 							continue;
! 						if (strcmp(cdef2->name, ccname) == 0)
! 						{
! 							success = false;
  							break;
! 						}
  					}
- 				}
  
! 				++j;
! 			} while (!success);
! 		}
  
! 		/*
! 		 * Transform raw parsetree to executable expression.
! 		 */
! 		expr = transformExpr(pstate, cdef->raw_expr);
  
! 		/*
! 		 * Make sure it yields a boolean result.
! 		 */
! 		expr = coerce_to_boolean(expr, "CHECK");
  
! 		/*
! 		 * Make sure no outside relations are referred to.
! 		 */
! 		if (length(pstate->p_rtable) != 1)
! 			elog(ERROR, "Only relation \"%s\" can be referenced in CHECK constraint expression",
! 				 relname);
  
! 		/*
! 		 * No subplans or aggregates, either...
! 		 */
! 		if (contain_subplans(expr))
! 			elog(ERROR, "cannot use subselect in CHECK constraint expression");
! 		if (contain_agg_clause(expr))
! 			elog(ERROR, "cannot use aggregate function in CHECK constraint expression");
  
! 		/*
! 		 * Might as well try to reduce any constant expressions.
! 		 */
! 		expr = eval_const_expressions(expr);
  
! 		/*
! 		 * Constraints are evaluated with execQual, which expects an
! 		 * implicit-AND list, so convert expression to implicit-AND form.
! 		 * (We could go so far as to convert to CNF, but that's probably
! 		 * overkill...)
! 		 */
! 		expr = (Node *) make_ands_implicit((Expr *) expr);
  
! 		/*
! 		 * Must fix opids in operator clauses.
! 		 */
! 		fix_opids(expr);
  
! 		/*
! 		 * OK, store it.
! 		 */
! 		StoreRelCheck(rel, ccname, nodeToString(expr));
  
! 		numchecks++;
  	}
  
  	/*
--- 1453,1673 ----
  	numchecks = numoldchecks;
  	foreach(listptr, rawConstraints)
  	{
! 		Node	   *newConstraint = lfirst(listptr);
  
! 		switch (nodeTag(newConstraint))
  		{
! 			case T_Constraint:
! 				{
! 					Constraint *cdef = (Constraint *) newConstraint;
! 					char	   *ccname = cdef->name;
  
! 					if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
! 						continue;
! 					Assert(cdef->cooked_expr == NULL);
! 
! 					/*
! 					 * Transform raw parsetree to executable expression.
! 					 */
! 					expr = transformExpr(pstate, cdef->raw_expr);
! 
! 					/*
! 					 * Make sure it yields a boolean result.
! 					 */
! 					if (exprType(expr) != BOOLOID)
! 						elog(ERROR, "CHECK constraint expression '%s' does not yield boolean result",
! 							 ccname);
! 
! 					/*
! 					 * Make sure no outside relations are referred to.
! 					 */
! 					if (length(pstate->p_rtable) != 1)
! 						elog(ERROR, "Only relation \"%s\" can be referenced in CHECK constraint expression",
! 							 relname);
! 
! 					/*
! 					 * No subplans or aggregates, either...
! 					 */
! 					if (contain_subplans(expr))
! 						elog(ERROR, "cannot use subselect in CHECK constraint expression");
! 					if (contain_agg_clause(expr))
! 						elog(ERROR, "cannot use aggregate function in CHECK constraint expression");
! 
! 					/*
! 					 * Might as well try to reduce any constant expressions.
! 					 */
! 					expr = eval_const_expressions(expr);
! 
! 					/*
! 					 * Constraints are evaluated with execQual, which expects an
! 					 * implicit-AND list, so convert expression to implicit-AND form.
! 					 * (We could go so far as to convert to CNF, but that's probably
! 					 * overkill...)
! 					 */
! 					expr = (Node *) make_ands_implicit((Expr *) expr);
! 
! 					/*
! 					 * Must fix opids in operator clauses.
! 					 */
! 					fix_opids(expr);
! 
! 					/*
! 					 * OK, store it.
! 					 *
! 					 * Will check name uniqueness for us.
! 					 */
! 					StoreRelCheck(rel, ccname, nodeToString(expr));
  
! 					numchecks++;
  
! 					break;
! 				}
! 			case T_FkConstraint:
  				{
! 					FkConstraint *fkconstraint = (FkConstraint *) newConstraint;
! 					Relation	pkrel;
! 					List	   *list;
! 					Oid			conId;
! 					AttrNumber *pkattr = NULL;
! 					AttrNumber *fkattr = NULL;
! 					int			pkcount = 0;
! 					int			fkcount = 0;
! 					int			i;
! 					char		updateType = CONSTRAINT_FKEY_RESTRICT;	/* Defaults kill warnings */
! 					char		deleteType = CONSTRAINT_FKEY_RESTRICT;
! 
! 					/*
! 					 * Grab an exclusive lock on the pk table, so that
! 					 * someone doesn't delete rows out from under us.
! 					 *
! 					 * XXX wouldn't a lesser lock be sufficient?
! 					 */
! 					pkrel = heap_openrv(fkconstraint->pktable,
! 										AccessExclusiveLock);
! 
! 					/*
! 					 * Validity checks
! 					 */
! 					if (pkrel->rd_rel->relkind != RELKIND_RELATION)
! 						elog(ERROR, "referenced table \"%s\" not a relation",
! 							 fkconstraint->pktable->relname);
! 
! 					if (isTempNamespace(RelationGetNamespace(pkrel)) &&
! 						!isTempNamespace(RelationGetNamespace(rel)))
! 						elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
! 
! 					/* Foreign Keyd table AttrNumber array */
! 					foreach(list, fkconstraint->fk_attrs)
! 						fkcount++;
! 
! 					fkattr = (AttrNumber *) palloc(fkcount * sizeof(AttrNumber));
! 					i = 0;
! 					foreach(list, fkconstraint->fk_attrs)
  					{
! 						Ident *id = (Ident *) lfirsti(list);
! 
! 						fkattr[i++] = get_attnum(RelationGetRelid(rel), id->name);
  					}
  
! 					/* Foreign Referenced table AttrNumber array */
! 					foreach(list, fkconstraint->pk_attrs)
! 						pkcount++;
! 
! 					pkattr = (AttrNumber *) palloc(pkcount * sizeof(AttrNumber));
! 					i = 0;
! 					foreach(list, fkconstraint->pk_attrs)
  					{
! 						Ident *id = (Ident *) lfirsti(list);
! 
! 						pkattr[i++] = get_attnum(RelationGetRelid(pkrel), id->name);
! 					}
  
! 					/* Find the delete type */
! 					switch ((fkconstraint->actions & FKCONSTR_ON_DELETE_MASK)
! 							>> FKCONSTR_ON_DELETE_SHIFT)
! 					{
! 						case FKCONSTR_ON_KEY_CASCADE:
! 							deleteType = CONSTRAINT_FKEY_CASCADE;
! 							break;
! 
! 						case FKCONSTR_ON_KEY_NOACTION:
! 							deleteType = CONSTRAINT_FKEY_NOACTION;
! 							break;
! 
! 						case FKCONSTR_ON_KEY_RESTRICT:
! 							deleteType = CONSTRAINT_FKEY_RESTRICT;
! 							break;
! 
! 						case FKCONSTR_ON_KEY_SETNULL:
! 							deleteType = CONSTRAINT_FKEY_NULL;
  							break;
! 
! 						case FKCONSTR_ON_KEY_SETDEFAULT:
! 							deleteType = CONSTRAINT_FKEY_DEFAULT;
! 							break;
! 
! 						default:
! 							elog(ERROR, "AlterTableAddConstraint: Foreign key delete type %d unknown",
! 								 fkconstraint->actions);
  					}
  
! 					/* Find the update type */
! 					switch ((fkconstraint->actions & FKCONSTR_ON_UPDATE_MASK)
! 							>> FKCONSTR_ON_UPDATE_SHIFT)
! 					{
  
! 						case FKCONSTR_ON_KEY_CASCADE:
! 							updateType = CONSTRAINT_FKEY_CASCADE;
! 							break;
  
! 						case FKCONSTR_ON_KEY_NOACTION:
! 							updateType = CONSTRAINT_FKEY_NOACTION;
! 							break;
  
! 						case FKCONSTR_ON_KEY_RESTRICT:
! 							updateType = CONSTRAINT_FKEY_RESTRICT;
! 							break;
  
! 						case FKCONSTR_ON_KEY_SETNULL:
! 							updateType = CONSTRAINT_FKEY_NULL;
! 							break;
  
! 						case FKCONSTR_ON_KEY_SETDEFAULT:
! 							updateType = CONSTRAINT_FKEY_DEFAULT;
! 							break;
  
! 						default:
! 							elog(ERROR, "AlterTableAddConstraint: Foreign key update type %d unknown",
! 								 fkconstraint->actions);
! 					}
  
! 					/*
! 					 * Record the Foreign Key constraint
! 					 */
! 					conId = constraintCreate(RelationGetRelid(rel),
! 				 							 fkconstraint->constr_name,
! 				 							 CONSTRAINT_FOREIGN,
! 				 							 fkconstraint->deferrable,
! 				 							 fkconstraint->initdeferred,
! 											 fkattr,
! 											 fkcount,
! 											 RelationGetRelid(pkrel),
! 				 							 pkattr,
! 											 pkcount,
! 											 updateType,
! 											 deleteType,
! 				 							 fkconstraint->match_type,
! 											 NULL,
! 											 NULL);
  
! 
! 					heap_close(pkrel, NoLock);
  
! 					break;
! 				}
! 			default:
! 				elog(ERROR, "AddRelationRawConstraints: Unable to determine type of constraint passed");
! 		}
  	}
  
  	/*
***************
*** 1828,1834 ****
  	return(expr);
  }
  
- 
  static void
  RemoveAttrDefaults(Relation rel)
  {
--- 1818,1823 ----
***************
*** 1853,1996 ****
  }
  
  static void
- RemoveRelChecks(Relation rel)
- {
- 	Relation	rcrel;
- 	HeapScanDesc rcscan;
- 	ScanKeyData key;
- 	HeapTuple	tup;
- 
- 	rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
- 
- 	ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
- 						   F_OIDEQ,
- 						   ObjectIdGetDatum(RelationGetRelid(rel)));
- 
- 	rcscan = heap_beginscan(rcrel, SnapshotNow, 1, &key);
- 
- 	while ((tup = heap_getnext(rcscan, ForwardScanDirection)) != NULL)
- 		simple_heap_delete(rcrel, &tup->t_self);
- 
- 	heap_endscan(rcscan);
- 	heap_close(rcrel, RowExclusiveLock);
- 
- }
- 
- /*
-  * Removes all CHECK 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 CHECK constraints removed.
-  */
- int
- RemoveCheckConstraint(Relation rel, const char *constrName, bool inh)
- {
- 	Oid			relid;
- 	Relation	rcrel;
- 	TupleDesc	tupleDesc;
- 	TupleConstr *oldconstr;
- 	int			numoldchecks;
- 	int			numchecks;
- 	HeapScanDesc rcscan;
- 	ScanKeyData key[2];
- 	HeapTuple	rctup;
- 	int			rel_deleted = 0;
- 	int			all_deleted = 0;
- 
- 	/* Find id of the relation */
- 	relid = RelationGetRelid(rel);
- 
- 	/*
- 	 * Process child tables and remove constraints of the same name.
- 	 */
- 	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);
- 			Relation	inhrel;
- 
- 			if (childrelid == relid)
- 				continue;
- 			inhrel = heap_open(childrelid, AccessExclusiveLock);
- 			all_deleted += RemoveCheckConstraint(inhrel, constrName, false);
- 			heap_close(inhrel, NoLock);
- 		}
- 	}
- 
- 	/*
- 	 * Get number of existing constraints.
- 	 */
- 	tupleDesc = RelationGetDescr(rel);
- 	oldconstr = tupleDesc->constr;
- 	if (oldconstr)
- 		numoldchecks = oldconstr->num_check;
- 	else
- 		numoldchecks = 0;
- 
- 	/* Grab an appropriate lock on the pg_relcheck relation */
- 	rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
- 
- 	/*
- 	 * Create two scan keys.  We need to match on the oid of the table the
- 	 * CHECK is in and also we need to match the name of the CHECK
- 	 * constraint.
- 	 */
- 	ScanKeyEntryInitialize(&key[0], 0, Anum_pg_relcheck_rcrelid,
- 						   F_OIDEQ,
- 						   ObjectIdGetDatum(RelationGetRelid(rel)));
- 
- 	ScanKeyEntryInitialize(&key[1], 0, Anum_pg_relcheck_rcname,
- 						   F_NAMEEQ,
- 						   PointerGetDatum(constrName));
- 
- 	/* Begin scanning the heap */
- 	rcscan = heap_beginscan(rcrel, SnapshotNow, 2, key);
- 
- 	/*
- 	 * Scan over the result set, removing any matching entries.  Note that
- 	 * this has the side-effect of removing ALL CHECK constraints that
- 	 * share the specified constraint name.
- 	 */
- 	while ((rctup = heap_getnext(rcscan, ForwardScanDirection)) != NULL)
- 	{
- 		simple_heap_delete(rcrel, &rctup->t_self);
- 		++rel_deleted;
- 		++all_deleted;
- 	}
- 
- 	/* Clean up after the scan */
- 	heap_endscan(rcscan);
- 	heap_close(rcrel, RowExclusiveLock);
- 
- 	if (rel_deleted)
- 	{
- 		/*
- 		 * Update the count of constraints in the relation's pg_class tuple.
- 		 */
- 		numchecks = numoldchecks - rel_deleted;
- 		if (numchecks < 0)
- 			elog(ERROR, "check count became negative");
- 
- 		SetRelationNumChecks(rel, numchecks);
- 	}
- 
- 	/* Return the number of tuples deleted, including all children */
- 	return all_deleted;
- }
- 
- static void
  RemoveConstraints(Relation rel)
  {
  	TupleConstr *constr = rel->rd_att->constr;
--- 1842,1847 ----
***************
*** 2000,2008 ****
  
  	if (constr->num_defval > 0)
  		RemoveAttrDefaults(rel);
- 
- 	if (constr->num_check > 0)
- 		RemoveRelChecks(rel);
  }
  
  static void
--- 1851,1856 ----
Index: src/backend/catalog/index.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/index.c,v
retrieving revision 1.179
diff -c -r1.179 index.c
*** src/backend/catalog/index.c	2002/05/21 22:05:53	1.179
--- src/backend/catalog/index.c	2002/06/15 16:37:58
***************
*** 32,39 ****
--- 32,43 ----
  #include "catalog/heap.h"
  #include "catalog/index.h"
  #include "catalog/indexing.h"
+ #include "catalog/pg_class.h"
+ #include "catalog/pg_constraint.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_index.h"
  #include "catalog/pg_opclass.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
  #include "commands/comment.h"
***************
*** 543,548 ****
--- 547,555 ----
  	bool		shared_relation;
  	Oid			namespaceId;
  	Oid			indexoid;
+ 	ObjectAddress	myself,
+ 					dependee;
+ 	int				i;
  
  	SetReindexProcessing(false);
  
***************
*** 593,599 ****
  	else
  		indexTupDesc = ConstructTupleDescriptor(heapRelation,
  												indexInfo->ii_NumKeyAttrs,
! 											indexInfo->ii_KeyAttrNumbers,
  												classObjectId);
  
  	/*
--- 600,606 ----
  	else
  		indexTupDesc = ConstructTupleDescriptor(heapRelation,
  												indexInfo->ii_NumKeyAttrs,
! 												indexInfo->ii_KeyAttrNumbers,
  												classObjectId);
  
  	/*
***************
*** 630,635 ****
--- 637,705 ----
  	 */
  	UpdateRelationRelation(indexRelation);
  
+ 	myself.classId = RelOid_pg_class;
+ 	myself.objectId = indexoid;
+ 	myself.objectSubId = 0;
+ 
+ 	/*
+ 	 * If this is a unique index, we need to store the constraint
+ 	 * information as well as the dependency on it.
+ 	 */
+ 	if (indexInfo->ii_Unique || primary)
+ 	{
+ 		char		constraintType;
+ 		Oid			conOid;
+ 
+ 		if (primary)
+ 			constraintType = CONSTRAINT_PRIMARY;
+ 		else
+ 			constraintType = CONSTRAINT_UNIQUE;
+ 
+ 		conOid = constraintCreate(heapRelationId,
+ 								  indexRelationName,
+ 								  constraintType,
+ 								  false, /* isDeferrable */
+ 								  false, /* isDeferred */
+ 								  indexInfo->ii_KeyAttrNumbers,
+ 								  indexInfo->ii_NumIndexAttrs,
+ 								  NULL, /* Foreign Key Information */
+ 								  NULL,
+ 								  NULL,
+ 								  NULL,
+ 								  NULL,
+ 								  NULL,
+ 								  NULL, /* Constraint Bin & Src */
+ 								  NULL);
+ 
+ 		dependee.classId = get_relname_relid(ConstraintRelationName, PG_CATALOG_NAMESPACE);
+ 		dependee.objectId = conOid;
+ 		dependee.objectSubId = 0;
+ 
+ 		/* We always cascade index drops with constraint drops */
+ 		dependCreate(&myself, &dependee, true);
+ 	}
+ 
+ 	/* Store dependencies on the attributes */
+ 	for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
+ 	{
+ 		dependee.classId = RelOid_pg_class;
+ 		dependee.objectId = heapRelationId;
+ 		dependee.objectSubId = indexInfo->ii_KeyAttrNumbers[i];
+ 
+ 		/* We always cascade index drops with attribute drops */
+ 		dependCreate(&myself, &dependee, true);
+ 	}
+ 
+ 	/* Store the dependency on the function (if appropriate) */
+ 	if (OidIsValid(indexInfo->ii_FuncOid))
+ 	{
+ 		dependee.classId = RelOid_pg_proc;
+ 		dependee.objectId = indexInfo->ii_FuncOid;
+ 		dependee.objectSubId = 0;
+ 
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
  	/*
  	 * We create the disk file for this relation here
  	 */
***************
*** 698,704 ****
   * ----------------------------------------------------------------
   */
  void
! index_drop(Oid indexId)
  {
  	Oid			heapId;
  	Relation	userHeapRelation;
--- 768,774 ----
   * ----------------------------------------------------------------
   */
  void
! index_drop(Oid indexId, int behavior)
  {
  	Oid			heapId;
  	Relation	userHeapRelation;
***************
*** 709,714 ****
--- 779,786 ----
  	HeapTuple	tuple;
  	int16		attnum;
  	int			i;
+ 	
+ 	ObjectAddress	myself;
  
  	Assert(OidIsValid(indexId));
  
***************
*** 736,745 ****
  	 * did check it here, deletion of TOAST tables would fail...
  	 */
  
! 	/*
! 	 * fix DESCRIPTION relation
! 	 */
! 	DeleteComments(indexId, RelOid_pg_class);
  
  	/*
  	 * fix RELATION relation
--- 808,817 ----
  	 * did check it here, deletion of TOAST tables would fail...
  	 */
  
! 	myself.classId = RelOid_pg_class;
! 	myself.objectId = indexId;
! 	myself.objectSubId = 0;
! 	dependDelete(&myself, behavior);
  
  	/*
  	 * fix RELATION relation
Index: src/backend/catalog/indexing.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/indexing.c,v
retrieving revision 1.93
diff -c -r1.93 indexing.c
*** src/backend/catalog/indexing.c	2002/05/24 18:57:55	1.93
--- src/backend/catalog/indexing.c	2002/06/15 16:37:58
***************
*** 45,52 ****
--- 45,56 ----
  {AttrDefaultIndex};
  char	   *Name_pg_class_indices[Num_pg_class_indices] =
  {ClassNameNspIndex, ClassOidIndex};
+ char	   *Name_pg_constraint_indices[Num_pg_constraint_indices] =
+ {ConstraintOidIndex, ConstraintRelidNameIndex};
  char	   *Name_pg_database_indices[Num_pg_database_indices] =
  {DatabaseNameIndex, DatabaseOidIndex};
+ char	   *Name_pg_depend_indices[Num_pg_depend_indices] =
+ {DependDependerIndex, DependDependeeIndex};
  char	   *Name_pg_group_indices[Num_pg_group_indices] =
  {GroupNameIndex, GroupSysidIndex};
  char	   *Name_pg_index_indices[Num_pg_index_indices] =
***************
*** 65,72 ****
  {OperatorOidIndex, OperatorNameNspIndex};
  char	   *Name_pg_proc_indices[Num_pg_proc_indices] =
  {ProcedureOidIndex, ProcedureNameNspIndex};
- char	   *Name_pg_relcheck_indices[Num_pg_relcheck_indices] =
- {RelCheckIndex};
  char	   *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
  {RewriteOidIndex, RewriteRelRulenameIndex};
  char	   *Name_pg_shadow_indices[Num_pg_shadow_indices] =
--- 69,74 ----
Index: src/backend/catalog/namespace.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/namespace.c,v
retrieving revision 1.22
diff -c -r1.22 namespace.c
*** src/backend/catalog/namespace.c	2002/05/20 23:51:41	1.22
--- src/backend/catalog/namespace.c	2002/06/15 16:37:59
***************
*** 25,30 ****
--- 25,31 ----
  #include "catalog/catname.h"
  #include "catalog/heap.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_inherits.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_opclass.h"
***************
*** 1554,1560 ****
  	{
  		Oid			reloid = (Oid) lfirsti(lptr);
  
! 		heap_drop_with_catalog(reloid, true);
  		/*
  		 * Advance cmd counter to make catalog changes visible, in case
  		 * a later entry depends on this one.
--- 1555,1565 ----
  	{
  		Oid			reloid = (Oid) lfirsti(lptr);
  
! 		/*
! 		 * Cascade through all objects which depend on this one,
! 		 * temporary or otherwise.
! 		 */
! 		heap_drop_with_catalog(reloid, true, DEPEND_CASCADE);
  		/*
  		 * Advance cmd counter to make catalog changes visible, in case
  		 * a later entry depends on this one.
Index: src/backend/catalog/pg_aggregate.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v
retrieving revision 1.48
diff -c -r1.48 pg_aggregate.c
*** src/backend/catalog/pg_aggregate.c	2002/05/22 17:20:58	1.48
--- src/backend/catalog/pg_aggregate.c	2002/06/15 16:37:59
***************
*** 19,24 ****
--- 19,26 ----
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_aggregate.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
  #include "optimizer/cost.h"
***************
*** 53,58 ****
--- 55,62 ----
  	Oid			procOid;
  	TupleDesc	tupDesc;
  	int			i;
+ 	ObjectAddress	myself,
+ 					dependee;
  
  	/* sanity checks */
  	if (!aggName)
***************
*** 186,190 ****
--- 190,224 ----
  		CatalogCloseIndices(Num_pg_aggregate_indices, idescs);
  	}
  
+ 	/* Define Dependencies */
+ 	myself.classId = GetSysCacheOid(RELNAMENSP,
+ 									CStringGetDatum(AggregateRelationName),
+ 									ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									0, 0);
+ 	myself.objectId = tup->t_data->t_oid;
+ 	myself.objectSubId = 0;
+ 
+ 	/* Depends on transition function */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggtransfn - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Depends on final function */
+ 	if (values[Anum_pg_aggregate_aggfinalfn - 1] != InvalidOid)
+ 	{
+ 		dependee.classId = RelOid_pg_proc;
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggfinalfn - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Depends on final transition type */
+ 	dependee.classId = RelOid_pg_type;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggtranstype - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Cleanup */
  	heap_close(aggdesc, RowExclusiveLock);
  }
Index: src/backend/catalog/pg_operator.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_operator.c,v
retrieving revision 1.69
diff -c -r1.69 pg_operator.c
*** src/backend/catalog/pg_operator.c	2002/05/21 22:05:54	1.69
--- src/backend/catalog/pg_operator.c	2002/06/15 16:38:04
***************
*** 21,26 ****
--- 21,28 ----
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_operator.h"
  #include "catalog/pg_type.h"
  #include "miscadmin.h"
***************
*** 262,267 ****
--- 264,270 ----
  	 */
  	operatorObjectId = simple_heap_insert(pg_operator_desc, tup);
  
+ 	/* Keep indexes up to date */
  	if (RelationGetForm(pg_operator_desc)->relhasindex)
  	{
  		Relation	idescs[Num_pg_operator_indices];
***************
*** 403,408 ****
--- 406,414 ----
  	TupleDesc	tupDesc;
  	int			i;
  
+ 	ObjectAddress	myself,
+ 					dependee;
+ 
  	/*
  	 * Sanity checks
  	 */
***************
*** 657,662 ****
--- 663,774 ----
  		CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs);
  		CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup);
  		CatalogCloseIndices(Num_pg_operator_indices, idescs);
+ 	}
+ 
+ 	/* Load our object address */
+ 	myself.classId = GetSysCacheOid(RELNAMENSP,
+ 									CStringGetDatum(OperatorRelationName),
+ 									ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									0, 0);
+ 	myself.objectId = operatorObjectId;
+ 	myself.objectSubId = 0;
+ 
+ 	/* Procedure on its Namespace */
+ 	dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 									  CStringGetDatum(NamespaceRelationName),
+ 									  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									  0, 0);
+ 
+ 	dependee.objectId = operatorNamespace;
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, true);
+ 
+ 	/* Dependency on left type */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprleft - 1]) != InvalidOid) {
+ 		dependee.classId = RelOid_pg_type;
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprleft - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Dependency on right type */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprright - 1]) != InvalidOid) {
+ 		dependee.classId = RelOid_pg_type;
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprright - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Dependency on result type */
+ 	dependee.classId = RelOid_pg_type;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprresult - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Dependency on commutator */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprcom - 1]) != InvalidOid) {
+ 		dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 										  CStringGetDatum(OperatorRelationName),
+ 										  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 										  0, 0);
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprcom - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Dependency on negator */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprnegate - 1]) != InvalidOid) {
+ 		dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 										  CStringGetDatum(OperatorRelationName),
+ 										  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 										  0, 0);
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprnegate - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Dependency on sort left hand operator */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) {
+ 		dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 										  CStringGetDatum(OperatorRelationName),
+ 										  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 										  0, 0);
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprlsortop - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Dependency on sort right hand operator */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprrsortop - 1]) != InvalidOid) {
+ 		dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 										  CStringGetDatum(OperatorRelationName),
+ 										  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 										  0, 0);
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprrsortop - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Dependency on implementation function */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprcode - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Dependency on restriction selectivity function */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) {
+ 		dependee.classId = RelOid_pg_proc;
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprrest - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	/* Dependency on join selectifity function */
+ 	if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) {
+ 		dependee.classId = RelOid_pg_proc;
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
  	}
  
  	heap_close(pg_operator_desc, RowExclusiveLock);
Index: src/backend/catalog/pg_proc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_proc.c,v
retrieving revision 1.75
diff -c -r1.75 pg_proc.c
*** src/backend/catalog/pg_proc.c	2002/05/22 18:33:15	1.75
--- src/backend/catalog/pg_proc.c	2002/06/15 16:38:05
***************
*** 17,23 ****
--- 17,25 ----
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_language.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_proc.h"
  #include "executor/executor.h"
  #include "fmgr.h"
***************
*** 77,82 ****
--- 79,87 ----
  	TupleDesc	tupDesc;
  	Oid			retval;
  
+ 	ObjectAddress	myself,
+ 					dependee;
+ 
  	/*
  	 * sanity checks
  	 */
***************
*** 250,255 ****
--- 255,309 ----
  	}
  
  	retval = tup->t_data->t_oid;
+ 
+ 	/* Record Dependencies */
+ 	myself.classId = RelOid_pg_proc;
+ 	myself.objectId = retval;
+ 	myself.objectSubId = 0;
+ 
+ 	/* Procedure on Language */
+ 	dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 									  CStringGetDatum(LanguageRelationName),
+ 									  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									  0, 0);
+ 	dependee.objectId = languageObjectId;
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Procedure on its Namespace */
+ 	dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 									  CStringGetDatum(NamespaceRelationName),
+ 									  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									  0, 0);
+ 
+ 	dependee.objectId = procNamespace;
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, true);
+ 
+ 	/*
+ 	 * Return Types are skipped in it's an InvalidOid (opaque) or if
+ 	 * the type is a shell type (prevent a type <-> function dependency)
+ 	 */
+ 	if (returnType != InvalidOid && get_typisdefined(returnType))
+ 	{
+ 		dependee.classId = RelOid_pg_type;
+ 		dependee.objectId = returnType;
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 	}
+ 
+ 	for (i = 0; i < parameterCount; i++)
+ 	{
+ 		/* Parameter Types */
+ 		if (typev[i] != InvalidOid)
+ 		{
+ 			dependee.classId = RelOid_pg_type;
+ 			dependee.objectId = typev[i];
+ 			dependee.objectSubId = 0;
+ 			dependCreate(&myself, &dependee, false);
+ 		}
+ 	}
+ 
  	heap_freetuple(tup);
  
  	heap_close(rel, RowExclusiveLock);
Index: src/backend/catalog/pg_type.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_type.c,v
retrieving revision 1.71
diff -c -r1.71 pg_type.c
*** src/backend/catalog/pg_type.c	2002/05/21 22:05:54	1.71
--- src/backend/catalog/pg_type.c	2002/06/15 16:38:05
***************
*** 17,22 ****
--- 17,24 ----
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_type.h"
  #include "miscadmin.h"
  #include "utils/builtins.h"
***************
*** 166,171 ****
--- 168,175 ----
  	NameData	name;
  	TupleDesc	tupDesc;
  	int			i;
+ 	ObjectAddress	myself,
+ 					dependee;
  
  	/*
  	 * validate size specifications: either positive (fixed-length) or -1
***************
*** 296,301 ****
--- 300,371 ----
  		CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
  		CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
  		CatalogCloseIndices(Num_pg_type_indices, idescs);
+ 	}
+ 
+ 	/*
+ 	 * Create dependencies
+ 	 */
+ 
+ 	/* Load our object address */
+ 	myself.classId = RelOid_pg_type;
+ 	myself.objectId = typeObjectId;
+ 	myself.objectSubId = 0;
+ 
+ 	/* Procedure on its Namespace */
+ 	dependee.classId = GetSysCacheOid(RELNAMENSP,
+ 									  CStringGetDatum(NamespaceRelationName),
+ 									  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									  0, 0);
+ 
+ 	dependee.objectId = typeNamespace;
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, true);
+ 
+ 	/* Dependency on the input function */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typinput - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Dependency on the output function */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typoutput - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Dependency on the receive function */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typreceive - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* Dependency on the send function */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typsend - 1]);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/*
+ 	 * Dependency on the relation for complex types.  Assume it's for
+ 	 * a relation of somekind and drop it when the relation is removed.
+ 	 */
+ 	if (DatumGetObjectId(values[Anum_pg_type_typrelid - 1]) != InvalidOid) {
+ 		dependee.classId = RelOid_pg_class;
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typrelid - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, true);
+ 	}
+ 
+ 	/*
+ 	 * Dependency on the element Id for arrays.  We can assume that it's for
+ 	 * an array and that we should always cascade into this type when the base
+ 	 * type is being removed.
+ 	 */
+ 	if (DatumGetObjectId(values[Anum_pg_type_typelem - 1]) != InvalidOid) {
+ 		dependee.classId = RelOid_pg_type;
+ 		dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typelem - 1]);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, true);
  	}
  
  	/*
Index: src/backend/commands/aggregatecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v
retrieving revision 1.2
diff -c -r1.2 aggregatecmds.c
*** src/backend/commands/aggregatecmds.c	2002/04/27 03:45:00	1.2
--- src/backend/commands/aggregatecmds.c	2002/06/15 16:38:05
***************
*** 26,33 ****
  #include "catalog/catname.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_proc.h"
- #include "commands/comment.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse_func.h"
--- 26,33 ----
  #include "catalog/catname.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_aggregate.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_proc.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse_func.h"
***************
*** 142,148 ****
  
  
  void
! RemoveAggregate(List *aggName, TypeName *aggType)
  {
  	Relation	relation;
  	HeapTuple	tup;
--- 142,148 ----
  
  
  void
! RemoveAggregate(List *aggName, TypeName *aggType, int behavior)
  {
  	Relation	relation;
  	HeapTuple	tup;
***************
*** 179,186 ****
  								 GetUserId()))
  		aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(aggName));
  
! 	/* Delete any comments associated with this function */
! 	DeleteComments(procOid, RelationGetRelid(relation));
  
  	/* Remove the pg_proc tuple */
  	simple_heap_delete(relation, &tup->t_self);
--- 179,186 ----
  								 GetUserId()))
  		aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(aggName));
  
! 	/* Deal with dependencies */
! 	dependDeleteTuple(tup, relation, behavior);
  
  	/* Remove the pg_proc tuple */
  	simple_heap_delete(relation, &tup->t_self);
Index: src/backend/commands/cluster.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/cluster.c,v
retrieving revision 1.81
diff -c -r1.81 cluster.c
*** src/backend/commands/cluster.c	2002/05/21 22:05:54	1.81
--- src/backend/commands/cluster.c	2002/06/15 16:38:05
***************
*** 26,31 ****
--- 26,32 ----
  #include "access/heapam.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_index.h"
  #include "catalog/pg_proc.h"
  #include "commands/cluster.h"
***************
*** 118,125 ****
  
  	CommandCounterIncrement();
  
! 	/* Destroy old heap (along with its index) and rename new. */
! 	heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods);
  
  	CommandCounterIncrement();
  
--- 119,129 ----
  
  	CommandCounterIncrement();
  
! 	/*
! 	 * Destroy old heap (along with its index) and rename new without
! 	 * blowing away objects which depend on this one.
! 	 */
! 	heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods, DEPEND_IMPLICITONLY);
  
  	CommandCounterIncrement();
  
Index: src/backend/commands/comment.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/comment.c,v
retrieving revision 1.48
diff -c -r1.48 comment.c
*** src/backend/commands/comment.c	2002/05/21 22:05:54	1.48
--- src/backend/commands/comment.c	2002/06/15 16:38:08
***************
*** 19,24 ****
--- 19,25 ----
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_constraint.h"
  #include "catalog/pg_database.h"
  #include "catalog/pg_description.h"
  #include "catalog/pg_namespace.h"
***************
*** 57,62 ****
--- 58,64 ----
  static void CommentProc(List *function, List *arguments, char *comment);
  static void CommentOperator(List *opername, List *arguments, char *comment);
  static void CommentTrigger(List *qualname, char *comment);
+ static void CommentConstraint(List *qualname, char *comment);
  
  
  /*
***************
*** 100,105 ****
--- 102,110 ----
  		case TRIGGER:
  			CommentTrigger(stmt->objname, stmt->comment);
  			break;
+ 		case CONSTRAINT:
+ 			CommentConstraint(stmt->objname, stmt->comment);
+ 			break;
  		case SCHEMA:
  			CommentNamespace(stmt->objname, stmt->comment);
  			break;
***************
*** 232,258 ****
   * is destroyed.
   */
  void
! DeleteComments(Oid oid, Oid classoid)
  {
  	Relation	description;
! 	ScanKeyData skey[2];
  	SysScanDesc	sd;
  	HeapTuple	oldtuple;
  
  	/* Use the index to search for all matching old tuples */
  
! 	ScanKeyEntryInitialize(&skey[0],
  						   (bits16) 0x0,
  						   (AttrNumber) 1,
  						   (RegProcedure) F_OIDEQ,
  						   ObjectIdGetDatum(oid));
  
! 	ScanKeyEntryInitialize(&skey[1],
  						   (bits16) 0x0,
  						   (AttrNumber) 2,
  						   (RegProcedure) F_OIDEQ,
  						   ObjectIdGetDatum(classoid));
  
  	description = heap_openr(DescriptionRelationName, RowExclusiveLock);
  
  	sd = systable_beginscan(description, DescriptionObjIndex, true,
--- 237,275 ----
   * is destroyed.
   */
  void
! DeleteComments(Oid oid, Oid classoid, int32 subid)
  {
  	Relation	description;
! 	Relation	descriptionindex;
! 	ScanKeyData skey[3];
  	SysScanDesc	sd;
  	HeapTuple	oldtuple;
+ 	int			i = 0;
+ 
+ 	/* Open pg_description and its index */
  
+ 	description = heap_openr(DescriptionRelationName, RowExclusiveLock);
+ 	descriptionindex = index_openr(DescriptionObjIndex);
+ 
  	/* Use the index to search for all matching old tuples */
  
! 	ScanKeyEntryInitialize(&skey[i++],
  						   (bits16) 0x0,
  						   (AttrNumber) 1,
  						   (RegProcedure) F_OIDEQ,
  						   ObjectIdGetDatum(oid));
  
! 	ScanKeyEntryInitialize(&skey[i++],
  						   (bits16) 0x0,
  						   (AttrNumber) 2,
  						   (RegProcedure) F_OIDEQ,
  						   ObjectIdGetDatum(classoid));
  
+ 	ScanKeyEntryInitialize(&skey[i++],
+ 						   (bits16) 0x0,
+ 						   (AttrNumber) 3,
+ 						   (RegProcedure) F_INT4EQ,
+ 						   Int32GetDatum(subid));
  	description = heap_openr(DescriptionRelationName, RowExclusiveLock);
  
  	sd = systable_beginscan(description, DescriptionObjIndex, true,
***************
*** 805,809 ****
--- 822,904 ----
  	/* Done, but hold lock on relation */
  
  	heap_close(pg_trigger, AccessShareLock);
+ 	heap_close(relation, NoLock);
+ }
+ 
+ /*
+  * CommentConstraint --
+  *
+  * Enable commenting on constraints held within the pg_constraint
+  * table.  A qualified name is required as constraint names are
+  * unique per relation.
+  */
+ static void
+ CommentConstraint(List *qualName, char *comment)
+ {
+ 	int			nnames;
+ 	List	   *relName;
+ 	char	   *conName;
+ 	RangeVar   *rel;
+ 	Relation	pg_constraint,
+ 				relation;
+ 	HeapTuple	tuple;
+ 	SysScanDesc	scan;
+ 	ScanKeyData skey[2];
+ 	Oid			oid;
+ 	int			i = 0;
+ 
+ 	/* Separate relname and trig name */
+ 	nnames = length(qualName);
+ 	if (nnames < 2)
+ 		elog(ERROR, "CommentConstraint: must specify relation and constraint");
+ 	relName = ltruncate(nnames-1, listCopy(qualName));
+ 	conName = strVal(nth(nnames-1, qualName));
+ 
+ 	/* Open the owning relation to ensure it won't go away meanwhile */
+ 	rel = makeRangeVarFromNameList(relName);
+ 	relation = heap_openrv(rel, AccessShareLock);
+ 
+ 	/* Check object security */
+ 
+ 	if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
+ 		aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(relation));
+ 
+ 	/*
+ 	 * Fetch the trigger tuple from pg_trigger.  There can be only one
+ 	 * because of the unique index.
+ 	 */
+ 	pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
+ 
+ 	ScanKeyEntryInitialize(&skey[i++],
+ 						   0, Anum_pg_constraint_conrelid, F_OIDEQ,
+ 						   ObjectIdGetDatum(RelationGetRelid(relation)));
+ 
+ 	ScanKeyEntryInitialize(&skey[i++],
+ 						   0, Anum_pg_constraint_conname, F_NAMEEQ,
+ 						   CStringGetDatum(conName));
+ 
+ 	scan = systable_beginscan(pg_constraint, ConstraintRelidNameIndex, true,
+ 							  SnapshotNow,
+ 							  i, skey);
+ 
+ 	tuple = systable_getnext(scan);
+ 
+ 	/* If no trigger exists for the relation specified, notify user */
+ 
+ 	if (!HeapTupleIsValid(tuple))
+ 		elog(ERROR, "constraint \"%s\" for relation \"%s\" does not exist",
+ 			 conName, RelationGetRelationName(relation));
+ 
+ 	oid = tuple->t_data->t_oid;
+ 
+ 	systable_endscan(scan);
+ 
+ 	/* Create the comments with the pg_trigger oid */
+ 
+ 	CreateComments(oid, RelationGetRelid(pg_constraint), 0, comment);
+ 
+ 	/* Done, but hold lock on relation */
+ 
+ 	heap_close(pg_constraint, AccessShareLock);
  	heap_close(relation, NoLock);
  }
Index: src/backend/commands/dbcommands.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/dbcommands.c,v
retrieving revision 1.92
diff -c -r1.92 dbcommands.c
*** src/backend/commands/dbcommands.c	2002/05/25 16:30:59	1.92
--- src/backend/commands/dbcommands.c	2002/06/15 16:38:08
***************
*** 406,412 ****
  	heap_endscan(pgdbscan);
  
  	/* Delete any comments associated with the database */
! 	DeleteComments(db_id, RelationGetRelid(pgdbrel));
  
  	/*
  	 * Close pg_database, but keep exclusive lock till commit to ensure
--- 406,412 ----
  	heap_endscan(pgdbscan);
  
  	/* Delete any comments associated with the database */
! 	DeleteComments(db_id, RelationGetRelid(pgdbrel), 0);
  
  	/*
  	 * Close pg_database, but keep exclusive lock till commit to ensure
Index: src/backend/commands/functioncmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/functioncmds.c,v
retrieving revision 1.6
diff -c -r1.6 functioncmds.c
*** src/backend/commands/functioncmds.c	2002/05/22 17:20:58	1.6
--- src/backend/commands/functioncmds.c	2002/06/15 16:38:09
***************
*** 34,43 ****
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
- #include "commands/comment.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "optimizer/cost.h"
--- 34,43 ----
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "optimizer/cost.h"
***************
*** 531,536 ****
--- 531,537 ----
  
  /*
   * RemoveFunction
+  * RemoveFunctionById
   *		Deletes a function.
   *
   * Exceptions:
***************
*** 540,554 ****
   */
  void
  RemoveFunction(List *functionName,		/* function name to be removed */
! 			   List *argTypes)	/* list of TypeName nodes */
  {
  	Oid			funcOid;
- 	Relation	relation;
- 	HeapTuple	tup;
  
  	funcOid = LookupFuncNameTypeNames(functionName, argTypes, 
  									  true, "RemoveFunction");
  
  	relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
  
  	tup = SearchSysCache(PROCOID,
--- 541,563 ----
   */
  void
  RemoveFunction(List *functionName,		/* function name to be removed */
! 			   List *argTypes,	/* list of TypeName nodes */
! 			   int behavior)
  {
  	Oid			funcOid;
  
  	funcOid = LookupFuncNameTypeNames(functionName, argTypes, 
  									  true, "RemoveFunction");
  
+ 	RemoveFunctionById(funcOid, behavior);
+ };
+ 
+ void
+ RemoveFunctionById(Oid funcOid, int behavior)
+ {
+ 	Relation	relation;
+ 	HeapTuple	tup;
+ 
  	relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
  
  	tup = SearchSysCache(PROCOID,
***************
*** 556,587 ****
  						 0, 0, 0);
  	if (!HeapTupleIsValid(tup))	/* should not happen */
  		elog(ERROR, "RemoveFunction: couldn't find tuple for function %s",
! 			 NameListToString(functionName));
  
  	/* Permission check: must own func or its namespace */
  	if (!pg_proc_ownercheck(funcOid, GetUserId()) &&
  		!pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
  								 GetUserId()))
! 		aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(functionName));
  
  	if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
  		elog(ERROR, "RemoveFunction: function '%s' is an aggregate"
  			 "\n\tUse DROP AGGREGATE to remove it",
! 			 NameListToString(functionName));
! 
! 	if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId)
! 	{
! 		/* "Helpful" WARNING when removing a builtin function ... */
! 		elog(WARNING, "Removing built-in function \"%s\"",
! 			 NameListToString(functionName));
! 	}
  
! 	/* Delete any comments associated with this function */
! 	DeleteComments(funcOid, RelationGetRelid(relation));
  
  	simple_heap_delete(relation, &tup->t_self);
  
  	ReleaseSysCache(tup);
  
  	heap_close(relation, RowExclusiveLock);
  }
--- 565,593 ----
  						 0, 0, 0);
  	if (!HeapTupleIsValid(tup))	/* should not happen */
  		elog(ERROR, "RemoveFunction: couldn't find tuple for function %s",
! 			 get_func_name(funcOid));
  
  	/* Permission check: must own func or its namespace */
  	if (!pg_proc_ownercheck(funcOid, GetUserId()) &&
  		!pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
  								 GetUserId()))
! 		aclcheck_error(ACLCHECK_NOT_OWNER, get_func_name(funcOid));
  
  	if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
  		elog(ERROR, "RemoveFunction: function '%s' is an aggregate"
  			 "\n\tUse DROP AGGREGATE to remove it",
! 			 get_func_name(funcOid));
  
! 	/*
! 	 * Deal with dependencies
! 	 * Manages system function restrictions for us as well.
! 	 */
! 	dependDeleteTuple(tup, relation, behavior);
  
  	simple_heap_delete(relation, &tup->t_self);
  
  	ReleaseSysCache(tup);
  
  	heap_close(relation, RowExclusiveLock);
+ 
  }
Index: src/backend/commands/indexcmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/indexcmds.c,v
retrieving revision 1.74
diff -c -r1.74 indexcmds.c
*** src/backend/commands/indexcmds.c	2002/05/20 23:51:42	1.74
--- src/backend/commands/indexcmds.c	2002/06/15 16:38:11
***************
*** 567,573 ****
   *		...
   */
  void
! RemoveIndex(RangeVar *relation)
  {
  	Oid			indOid;
  	HeapTuple	tuple;
--- 567,573 ----
   *		...
   */
  void
! RemoveIndex(RangeVar *relation, int behavior)
  {
  	Oid			indOid;
  	HeapTuple	tuple;
***************
*** 585,591 ****
  
  	ReleaseSysCache(tuple);
  
! 	index_drop(indOid);
  }
  
  /*
--- 585,591 ----
  
  	ReleaseSysCache(tuple);
  
! 	index_drop(indOid, behavior);
  }
  
  /*
Index: src/backend/commands/operatorcmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/operatorcmds.c,v
retrieving revision 1.3
diff -c -r1.3 operatorcmds.c
*** src/backend/commands/operatorcmds.c	2002/04/27 03:45:01	1.3
--- src/backend/commands/operatorcmds.c	2002/06/15 16:38:11
***************
*** 37,44 ****
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_operator.h"
- #include "commands/comment.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse_oper.h"
--- 37,44 ----
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_operator.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse_oper.h"
***************
*** 208,213 ****
--- 208,214 ----
  
  /*
   * RemoveOperator
+  * RemoveOperatorById
   *		Deletes an operator.
   *
   * Exceptions:
***************
*** 219,233 ****
  void
  RemoveOperator(List *operatorName,		/* operator name */
  			   TypeName *typeName1, /* left argument type name */
! 			   TypeName *typeName2) /* right argument type name */
  {
  	Oid			operOid;
- 	Relation	relation;
- 	HeapTuple	tup;
  
  	operOid = LookupOperNameTypeNames(operatorName, typeName1, typeName2,
  									  "RemoveOperator");
  
  	relation = heap_openr(OperatorRelationName, RowExclusiveLock);
  
  	tup = SearchSysCacheCopy(OPEROID,
--- 220,241 ----
  void
  RemoveOperator(List *operatorName,		/* operator name */
  			   TypeName *typeName1, /* left argument type name */
! 			   TypeName *typeName2, /* right argument type name */
! 			   int behavior)
  {
  	Oid			operOid;
  
  	operOid = LookupOperNameTypeNames(operatorName, typeName1, typeName2,
  									  "RemoveOperator");
  
+ 	RemoveOperatorById(operOid, behavior);
+ }
+ 
+ void
+ RemoveOperatorById(Oid operOid, int behavior)
+ {
+ 	Relation	relation;
+ 	HeapTuple	tup;
  	relation = heap_openr(OperatorRelationName, RowExclusiveLock);
  
  	tup = SearchSysCacheCopy(OPEROID,
***************
*** 235,250 ****
  							 0, 0, 0);
  	if (!HeapTupleIsValid(tup))	/* should not happen */
  		elog(ERROR, "RemoveOperator: failed to find tuple for operator '%s'",
! 			 NameListToString(operatorName));
  
  	/* Permission check: must own operator or its namespace */
  	if (!pg_oper_ownercheck(operOid, GetUserId()) &&
  		!pg_namespace_ownercheck(((Form_pg_operator) GETSTRUCT(tup))->oprnamespace,
  								 GetUserId()))
! 		aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(operatorName));
  
! 	/* Delete any comments associated with this operator */
! 	DeleteComments(operOid, RelationGetRelid(relation));
  
  	simple_heap_delete(relation, &tup->t_self);
  
--- 243,262 ----
  							 0, 0, 0);
  	if (!HeapTupleIsValid(tup))	/* should not happen */
  		elog(ERROR, "RemoveOperator: failed to find tuple for operator '%s'",
! 			 get_opname(operOid));
  
  	/* Permission check: must own operator or its namespace */
  	if (!pg_oper_ownercheck(operOid, GetUserId()) &&
  		!pg_namespace_ownercheck(((Form_pg_operator) GETSTRUCT(tup))->oprnamespace,
  								 GetUserId()))
! 		aclcheck_error(ACLCHECK_NOT_OWNER, get_opname(operOid));
! 
! 	if (!pg_oper_ownercheck(operOid, GetUserId()))
! 		elog(ERROR, "RemoveOperator: operator '%s': permission denied",
! 			 get_opname(operOid));
  
! 	/* Deal with dependencies */
! 	dependDeleteTuple(tup, relation, behavior);
  
  	simple_heap_delete(relation, &tup->t_self);
  
Index: src/backend/commands/proclang.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/proclang.c,v
retrieving revision 1.33
diff -c -r1.33 proclang.c
*** src/backend/commands/proclang.c	2002/05/22 17:20:58	1.33
--- src/backend/commands/proclang.c	2002/06/15 16:38:11
***************
*** 18,23 ****
--- 18,24 ----
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
***************
*** 49,54 ****
--- 50,58 ----
  	TupleDesc	tupDesc;
  	int			i;
  
+ 	ObjectAddress	myself,
+ 					dependee;
+ 
  	/*
  	 * Check permission
  	 */
***************
*** 80,85 ****
--- 84,94 ----
  		elog(ERROR, "PL handler function %s() does not return type \"opaque\"",
  			 NameListToString(stmt->plhandler));
  
+ 	/* Address of the PL handler function */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = procOid;
+ 	dependee.objectSubId = 0;
+ 
  	/* validate the validator function */
  	if (stmt->plvalidator)
  	{
***************
*** 127,132 ****
--- 136,149 ----
  		CatalogCloseIndices(Num_pg_language_indices, idescs);
  	}
  
+ 	/* Address of myself */
+ 	myself.classId = RelationGetRelid(rel);
+ 	myself.objectId = tup->t_data->t_oid;
+ 	myself.objectSubId = 0;
+ 
+ 	/* Create dependency on the language PL Handler function */
+ 	dependCreate(&myself, &dependee, false);
+ 
  	heap_close(rel, RowExclusiveLock);
  }
  
***************
*** 166,171 ****
--- 183,191 ----
  	if (!((Form_pg_language) GETSTRUCT(langTup))->lanispl)
  		elog(ERROR, "Language %s isn't a created procedural language",
  			 languageName);
+ 
+ 	/* Deal with Dependencies */
+ 	dependDeleteTuple(langTup, rel, stmt->behavior);
  
  	simple_heap_delete(rel, &langTup->t_self);
  
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.16
diff -c -r1.16 tablecmds.c
*** src/backend/commands/tablecmds.c	2002/05/21 22:05:54	1.16
--- src/backend/commands/tablecmds.c	2002/06/15 16:38:16
***************
*** 23,28 ****
--- 23,30 ----
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_attrdef.h"
+ #include "catalog/pg_constraint.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_inherits.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_opclass.h"
***************
*** 240,248 ****
--- 242,275 ----
  	{
  		ColumnDef  *colDef = lfirst(listptr);
  		RawColumnDefault *rawEnt;
+ 		ObjectAddress   myself,
+ 						dependee;
  
  		attnum++;
  
+ 		myself.classId = RelOid_pg_class;
+ 		myself.objectId = relationId;
+ 		myself.objectSubId = attnum;
+ 
+ 		/*
+ 		 * Seek for serial dependency
+ 		 * The sequence must have been created first!
+ 		 */
+ 		if (colDef->typename->serial != NULL) {
+ 			ObjectAddress	depender;
+ 
+ 			depender.classId = RelOid_pg_class;
+ 			depender.objectId = RangeVarGetRelid(colDef->typename->serial, false);
+ 			depender.objectSubId = 0;
+ 			dependCreate(&depender, &myself, true);
+ 		}
+ 
+ 		/* Store the column dependency on the column type */
+ 		dependee.classId = RelOid_pg_type;
+ 		dependee.objectId = LookupTypeName(colDef->typename);
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, false);
+ 
  		if (colDef->raw_default == NULL)
  			continue;
  		Assert(colDef->cooked_default == NULL);
***************
*** 280,291 ****
   * themselves will be destroyed, too.
   */
  void
! RemoveRelation(const RangeVar *relation)
  {
  	Oid			relOid;
  
  	relOid = RangeVarGetRelid(relation, false);
! 	heap_drop_with_catalog(relOid, allowSystemTableMods);
  }
  
  /*
--- 307,318 ----
   * themselves will be destroyed, too.
   */
  void
! RemoveRelation(const RangeVar *relation, int behavior)
  {
  	Oid			relOid;
  
  	relOid = RangeVarGetRelid(relation, false);
! 	heap_drop_with_catalog(relOid, allowSystemTableMods, behavior);
  }
  
  /*
***************
*** 736,742 ****
  /*
   * complementary static functions for MergeAttributes().
   *
!  * Varattnos of pg_relcheck.rcbin must be rewritten when subclasses inherit
   * constraints from parent classes, since the inherited attributes could
   * be given different column numbers in multiple-inheritance cases.
   *
--- 763,769 ----
  /*
   * complementary static functions for MergeAttributes().
   *
!  * Varattnos of pg_constraint.conbin must be rewritten when subclasses inherit
   * constraints from parent classes, since the inherited attributes could
   * be given different column numbers in multiple-inheritance cases.
   *
***************
*** 2592,2598 ****
  					trig.tgargs[0] = trig.tgname;
  					trig.tgargs[1] = RelationGetRelationName(rel);
  					trig.tgargs[2] = RelationGetRelationName(pkrel);
! 					trig.tgargs[3] = fkconstraint->match_type;
  					count = 4;
  					foreach(list, fkconstraint->fk_attrs)
  					{
--- 2619,2639 ----
  					trig.tgargs[0] = trig.tgname;
  					trig.tgargs[1] = RelationGetRelationName(rel);
  					trig.tgargs[2] = RelationGetRelationName(pkrel);
! 					switch (fkconstraint->match_type) 
! 					{
! 						case CONSTRAINT_FKEY_FULL:
! 							trig.tgargs[3] = "FULL";
! 							break;
! 						case CONSTRAINT_FKEY_PARTIAL:
! 							trig.tgargs[3] = "PARTIAL";
! 							break;
! 						case CONSTRAINT_FKEY_UNSPECIFIED:
! 							trig.tgargs[3] = "UNSPECIFIED";
! 							break;
! 						default:
! 							elog(ERROR, "constraintCreate: Unknown MATCH TYPE");
! 					}
! 
  					count = 4;
  					foreach(list, fkconstraint->fk_attrs)
  					{
***************
*** 2646,2651 ****
--- 2687,2702 ----
  
  					pfree(trig.tgargs);
  
+ 					/*
+ 					 * Call AddRelationRawConstraints to do
+ 					 * the real adding -- It duplicates some
+ 					 * of the above, but does not check the
+ 					 * validity of the constraint against
+ 					 * tuples already in the table.
+ 					 */
+ 					AddRelationRawConstraints(rel, NIL,
+ 											  makeList1(fkconstraint));
+ 
  					heap_close(pkrel, NoLock);
  
  					break;
***************
*** 2659,2691 ****
  	heap_close(rel, NoLock);
  }
  
- 
  /*
   * ALTER TABLE DROP CONSTRAINT
-  * Note: It is legal to remove a constraint with name "" as it is possible
-  * to add a constraint with name "".
-  * Christopher Kings-Lynne
   */
  void
! AlterTableDropConstraint(Oid myrelid,
  						 bool inh, const char *constrName,
  						 int behavior)
  {
! 	Relation	rel;
! 	int			deleted;
  
  	/*
- 	 * We don't support CASCADE yet  - in fact, RESTRICT doesn't work to
- 	 * the spec either!
- 	 */
- 	if (behavior == CASCADE)
- 		elog(ERROR, "ALTER TABLE / DROP CONSTRAINT does not support the CASCADE keyword");
- 
- 	/*
  	 * Acquire an exclusive lock on the target relation for the duration
  	 * of the operation.
  	 */
! 	rel = heap_open(myrelid, AccessExclusiveLock);
  
  	/* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */
  	if (rel->rd_rel->relkind != RELKIND_RELATION)
--- 2710,2735 ----
  	heap_close(rel, NoLock);
  }
  
  /*
   * ALTER TABLE DROP CONSTRAINT
   */
  void
! AlterTableDropConstraint(Oid relId,
  						 bool inh, const char *constrName,
  						 int behavior)
  {
! 	Relation		rel;
! 	ScanKeyData		skey[2];
! 	SysScanDesc 	rcscan;
! 	int				i = 0;
! 	HeapTuple		tup;
! 	Relation		conDesc;
  
  	/*
  	 * Acquire an exclusive lock on the target relation for the duration
  	 * of the operation.
  	 */
! 	rel = heap_open(relId, AccessExclusiveLock);
  
  	/* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */
  	if (rel->rd_rel->relkind != RELKIND_RELATION)
***************
*** 2697,2737 ****
  		elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
  			 RelationGetRelationName(rel));
  
! 	if (!pg_class_ownercheck(myrelid, GetUserId()))
  		aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
  
- 	/*
- 	 * Since all we have is the name of the constraint, we have to look
- 	 * through all catalogs that could possibly contain a constraint for
- 	 * this relation. We also keep a count of the number of constraints
- 	 * removed.
- 	 */
  
! 	deleted = 0;
  
! 	/*
! 	 * First, we remove all CHECK constraints with the given name
! 	 */
  
! 	deleted += RemoveCheckConstraint(rel, constrName, inh);
  
! 	/*
! 	 * Now we remove NULL, UNIQUE, PRIMARY KEY and FOREIGN KEY
! 	 * constraints.
! 	 *
! 	 * Unimplemented.
! 	 */
  
! 	/* Close the target relation */
  	heap_close(rel, NoLock);
- 
- 	/* If zero constraints deleted, complain */
- 	if (deleted == 0)
- 		elog(ERROR, "ALTER TABLE / DROP CONSTRAINT: %s does not exist",
- 			 constrName);
- 	/* Otherwise if more than one constraint deleted, notify */
- 	else if (deleted > 1)
- 		elog(NOTICE, "Multiple constraints dropped");
  }
  
  /*
--- 2741,2776 ----
  		elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
  			 RelationGetRelationName(rel));
  
! 	if (!pg_class_ownercheck(relId, GetUserId()))
  		aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
  
  
! 	/* Find the ID of our constraint */
! 	ScanKeyEntryInitialize(&skey[i++],
! 						   0, Anum_pg_constraint_conrelid, F_OIDEQ,
! 						   ObjectIdGetDatum(relId));
! 	ScanKeyEntryInitialize(&skey[i++],
! 						   0, Anum_pg_constraint_conname, F_NAMEEQ,
! 						   NameGetDatum(constrName));
! 
! 	conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
! 	rcscan = systable_beginscan(conDesc, ConstraintRelidNameIndex, true,
! 								SnapshotNow,
! 								i, skey);
  
! 	tup = systable_getnext(rcscan);
  
! 	/* If the constraint doesn't exist then throw an error */
! 	if (!HeapTupleIsValid(tup))
! 		elog(ERROR, "ALTER TABLE / DROP CONSTRAINT: %s does not exist",
! 			 constrName);
  
! 	/* Call for removal of the constraint */
! 	DropConstraintById(tup->t_data->t_oid, behavior);
  
! 	/* Clean up and exit */
! 	systable_endscan(rcscan);
  	heap_close(rel, NoLock);
  }
  
  /*
Index: src/backend/commands/trigger.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.119
diff -c -r1.119 trigger.c
*** src/backend/commands/trigger.c	2002/05/24 18:57:55	1.119
--- src/backend/commands/trigger.c	2002/06/15 16:38:22
***************
*** 18,28 ****
  #include "catalog/catalog.h"
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_trigger.h"
- #include "commands/comment.h"
  #include "commands/trigger.h"
  #include "executor/executor.h"
  #include "miscadmin.h"
--- 18,28 ----
  #include "catalog/catalog.h"
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_trigger.h"
  #include "commands/trigger.h"
  #include "executor/executor.h"
  #include "miscadmin.h"
***************
*** 50,56 ****
  					   MemoryContext per_tuple_context);
  
  
! void
  CreateTrigger(CreateTrigStmt *stmt)
  {
  	int16		tgtype;
--- 50,56 ----
  					   MemoryContext per_tuple_context);
  
  
! Oid
  CreateTrigger(CreateTrigStmt *stmt)
  {
  	int16		tgtype;
***************
*** 71,79 ****
  	Oid			funclang;
  	int			found = 0;
  	int			i;
- 	char		constrtrigname[NAMEDATALEN];
  	char	   *constrname = "";
  	Oid			constrrelid = InvalidOid;
  
  	rel = heap_openrv(stmt->relation, AccessExclusiveLock);
  
--- 71,81 ----
  	Oid			funclang;
  	int			found = 0;
  	int			i;
  	char	   *constrname = "";
  	Oid			constrrelid = InvalidOid;
+ 	Oid			insertOid, insertTupOid;
+ 	ObjectAddress	myself,
+ 					dependee;
  
  	rel = heap_openrv(stmt->relation, AccessExclusiveLock);
  
***************
*** 89,111 ****
  						  stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER);
  	if (aclresult != ACLCHECK_OK)
  		aclcheck_error(aclresult, RelationGetRelationName(rel));
- 
- 	/*
- 	 * If trigger is an RI constraint, use trigger name as constraint name
- 	 * and build a unique trigger name instead.
- 	 */
- 	if (stmt->isconstraint)
- 	{
- 		constrname = stmt->trigname;
- 		snprintf(constrtrigname, sizeof(constrtrigname),
- 				 "RI_ConstraintTrigger_%u", newoid());
- 		stmt->trigname = constrtrigname;
  
! 		if (stmt->constrrel != NULL)
! 			constrrelid = RangeVarGetRelid(stmt->constrrel, false);
! 		else
! 			constrrelid = InvalidOid;
! 	}
  
  	TRIGGER_CLEAR_TYPE(tgtype);
  	if (stmt->before)
--- 91,102 ----
  						  stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER);
  	if (aclresult != ACLCHECK_OK)
  		aclcheck_error(aclresult, RelationGetRelationName(rel));
  
! 	/* Fetch the constraint relation */
! 	if (stmt->constrrel != NULL)
! 		constrrelid = RangeVarGetRelid(stmt->constrrel, false);
! 	else
! 		constrrelid = InvalidOid;
  
  	TRIGGER_CLEAR_TYPE(tgtype);
  	if (stmt->before)
***************
*** 229,235 ****
  		foreach(le, stmt->args)
  		{
  			char	   *ar = ((Value *) lfirst(le))->val.str;
- 
  			len += strlen(ar) + 4;
  			for (; *ar; ar++)
  			{
--- 220,225 ----
***************
*** 267,272 ****
--- 257,264 ----
  
  	tuple = heap_formtuple(tgrel->rd_att, values, nulls);
  
+ 	insertOid = tgrel->rd_id;
+ 
  	/*
  	 * Insert tuple into pg_trigger.
  	 */
***************
*** 274,279 ****
--- 266,275 ----
  	CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
  	CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
  	CatalogCloseIndices(Num_pg_trigger_indices, idescs);
+ 
+ 	/* Need the Inserted Tup Oid below for the address of 'myself' */
+ 	insertTupOid = tuple->t_data->t_oid;
+ 
  	heap_freetuple(tuple);
  	heap_close(tgrel, RowExclusiveLock);
  
***************
*** 302,307 ****
--- 298,331 ----
  	heap_close(pgrel, RowExclusiveLock);
  
  	/*
+ 	 * Insert dependencies
+ 	 */
+ 	myself.classId = insertOid;
+ 	myself.objectId = insertTupOid;
+ 	myself.objectSubId = 0;
+ 
+ 	/* tgrelid */
+ 	dependee.classId = RelOid_pg_class;
+ 	dependee.objectId = RelationGetRelid(rel);
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, true);
+ 
+ 	/* tgfoid */
+ 	dependee.classId = RelOid_pg_proc;
+ 	dependee.objectId = funcoid;
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, false);
+ 
+ 	/* tgconstrrelid */
+ 	if (constrrelid != InvalidOid)
+ 	{
+ 		dependee.classId = RelOid_pg_class;
+ 		dependee.objectId = constrrelid;
+ 		dependee.objectSubId = 0;
+ 		dependCreate(&myself, &dependee, true);
+ 	}
+ 
+ 	/*
  	 * We used to try to update the rel's relcache entry here, but that's
  	 * fairly pointless since it will happen as a byproduct of the
  	 * upcoming CommandCounterIncrement...
***************
*** 309,321 ****
  
  	/* Keep lock on target rel until end of xact */
  	heap_close(rel, NoLock);
  }
  
  /*
   * DropTrigger - drop an individual trigger by name
   */
  void
! DropTrigger(Oid relid, const char *trigname)
  {
  	Relation	rel;
  	Relation	tgrel;
--- 333,402 ----
  
  	/* Keep lock on target rel until end of xact */
  	heap_close(rel, NoLock);
+ 
+ 	return insertTupOid;
  }
  
+ char *
+ getTriggerName(Oid relId, char *prefix)
+ {
+ 	int			j = 1;
+ 	bool		success;
+ 	Relation	trgDesc;
+ 	HeapTuple	tup;
+ 	char	   *cname;
+ 
+ 	cname = palloc(NAMEDATALEN * sizeof(char));
+ 
+ 	trgDesc = heap_openr(TriggerRelationName, RowExclusiveLock);
+ 
+ 	if (prefix == NULL)
+ 		prefix = "trigger";
+ 
+ 	/* Loop until we find a non-conflicting constraint name */
+ 	/* What happens if this loops forever? */
+ 	do
+ 	{
+ 		int			i = 0;
+ 		SysScanDesc rcscan;
+ 		ScanKeyData skey[2];
+ 
+ 		success = false;
+ 
+ 		snprintf(cname, NAMEDATALEN, "%s_%d", prefix, j);
+ 
+ 		/* make sure there is no existing constraints of the same name */
+ 		ScanKeyEntryInitialize(&skey[i++],
+ 							   0, Anum_pg_trigger_tgrelid, F_OIDEQ,
+ 							   ObjectIdGetDatum(relId));
+ 
+ 		ScanKeyEntryInitialize(&skey[i++],
+ 							   0, Anum_pg_trigger_tgname, F_NAMEEQ,
+ 							   NameGetDatum(cname));
+ 
+ 		rcscan = systable_beginscan(trgDesc, TriggerRelidNameIndex, true,
+ 									SnapshotNow,
+ 									i, skey);
+ 
+ 		tup = systable_getnext(rcscan);
+ 		if (!HeapTupleIsValid(tup))
+ 			success = true;
+ 
+ 		systable_endscan(rcscan);
+ 		++j;
+ 	} while (!success);
+ 
+ 	/* Cleanup, but keep lock */
+ 	heap_close(trgDesc, NoLock);
+ 
+ 	return cname;
+ }
+ 
  /*
   * DropTrigger - drop an individual trigger by name
   */
  void
! DropTrigger(Oid relid, const char *trigname, int behavior)
  {
  	Relation	rel;
  	Relation	tgrel;
***************
*** 363,370 ****
  
  		if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
  		{
! 			/* Delete any comments associated with this trigger */
! 			DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel));
  
  			simple_heap_delete(tgrel, &tuple->t_self);
  			found++;
--- 444,451 ----
  
  		if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
  		{
! 			/* Deal with dependencies */
! 			dependDeleteTuple(tuple, tgrel, behavior);
  
  			simple_heap_delete(tgrel, &tuple->t_self);
  			found++;
***************
*** 408,505 ****
  }
  
  /*
!  * Remove all triggers for a relation that's being deleted.
   */
  void
! RelationRemoveTriggers(Relation rel)
  {
! 	Relation	tgrel;
! 	SysScanDesc	tgscan;
! 	ScanKeyData key;
! 	HeapTuple	tup;
! 	bool		found = false;
  
  	tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
! 	ScanKeyEntryInitialize(&key, 0,
! 						   Anum_pg_trigger_tgrelid,
  						   F_OIDEQ,
! 						   ObjectIdGetDatum(RelationGetRelid(rel)));
! 	tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
! 								SnapshotNow, 1, &key);
  
! 	while (HeapTupleIsValid(tup = systable_getnext(tgscan)))
! 	{
! 		/* Delete any comments associated with this trigger */
! 		DeleteComments(tup->t_data->t_oid, RelationGetRelid(tgrel));
  
! 		simple_heap_delete(tgrel, &tup->t_self);
  
! 		found = true;
! 	}
  
! 	systable_endscan(tgscan);
  
! 	/*
! 	 * If we deleted any triggers, must update pg_class entry and advance
! 	 * command counter to make the updated entry visible. This is fairly
! 	 * annoying, since we'e just going to drop the durn thing later, but
! 	 * it's necessary to have a consistent state in case we do
! 	 * CommandCounterIncrement() below --- if RelationBuildTriggers()
! 	 * runs, it will complain otherwise. Perhaps RelationBuildTriggers()
! 	 * shouldn't be so picky...
! 	 */
! 	if (found)
! 	{
! 		Relation	pgrel;
! 		Relation	ridescs[Num_pg_class_indices];
  
! 		pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
! 		tup = SearchSysCacheCopy(RELOID,
! 								 ObjectIdGetDatum(RelationGetRelid(rel)),
! 								 0, 0, 0);
! 		if (!HeapTupleIsValid(tup))
! 			elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class",
! 				 RelationGetRelid(rel));
  
! 		((Form_pg_class) GETSTRUCT(tup))->reltriggers = 0;
! 		simple_heap_update(pgrel, &tup->t_self, tup);
! 		CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
! 		CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tup);
! 		CatalogCloseIndices(Num_pg_class_indices, ridescs);
! 		heap_freetuple(tup);
! 		heap_close(pgrel, RowExclusiveLock);
! 		CommandCounterIncrement();
! 	}
  
  	/*
! 	 * Also drop all constraint triggers referencing this relation
  	 */
! 	ScanKeyEntryInitialize(&key, 0,
! 						   Anum_pg_trigger_tgconstrrelid,
! 						   F_OIDEQ,
! 						   ObjectIdGetDatum(RelationGetRelid(rel)));
! 	tgscan = systable_beginscan(tgrel, TriggerConstrRelidIndex, true,
! 								SnapshotNow, 1, &key);
! 
! 	while (HeapTupleIsValid(tup = systable_getnext(tgscan)))
! 	{
! 		Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
  
! 		elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"",
! 			 get_rel_name(pg_trigger->tgrelid));
  
! 		DropTrigger(pg_trigger->tgrelid, NameStr(pg_trigger->tgname));
  
! 		/*
! 		 * Need to do a command counter increment here to show up new
! 		 * pg_class.reltriggers in the next loop iteration (in case there
! 		 * are multiple referential integrity action triggers for the same
! 		 * FK table defined on the PK table).
! 		 */
! 		CommandCounterIncrement();
! 	}
! 	systable_endscan(tgscan);
  
  	heap_close(tgrel, RowExclusiveLock);
  }
  
--- 489,566 ----
  }
  
  /*
!  * DropTriggerById - Drop a trigger by it's OID
   */
  void
! DropTriggerById(Oid trigId, int behavior)
  {
! 	Relation		rel;
! 	Relation		tgrel;
! 	SysScanDesc		tgscan;
! 	ScanKeyData 	key[1];
! 	Relation		pgrel;
! 	HeapTuple		tuple;
! 	Relation		ridescs[Num_pg_class_indices];
! 	Form_pg_trigger	pg_trigger;
! 	Form_pg_class	pg_class;
! 	int				nkeys = 0;
  
+ 	/*
+ 	 * Search pg_trigger, delete target trigger, count remaining triggers
+ 	 * for relation.  Note this is OK only because we have
+ 	 * AccessExclusiveLock on the rel, so no one else is creating/deleting
+ 	 * triggers on this rel at the same time.
+ 	 */
  	tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
! 	ScanKeyEntryInitialize(&key[nkeys++], 0, ObjectIdAttributeNumber,
  						   F_OIDEQ,
! 						   ObjectIdGetDatum(trigId));
  
! 	tgscan = systable_beginscan(tgrel, 0, false,
! 								SnapshotNow, nkeys, key);
  
! 	tuple = systable_getnext(tgscan);
  
! 	if (!HeapTupleIsValid(tuple))
! 		elog(ERROR, "DropTriggerById: TriggerID %d not valid", trigId);
  
! 	/* Grab the info, and lock the triggers relation */
! 	pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
  
! 	rel = heap_open(pg_trigger->tgrelid, AccessExclusiveLock);
  
! 	/* Deal with dependencies */
! 	dependDeleteTuple(tuple, tgrel, behavior);
  
! 	simple_heap_delete(tgrel, &tuple->t_self);
! 
! 	systable_endscan(tgscan);
! 	heap_close(rel, AccessExclusiveLock);
  
  	/*
! 	 * Update relation's pg_class entry.  Crucial side-effect: other
! 	 * backends (and this one too!) are sent SI message to make them
! 	 * rebuild relcache entries.
  	 */
! 	pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
! 	tuple = SearchSysCacheCopy(RELOID,
! 							   ObjectIdGetDatum(RelationGetRelid(rel)),
! 							   0, 0, 0);
! 	if (!HeapTupleIsValid(tuple))
! 		elog(ERROR, "DropTriggerById: relation %s not found in pg_class",
! 			 RelationGetRelationName(rel));
  
! 	pg_class = (Form_pg_class) GETSTRUCT(tuple);
  
! 	pg_class->reltriggers -= 1;
  
! 	simple_heap_update(pgrel, &tuple->t_self, tuple);
! 	CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
! 	CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tuple);
! 	CatalogCloseIndices(Num_pg_class_indices, ridescs);
! 	heap_freetuple(tuple);
  
+ 	heap_close(pgrel, RowExclusiveLock);
  	heap_close(tgrel, RowExclusiveLock);
  }
  
Index: src/backend/commands/typecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/typecmds.c,v
retrieving revision 1.3
diff -c -r1.3 typecmds.c
*** src/backend/commands/typecmds.c	2002/05/03 00:32:16	1.3
--- src/backend/commands/typecmds.c	2002/06/15 16:38:22
***************
*** 35,42 ****
  #include "catalog/catname.h"
  #include "catalog/heap.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_type.h"
- #include "commands/comment.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse.h"
--- 35,42 ----
  #include "catalog/catname.h"
  #include "catalog/heap.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/pg_type.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse.h"
***************
*** 268,279 ****
   * only work on scalar types.
   */
  void
! RemoveType(List *names)
  {
  	TypeName   *typename;
- 	Relation	relation;
- 	Oid			typeoid;
- 	HeapTuple	tup;
  
  	/* Make a TypeName so we can use standard type lookup machinery */
  	typename = makeNode(TypeName);
--- 268,276 ----
   * only work on scalar types.
   */
  void
! RemoveType(List *names, int behavior)
  {
  	TypeName   *typename;
  
  	/* Make a TypeName so we can use standard type lookup machinery */
  	typename = makeNode(TypeName);
***************
*** 281,286 ****
--- 278,297 ----
  	typename->typmod = -1;
  	typename->arrayBounds = NIL;
  
+ 	RemoveTypeByTypeName(typename, behavior);
+ }
+ 
+ /*
+  *	TypeRemove
+  *		Removes a datatype by the typename struct
+  */
+ void
+ RemoveTypeByTypeName(TypeName *typename, int behavior)
+ {
+ 	Relation	relation;
+ 	Oid			typeoid;
+ 	HeapTuple	tup;
+ 
  	relation = heap_openr(TypeRelationName, RowExclusiveLock);
  
  	/* Use LookupTypeName here so that shell types can be removed. */
***************
*** 301,331 ****
  		!pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace,
  								 GetUserId()))
  		aclcheck_error(ACLCHECK_NOT_OWNER, TypeNameToString(typename));
- 
- 	/* Delete any comments associated with this type */
- 	DeleteComments(typeoid, RelationGetRelid(relation));
- 
- 	/* Remove the type tuple from pg_type */
- 	simple_heap_delete(relation, &tup->t_self);
- 
- 	ReleaseSysCache(tup);
- 
- 	/* Now, delete the "array of" that type */
- 	typename->arrayBounds = makeList1(makeInteger(1));
- 
- 	typeoid = LookupTypeName(typename);
- 	if (!OidIsValid(typeoid))
- 		elog(ERROR, "Type \"%s\" does not exist",
- 			 TypeNameToString(typename));
  
! 	tup = SearchSysCache(TYPEOID,
! 						 ObjectIdGetDatum(typeoid),
! 						 0, 0, 0);
! 	if (!HeapTupleIsValid(tup))
! 		elog(ERROR, "Type \"%s\" does not exist",
  			 TypeNameToString(typename));
  
! 	DeleteComments(typeoid, RelationGetRelid(relation));
  
  	simple_heap_delete(relation, &tup->t_self);
  
--- 312,324 ----
  		!pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace,
  								 GetUserId()))
  		aclcheck_error(ACLCHECK_NOT_OWNER, TypeNameToString(typename));
  
! 	if (!pg_type_ownercheck(typeoid, GetUserId()))
! 		elog(ERROR, "RemoveType: type '%s': permission denied",
  			 TypeNameToString(typename));
  
! 	/* Deal with dependencies */
! 	dependDeleteTuple(tup, relation, behavior);
  
  	simple_heap_delete(relation, &tup->t_self);
  
***************
*** 582,591 ****
  	HeapTuple	tup;
  	char		typtype;
  
- 	/* CASCADE unsupported */
- 	if (behavior == CASCADE)
- 		elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword");
- 
  	/* Make a TypeName so we can use standard type lookup machinery */
  	typename = makeNode(TypeName);
  	typename->names = names;
--- 575,580 ----
***************
*** 616,630 ****
  		elog(ERROR, "%s is not a domain",
  			 TypeNameToString(typename));
  
! 	/* Delete any comments associated with this type */
! 	DeleteComments(typeoid, RelationGetRelid(relation));
  
  	/* Remove the type tuple from pg_type */
  	simple_heap_delete(relation, &tup->t_self);
  
  	ReleaseSysCache(tup);
- 
- 	/* At present, domains don't have associated array types */
  
  	heap_close(relation, RowExclusiveLock);
  }
--- 605,617 ----
  		elog(ERROR, "%s is not a domain",
  			 TypeNameToString(typename));
  
! 	/* Deal with dependencies */
! 	dependDeleteTuple(tup, relation, behavior);
  
  	/* Remove the type tuple from pg_type */
  	simple_heap_delete(relation, &tup->t_self);
  
  	ReleaseSysCache(tup);
  
  	heap_close(relation, RowExclusiveLock);
  }
Index: src/backend/commands/view.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/view.c,v
retrieving revision 1.63
diff -c -r1.63 view.c
*** src/backend/commands/view.c	2002/04/19 23:13:54	1.63
--- src/backend/commands/view.c	2002/06/15 16:38:22
***************
*** 255,261 ****
   *------------------------------------------------------------------
   */
  void
! RemoveView(const RangeVar *view)
  {
  	Oid			viewOid;
  
--- 255,261 ----
   *------------------------------------------------------------------
   */
  void
! RemoveView(const RangeVar *view, int behavior)
  {
  	Oid			viewOid;
  
***************
*** 264,268 ****
  	 * We just have to drop the relation; the associated rules will be
  	 * cleaned up automatically.
  	 */
! 	heap_drop_with_catalog(viewOid, allowSystemTableMods);
  }
--- 264,268 ----
  	 * We just have to drop the relation; the associated rules will be
  	 * cleaned up automatically.
  	 */
! 	heap_drop_with_catalog(viewOid, allowSystemTableMods, behavior);
  }
Index: src/backend/nodes/copyfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.188
diff -c -r1.188 copyfuncs.c
*** src/backend/nodes/copyfuncs.c	2002/05/22 17:20:58	1.188
--- src/backend/nodes/copyfuncs.c	2002/06/15 16:38:26
***************
*** 1505,1512 ****
  	Node_Copy(from, newnode, pktable);
  	Node_Copy(from, newnode, fk_attrs);
  	Node_Copy(from, newnode, pk_attrs);
! 	if (from->match_type)
! 		newnode->match_type = pstrdup(from->match_type);
  	newnode->actions = from->actions;
  	newnode->deferrable = from->deferrable;
  	newnode->initdeferred = from->initdeferred;
--- 1505,1511 ----
  	Node_Copy(from, newnode, pktable);
  	Node_Copy(from, newnode, fk_attrs);
  	Node_Copy(from, newnode, pk_attrs);
! 	newnode->match_type = from->match_type;
  	newnode->actions = from->actions;
  	newnode->deferrable = from->deferrable;
  	newnode->initdeferred = from->initdeferred;
***************
*** 1642,1647 ****
--- 1641,1647 ----
  	newnode->setof = from->setof;
  	newnode->pct_type = from->pct_type;
  	newnode->typmod = from->typmod;
+ 	newnode->serial = from->serial;
  	Node_Copy(from, newnode, arrayBounds);
  
  	return newnode;
Index: src/backend/nodes/equalfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.135
diff -c -r1.135 equalfuncs.c
*** src/backend/nodes/equalfuncs.c	2002/05/22 17:20:59	1.135
--- src/backend/nodes/equalfuncs.c	2002/06/15 16:38:29
***************
*** 1602,1607 ****
--- 1602,1609 ----
  		return false;
  	if (!equal(a->arrayBounds, b->arrayBounds))
  		return false;
+ 	if (a->serial != b->serial)
+ 		return false;
  
  	return true;
  }
***************
*** 1736,1742 ****
  		return false;
  	if (!equal(a->pk_attrs, b->pk_attrs))
  		return false;
! 	if (!equalstr(a->match_type, b->match_type))
  		return false;
  	if (a->actions != b->actions)
  		return false;
--- 1738,1744 ----
  		return false;
  	if (!equal(a->pk_attrs, b->pk_attrs))
  		return false;
! 	if (a->match_type != b->match_type)
  		return false;
  	if (a->actions != b->actions)
  		return false;
Index: src/backend/nodes/outfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/outfuncs.c,v
retrieving revision 1.159
diff -c -r1.159 outfuncs.c
*** src/backend/nodes/outfuncs.c	2002/05/12 23:43:02	1.159
--- src/backend/nodes/outfuncs.c	2002/06/15 16:38:32
***************
*** 1444,1451 ****
  	_outNode(str, node->fk_attrs);
  	appendStringInfo(str, " :pk_attrs ");
  	_outNode(str, node->pk_attrs);
! 	appendStringInfo(str, " :match_type ");
! 	_outToken(str, node->match_type);
  	appendStringInfo(str, " :actions %d :deferrable %s :initdeferred %s",
  					 node->actions,
  					 booltostr(node->deferrable),
--- 1444,1451 ----
  	_outNode(str, node->fk_attrs);
  	appendStringInfo(str, " :pk_attrs ");
  	_outNode(str, node->pk_attrs);
! 	appendStringInfo(str, " :match_type %c",
! 					 node->match_type);
  	appendStringInfo(str, " :actions %d :deferrable %s :initdeferred %s",
  					 node->actions,
  					 booltostr(node->deferrable),
Index: src/backend/parser/analyze.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v
retrieving revision 1.236
diff -c -r1.236 analyze.c
*** src/backend/parser/analyze.c	2002/06/13 02:04:46	1.236
--- src/backend/parser/analyze.c	2002/06/15 16:38:41
***************
*** 773,781 ****
  	q->commandType = CMD_UTILITY;
  	q->utilityStmt = (Node *) stmt;
  	stmt->tableElts = cxt.columns;
! 	stmt->constraints = cxt.ckconstraints;
! 	*extras_before = nconc (*extras_before, cxt.blist);
! 	*extras_after = nconc (cxt.alist, *extras_after);
  
  	return q;
  }
--- 773,781 ----
  	q->commandType = CMD_UTILITY;
  	q->utilityStmt = (Node *) stmt;
  	stmt->tableElts = cxt.columns;
! 	stmt->constraints = nconc(cxt.ckconstraints, cxt.fkconstraints);
! 	*extras_before = nconc(*extras_before, cxt.blist);
! 	*extras_after = nconc(cxt.alist, *extras_after);
  
  	return q;
  }
***************
*** 826,837 ****
--- 826,839 ----
  		A_Const    *snamenode;
  		FuncCall   *funccallnode;
  		CreateSeqStmt *seqstmt;
+ 		RangeVar   *srvar;
  
  		/*
  		 * Determine name and namespace to use for the sequence.
  		 */
  		sname = makeObjectName(cxt->relation->relname, column->colname, "seq");
  		snamespace = get_namespace_name(RangeVarGetCreationNamespace(cxt->relation));
+ 		srvar=makeRangeVar(snamespace, sname);
  
  		elog(NOTICE, "%s will create implicit sequence '%s' for SERIAL column '%s.%s'",
  			 cxt->stmtType, sname, cxt->relation->relname, column->colname);
***************
*** 842,853 ****
  		 * CREATE/ALTER TABLE.
  		 */
  		seqstmt = makeNode(CreateSeqStmt);
! 		seqstmt->sequence = makeRangeVar(snamespace, sname);
  		seqstmt->options = NIL;
  
  		cxt->blist = lappend(cxt->blist, seqstmt);
  
  		/*
  		 * Create appropriate constraints for SERIAL.  We do this in full,
  		 * rather than shortcutting, so that we will detect any
  		 * conflicting constraints the user wrote (like a different
--- 844,861 ----
  		 * CREATE/ALTER TABLE.
  		 */
  		seqstmt = makeNode(CreateSeqStmt);
! 		seqstmt->sequence = srvar;
  		seqstmt->options = NIL;
  
  		cxt->blist = lappend(cxt->blist, seqstmt);
  
  		/*
+ 		 * Keep the serial name so that lateron the table can create an
+ 		 * implicit dependency to drop the serial with the table
+ 		 */
+ 		column->typename->serial = srvar;
+ 
+ 		/*
  		 * Create appropriate constraints for SERIAL.  We do this in full,
  		 * rather than shortcutting, so that we will detect any
  		 * conflicting constraints the user wrote (like a different
***************
*** 1304,1315 ****
  static void
  transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
  {
- 	CreateTrigStmt *fk_trigger;
  	List	   *fkactions = NIL;
  	List	   *fkclist;
- 	List	   *fk_attr;
- 	List	   *pk_attr;
- 	Ident	   *id;
  	Oid			pktypoid[INDEX_MAX_KEYS];
  	Oid			fktypoid[INDEX_MAX_KEYS];
  	int			i;
--- 1312,1319 ----
***************
*** 1325,1336 ****
  		FkConstraint *fkconstraint = (FkConstraint *) lfirst(fkclist);
  		int			attnum;
  		List	   *fkattrs;
  
  		/*
  		 * If the constraint has no name, set it to <unnamed>
  		 */
  		if (fkconstraint->constr_name == NULL)
! 			fkconstraint->constr_name = "<unnamed>";
  
  		for (attnum = 0; attnum < INDEX_MAX_KEYS; attnum++)
  			pktypoid[attnum] = fktypoid[attnum] = InvalidOid;
--- 1329,1343 ----
  		FkConstraint *fkconstraint = (FkConstraint *) lfirst(fkclist);
  		int			attnum;
  		List	   *fkattrs;
+ 		char	   *fkname;
  
  		/*
  		 * If the constraint has no name, set it to <unnamed>
  		 */
  		if (fkconstraint->constr_name == NULL)
! 			fkname = "<unnamed>";
! 		else
! 			fkname = fkconstraint->constr_name;
  
  		for (attnum = 0; attnum < INDEX_MAX_KEYS; attnum++)
  			pktypoid[attnum] = fktypoid[attnum] = InvalidOid;
***************
*** 1472,1675 ****
  			ReleaseSysCache(o);
  		}
  
- 		/*
- 		 * Build a CREATE CONSTRAINT TRIGGER statement for the CHECK
- 		 * action.
- 		 */
- 		fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
- 		fk_trigger->trigname = fkconstraint->constr_name;
- 		fk_trigger->relation = cxt->relation;
- 		fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
- 		fk_trigger->before = false;
- 		fk_trigger->row = true;
- 		fk_trigger->actions[0] = 'i';
- 		fk_trigger->actions[1] = 'u';
- 		fk_trigger->actions[2] = '\0';
- 		fk_trigger->lang = NULL;
- 		fk_trigger->text = NULL;
- 
- 		fk_trigger->attr = NIL;
- 		fk_trigger->when = NULL;
- 		fk_trigger->isconstraint = true;
- 		fk_trigger->deferrable = fkconstraint->deferrable;
- 		fk_trigger->initdeferred = fkconstraint->initdeferred;
- 		fk_trigger->constrrel = fkconstraint->pktable;
- 
- 		fk_trigger->args = NIL;
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString(fkconstraint->constr_name));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString((cxt->relation)->relname));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								 makeString(fkconstraint->pktable->relname));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString(fkconstraint->match_type));
- 		fk_attr = fkconstraint->fk_attrs;
- 		pk_attr = fkconstraint->pk_attrs;
- 		if (length(fk_attr) != length(pk_attr))
- 			elog(ERROR, "number of key attributes in referenced table must be equal to foreign key"
- 				 "\n\tIllegal FOREIGN KEY definition references \"%s\"",
- 				 fkconstraint->pktable->relname);
- 
- 		while (fk_attr != NIL)
- 		{
- 			id = (Ident *) lfirst(fk_attr);
- 			fk_trigger->args = lappend(fk_trigger->args,
- 									   makeString(id->name));
- 
- 			id = (Ident *) lfirst(pk_attr);
- 			fk_trigger->args = lappend(fk_trigger->args,
- 									   makeString(id->name));
- 
- 			fk_attr = lnext(fk_attr);
- 			pk_attr = lnext(pk_attr);
- 		}
- 
- 		fkactions = lappend(fkactions, (Node *) fk_trigger);
- 
  		/*
! 		 * Build a CREATE CONSTRAINT TRIGGER statement for the ON DELETE
! 		 * action fired on the PK table !!!
  		 */
- 		fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
- 		fk_trigger->trigname = fkconstraint->constr_name;
- 		fk_trigger->relation = fkconstraint->pktable;
- 		fk_trigger->before = false;
- 		fk_trigger->row = true;
- 		fk_trigger->actions[0] = 'd';
- 		fk_trigger->actions[1] = '\0';
- 		fk_trigger->lang = NULL;
- 		fk_trigger->text = NULL;
- 
- 		fk_trigger->attr = NIL;
- 		fk_trigger->when = NULL;
- 		fk_trigger->isconstraint = true;
- 		fk_trigger->deferrable = fkconstraint->deferrable;
- 		fk_trigger->initdeferred = fkconstraint->initdeferred;
- 		fk_trigger->constrrel = cxt->relation;
- 		switch ((fkconstraint->actions & FKCONSTR_ON_DELETE_MASK)
- 				>> FKCONSTR_ON_DELETE_SHIFT)
- 		{
- 			case FKCONSTR_ON_KEY_NOACTION:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
- 				break;
- 			case FKCONSTR_ON_KEY_RESTRICT:
- 				fk_trigger->deferrable = false;
- 				fk_trigger->initdeferred = false;
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
- 				break;
- 			case FKCONSTR_ON_KEY_CASCADE:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
- 				break;
- 			case FKCONSTR_ON_KEY_SETNULL:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
- 				break;
- 			case FKCONSTR_ON_KEY_SETDEFAULT:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
- 				break;
- 			default:
- 				elog(ERROR, "Only one ON DELETE action can be specified for FOREIGN KEY constraint");
- 				break;
- 		}
- 
- 		fk_trigger->args = NIL;
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString(fkconstraint->constr_name));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString((cxt->relation)->relname));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								 makeString(fkconstraint->pktable->relname));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString(fkconstraint->match_type));
- 		fk_attr = fkconstraint->fk_attrs;
- 		pk_attr = fkconstraint->pk_attrs;
- 		while (fk_attr != NIL)
- 		{
- 			id = (Ident *) lfirst(fk_attr);
- 			fk_trigger->args = lappend(fk_trigger->args,
- 									   makeString(id->name));
- 
- 			id = (Ident *) lfirst(pk_attr);
- 			fk_trigger->args = lappend(fk_trigger->args,
- 									   makeString(id->name));
- 
- 			fk_attr = lnext(fk_attr);
- 			pk_attr = lnext(pk_attr);
- 		}
- 
- 		fkactions = lappend(fkactions, (Node *) fk_trigger);
- 
- 		/*
- 		 * Build a CREATE CONSTRAINT TRIGGER statement for the ON UPDATE
- 		 * action fired on the PK table !!!
- 		 */
- 		fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
- 		fk_trigger->trigname = fkconstraint->constr_name;
- 		fk_trigger->relation = fkconstraint->pktable;
- 		fk_trigger->before = false;
- 		fk_trigger->row = true;
- 		fk_trigger->actions[0] = 'u';
- 		fk_trigger->actions[1] = '\0';
- 		fk_trigger->lang = NULL;
- 		fk_trigger->text = NULL;
- 
- 		fk_trigger->attr = NIL;
- 		fk_trigger->when = NULL;
- 		fk_trigger->isconstraint = true;
- 		fk_trigger->deferrable = fkconstraint->deferrable;
- 		fk_trigger->initdeferred = fkconstraint->initdeferred;
- 		fk_trigger->constrrel = cxt->relation;
- 		switch ((fkconstraint->actions & FKCONSTR_ON_UPDATE_MASK)
- 				>> FKCONSTR_ON_UPDATE_SHIFT)
- 		{
- 			case FKCONSTR_ON_KEY_NOACTION:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
- 				break;
- 			case FKCONSTR_ON_KEY_RESTRICT:
- 				fk_trigger->deferrable = false;
- 				fk_trigger->initdeferred = false;
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
- 				break;
- 			case FKCONSTR_ON_KEY_CASCADE:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
- 				break;
- 			case FKCONSTR_ON_KEY_SETNULL:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
- 				break;
- 			case FKCONSTR_ON_KEY_SETDEFAULT:
- 				fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
- 				break;
- 			default:
- 				elog(ERROR, "Only one ON UPDATE action can be specified for FOREIGN KEY constraint");
- 				break;
- 		}
- 
- 		fk_trigger->args = NIL;
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString(fkconstraint->constr_name));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString((cxt->relation)->relname));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								 makeString(fkconstraint->pktable->relname));
- 		fk_trigger->args = lappend(fk_trigger->args,
- 								   makeString(fkconstraint->match_type));
- 		fk_attr = fkconstraint->fk_attrs;
- 		pk_attr = fkconstraint->pk_attrs;
- 		while (fk_attr != NIL)
- 		{
- 			id = (Ident *) lfirst(fk_attr);
- 			fk_trigger->args = lappend(fk_trigger->args,
- 									   makeString(id->name));
- 
- 			id = (Ident *) lfirst(pk_attr);
- 			fk_trigger->args = lappend(fk_trigger->args,
- 									   makeString(id->name));
- 
- 			fk_attr = lnext(fk_attr);
- 			pk_attr = lnext(pk_attr);
- 		}
- 
- 		fkactions = lappend(fkactions, (Node *) fk_trigger);
  	}
  
  	/*
--- 1479,1489 ----
  			ReleaseSysCache(o);
  		}
  
  		/*
! 		 * At one point triggers were created here and added to the alist of
! 		 * actions to complete during this statement.   Trigger creation has
! 		 * been moved to constraintCreate() for dependency tracking purposes.
  		 */
  	}
  
  	/*
***************
*** 2603,2609 ****
  			transformIndexConstraints(pstate, &cxt);
  			transformFKConstraints(pstate, &cxt);
  
! 			((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints;
  			*extras_before = nconc(*extras_before, cxt.blist);
  			*extras_after = nconc(cxt.alist, *extras_after);
  			break;
--- 2417,2423 ----
  			transformIndexConstraints(pstate, &cxt);
  			transformFKConstraints(pstate, &cxt);
  
! 			((ColumnDef *) stmt->def)->constraints = nconc(cxt.ckconstraints, cxt.fkconstraints);
  			*extras_before = nconc(*extras_before, cxt.blist);
  			*extras_after = nconc(cxt.alist, *extras_after);
  			break;
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.323
diff -c -r2.323 gram.y
*** src/backend/parser/gram.y	2002/06/15 03:00:03	2.323
--- src/backend/parser/gram.y	2002/06/15 16:38:53
***************
*** 52,57 ****
--- 52,59 ----
  
  #include "access/htup.h"
  #include "catalog/index.h"
+ #include "catalog/pg_constraint.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_type.h"
  #include "nodes/makefuncs.h"
***************
*** 152,158 ****
  				simple_select
  
  %type <node>    alter_column_default
! %type <ival>    drop_behavior, opt_drop_behavior
  
  %type <list>	createdb_opt_list, createdb_opt_item
  %type <boolean>	opt_equal
--- 154,160 ----
  				simple_select
  
  %type <node>    alter_column_default
! %type <ival>    opt_drop_behavior
  
  %type <list>	createdb_opt_list, createdb_opt_item
  %type <boolean>	opt_equal
***************
*** 295,302 ****
  %type <node>	TableConstraint
  %type <list>	ColQualList
  %type <node>	ColConstraint, ColConstraintElem, ConstraintAttr
! %type <ival>	key_actions, key_delete, key_update, key_reference
! %type <str>		key_match
  %type <ival>	ConstraintAttributeSpec, ConstraintDeferrabilitySpec,
  				ConstraintTimeSpec
  
--- 297,303 ----
  %type <node>	TableConstraint
  %type <list>	ColQualList
  %type <node>	ColConstraint, ColConstraintElem, ConstraintAttr
! %type <ival>	key_actions, key_delete, key_match, key_update, key_reference
  %type <ival>	ConstraintAttributeSpec, ConstraintDeferrabilitySpec,
  				ConstraintTimeSpec
  
***************
*** 1158,1164 ****
  					$$ = (Node *)n;
  				}
  /* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
! 		| ALTER TABLE relation_expr DROP opt_column ColId drop_behavior
  				{
  					AlterTableStmt *n = makeNode(AlterTableStmt);
  					n->subtype = 'D';
--- 1159,1165 ----
  					$$ = (Node *)n;
  				}
  /* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
! 		| ALTER TABLE relation_expr DROP opt_column ColId opt_drop_behavior
  				{
  					AlterTableStmt *n = makeNode(AlterTableStmt);
  					n->subtype = 'D';
***************
*** 1177,1183 ****
  					$$ = (Node *)n;
  				}
  /* ALTER TABLE <relation> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */
! 		| ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior
  				{
  					AlterTableStmt *n = makeNode(AlterTableStmt);
  					n->subtype = 'X';
--- 1178,1184 ----
  					$$ = (Node *)n;
  				}
  /* ALTER TABLE <relation> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */
! 		| ALTER TABLE relation_expr DROP CONSTRAINT name opt_drop_behavior
  				{
  					AlterTableStmt *n = makeNode(AlterTableStmt);
  					n->subtype = 'X';
***************
*** 1219,1231 ****
  		| DROP DEFAULT					{ $$ = NULL; }
          ;
  
! drop_behavior: CASCADE					{ $$ = CASCADE; }
! 		| RESTRICT						{ $$ = RESTRICT; }
!         ;
! 
! opt_drop_behavior: CASCADE				{ $$ = CASCADE; }
! 		| RESTRICT						{ $$ = RESTRICT; }
! 		| /* EMPTY */					{ $$ = RESTRICT; /* default */ }
  		;
  
  
--- 1220,1228 ----
  		| DROP DEFAULT					{ $$ = NULL; }
          ;
  
! opt_drop_behavior: CASCADE				{ $$ = DEPEND_CASCADE; }
! 		| RESTRICT						{ $$ = DEPEND_RESTRICT; }
! 		| /* EMPTY */					{ $$ = DEPEND_RESTRICT; /* default */ }
  		;
  
  
***************
*** 1651,1666 ****
  
  key_match:  MATCH FULL
  			{
! 				$$ = "FULL";
  			}
  		| MATCH PARTIAL
  			{
  				elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented");
! 				$$ = "PARTIAL";
  			}
  		| /*EMPTY*/
  			{
! 				$$ = "UNSPECIFIED";
  			}
  		;
  
--- 1648,1663 ----
  
  key_match:  MATCH FULL
  			{
! 				$$ = CONSTRAINT_FKEY_FULL;
  			}
  		| MATCH PARTIAL
  			{
  				elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented");
! 				$$ = CONSTRAINT_FKEY_PARTIAL;
  			}
  		| /*EMPTY*/
  			{
! 				$$ = CONSTRAINT_FKEY_UNSPECIFIED;
  			}
  		;
  
***************
*** 1869,1878 ****
  			| /*EMPTY*/ { $$ = NULL; }
  		;
  
! DropPLangStmt:  DROP opt_procedural LANGUAGE ColId_or_Sconst
  			{
  				DropPLangStmt *n = makeNode(DropPLangStmt);
  				n->plname = $4;
  				$$ = (Node *)n;
  			}
  		;
--- 1866,1876 ----
  			| /*EMPTY*/ { $$ = NULL; }
  		;
  
! DropPLangStmt:  DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior
  			{
  				DropPLangStmt *n = makeNode(DropPLangStmt);
  				n->plname = $4;
+ 				n->behavior = $5;
  				$$ = (Node *)n;
  			}
  		;
***************
*** 2061,2071 ****
  		;
  
  
! DropTrigStmt:  DROP TRIGGER name ON qualified_name
  				{
  					DropPropertyStmt *n = makeNode(DropPropertyStmt);
  					n->relation = $5;
  					n->property = $3;
  					n->removeType = DROP_TRIGGER;
  					$$ = (Node *) n;
  				}
--- 2059,2070 ----
  		;
  
  
! DropTrigStmt:  DROP TRIGGER name ON qualified_name opt_drop_behavior
  				{
  					DropPropertyStmt *n = makeNode(DropPropertyStmt);
  					n->relation = $5;
  					n->property = $3;
+ 					n->behavior = $6;
  					n->removeType = DROP_TRIGGER;
  					$$ = (Node *) n;
  				}
***************
*** 2289,2294 ****
--- 2288,2302 ----
  				n->comment = $8;
  				$$ = (Node *) n;
  			}
+ 		| COMMENT ON CONSTRAINT name ON any_name IS comment_text
+ 			{
+ 				CommentStmt *n = makeNode(CommentStmt);
+ 				n->objtype = CONSTRAINT;
+ 				n->objname = lappend($6, makeString($4));
+ 				n->objargs = NIL;
+ 				n->comment = $8;
+ 				$$ = (Node *) n;
+ 			}
  		| COMMENT ON RULE name ON any_name IS comment_text
  			{
  				CommentStmt *n = makeNode(CommentStmt);
***************
*** 2966,2985 ****
   *
   *****************************************************************************/
  
! RemoveFuncStmt:  DROP FUNCTION func_name func_args
  				{
  					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
  					n->funcname = $3;
  					n->args = $4;
  					$$ = (Node *)n;
  				}
  		;
  
! RemoveAggrStmt:  DROP AGGREGATE func_name '(' aggr_argtype ')'
  				{
  						RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
  						n->aggname = $3;
  						n->aggtype = $5;
  						$$ = (Node *)n;
  				}
  		;
--- 2974,2995 ----
   *
   *****************************************************************************/
  
! RemoveFuncStmt:  DROP FUNCTION func_name func_args opt_drop_behavior
  				{
  					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
  					n->funcname = $3;
  					n->args = $4;
+ 					n->behavior = $5;
  					$$ = (Node *)n;
  				}
  		;
  
! RemoveAggrStmt:  DROP AGGREGATE func_name '(' aggr_argtype ')' opt_drop_behavior
  				{
  						RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
  						n->aggname = $3;
  						n->aggtype = $5;
+ 						n->behavior = $7;
  						$$ = (Node *)n;
  				}
  		;
***************
*** 2988,2998 ****
  		| '*'									{ $$ = NULL; }
  		;
  
! RemoveOperStmt:  DROP OPERATOR any_operator '(' oper_argtypes ')'
  				{
  					RemoveOperStmt *n = makeNode(RemoveOperStmt);
  					n->opname = $3;
  					n->args = $5;
  					$$ = (Node *)n;
  				}
  		;
--- 2998,3009 ----
  		| '*'									{ $$ = NULL; }
  		;
  
! RemoveOperStmt:  DROP OPERATOR any_operator '(' oper_argtypes ')' opt_drop_behavior
  				{
  					RemoveOperStmt *n = makeNode(RemoveOperStmt);
  					n->opname = $3;
  					n->args = $5;
+ 					n->behavior = $7;
  					$$ = (Node *)n;
  				}
  		;
***************
*** 3160,3170 ****
  		;
  
  
! DropRuleStmt:  DROP RULE name ON qualified_name
  				{
  					DropPropertyStmt *n = makeNode(DropPropertyStmt);
  					n->relation = $5;
  					n->property = $3;
  					n->removeType = DROP_RULE;
  					$$ = (Node *) n;
  				}
--- 3171,3182 ----
  		;
  
  
! DropRuleStmt:  DROP RULE name ON qualified_name opt_drop_behavior
  				{
  					DropPropertyStmt *n = makeNode(DropPropertyStmt);
  					n->relation = $5;
  					n->property = $3;
+ 					n->behavior = $6;
  					n->removeType = DROP_RULE;
  					$$ = (Node *) n;
  				}
Index: src/backend/parser/parse_func.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_func.c,v
retrieving revision 1.131
diff -c -r1.131 parse_func.c
*** src/backend/parser/parse_func.c	2002/05/20 23:51:42	1.131
--- src/backend/parser/parse_func.c	2002/06/15 16:38:53
***************
*** 1248,1254 ****
  
  	if (caller == NULL)
  	{
! 		elog(ERROR, "Function %s(%s) does not exist%s%s",
  			 NameListToString(funcname), argbuf.data,
  			 ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));
  	}
--- 1248,1254 ----
  
  	if (caller == NULL)
  	{
! 		elog(ERROR, "Function '%s(%s)' does not exist%s%s",
  			 NameListToString(funcname), argbuf.data,
  			 ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));
  	}
Index: src/backend/rewrite/rewriteDefine.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v
retrieving revision 1.72
diff -c -r1.72 rewriteDefine.c
*** src/backend/rewrite/rewriteDefine.c	2002/05/21 22:05:55	1.72
--- src/backend/rewrite/rewriteDefine.c	2002/06/15 16:38:53
***************
*** 17,22 ****
--- 17,24 ----
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_rewrite.h"
  #include "commands/view.h"
  #include "miscadmin.h"
***************
*** 49,62 ****
  		   char *evqual,
  		   char *actiontree)
  {
! 	int			i;
! 	Datum		values[Natts_pg_rewrite];
! 	char		nulls[Natts_pg_rewrite];
! 	NameData	rname;
! 	Relation	pg_rewrite_desc;
! 	TupleDesc	tupDesc;
! 	HeapTuple	tup;
! 	Oid			rewriteObjectId;
  
  	if (IsDefinedRewriteRule(eventrel_oid, rulname))
  		elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists",
--- 51,66 ----
  		   char *evqual,
  		   char *actiontree)
  {
! 	int				i;
! 	Datum			values[Natts_pg_rewrite];
! 	char			nulls[Natts_pg_rewrite];
! 	NameData		rname;
! 	Relation		pg_rewrite_desc;
! 	TupleDesc		tupDesc;
! 	HeapTuple		tup;
! 	Oid				rewriteObjectId;
! 	ObjectAddress	myself,
! 					dependee;
  
  	if (IsDefinedRewriteRule(eventrel_oid, rulname))
  		elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists",
***************
*** 100,105 ****
--- 104,125 ----
  						   tup);
  		CatalogCloseIndices(Num_pg_rewrite_indices, idescs);
  	}
+ 
+ 	/*
+ 	 * Create Dependencies
+ 	 *	- Class of relation
+ 	 */
+ 	myself.classId = GetSysCacheOid(RELNAMENSP,
+ 									CStringGetDatum(RewriteRelationName),
+ 									ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 									0, 0);
+ 	myself.objectId = tup->t_data->t_oid;
+ 	myself.objectSubId = 0;
+ 	
+ 	dependee.classId = RelOid_pg_class;
+ 	dependee.objectId = eventrel_oid;
+ 	dependee.objectSubId = 0;
+ 	dependCreate(&myself, &dependee, true);
  
  	heap_freetuple(tup);
  
Index: src/backend/rewrite/rewriteRemove.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v
retrieving revision 1.49
diff -c -r1.49 rewriteRemove.c
*** src/backend/rewrite/rewriteRemove.c	2002/04/27 03:45:03	1.49
--- src/backend/rewrite/rewriteRemove.c	2002/06/15 16:38:53
***************
*** 17,32 ****
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "catalog/catname.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_rewrite.h"
- #include "commands/comment.h"
  #include "miscadmin.h"
  #include "rewrite/rewriteRemove.h"
  #include "rewrite/rewriteSupport.h"
  #include "utils/acl.h"
  #include "utils/fmgroids.h"
  #include "utils/syscache.h"
  
  
  /*
   * RemoveRewriteRule
--- 17,34 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "catalog/catname.h"
+ #include "catalog/pg_depend.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_rewrite.h"
  #include "miscadmin.h"
  #include "rewrite/rewriteRemove.h"
  #include "rewrite/rewriteSupport.h"
+ #include "utils/builtins.h"
  #include "utils/acl.h"
  #include "utils/fmgroids.h"
  #include "utils/syscache.h"
  
+ void RemoveRewriteRuleByTuple(Relation rewriteRelation, HeapTuple tuple, bool force, int behavior);
  
  /*
   * RemoveRewriteRule
***************
*** 34,48 ****
   * Delete a rule given its name.
   */
  void
! RemoveRewriteRule(Oid owningRel, const char *ruleName)
  {
  	Relation	RewriteRelation;
- 	Relation	event_relation;
  	HeapTuple	tuple;
- 	Oid			ruleId;
- 	Oid			eventRelationOid;
- 	bool		hasMoreRules;
- 	AclResult	aclresult;
  
  	/*
  	 * Open the pg_rewrite relation.
--- 36,45 ----
   * Delete a rule given its name.
   */
  void
! RemoveRewriteRule(Oid owningRel, const char *ruleName, int behavior)
  {
  	Relation	RewriteRelation;
  	HeapTuple	tuple;
  
  	/*
  	 * Open the pg_rewrite relation.
***************
*** 67,75 ****
  	 * Save the OID of the rule (i.e. the tuple's OID) and the event
  	 * relation's OID
  	 */
  	ruleId = tuple->t_data->t_oid;
  	eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
- 	Assert(eventRelationOid == owningRel);
  
  	/*
  	 * We had better grab AccessExclusiveLock so that we know no other
--- 64,133 ----
  	 * Save the OID of the rule (i.e. the tuple's OID) and the event
  	 * relation's OID
  	 */
+ 	Assert(((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class == owningRel);
+ 
+ 	RemoveRewriteRuleByTuple(RewriteRelation, tuple, false, behavior);
+ 
+ 	heap_freetuple(tuple);
+ 
+ 	heap_close(RewriteRelation, RowExclusiveLock);
+ }
+ 
+ void
+ RemoveRewriteRuleById(Oid ruleId, int behavior)
+ {
+ 	Relation	RewriteRelation;
+ 	SysScanDesc scanDesc;
+ 	ScanKeyData scanKeyData;
+ 	HeapTuple	tuple;
+ 	
+ 	/*
+ 	 * Open the pg_rewrite relation.
+ 	 */
+ 	RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
+ 
+ 	/*
+ 	 * Find the tuple for the target rule.
+ 	 */
+ 	ScanKeyEntryInitialize(&scanKeyData,
+ 						   0,
+ 						   ObjectIdAttributeNumber,
+ 						   F_OIDEQ,
+ 						   ObjectIdGetDatum(ruleId));
+ 
+ 	scanDesc = systable_beginscan(RewriteRelation, 0, false,
+ 								  SnapshotNow, 1, &scanKeyData);
+ 
+ 	/* Exactly 1 tuple should be found */
+ 	tuple = systable_getnext(scanDesc);
+ 	if (!HeapTupleIsValid(tuple))
+ 		elog(ERROR, "RemoveRewriteRuleById: Could not find RuleId %d", ruleId);
+ 
+ 	RemoveRewriteRuleByTuple(RewriteRelation, tuple, true, behavior);
+ 
+ 	systable_endscan(scanDesc);
+ 
+ 	heap_close(RewriteRelation, RowExclusiveLock);
+ }
+ 
+ /*
+  * RemoveRewriteRuleByTuple
+  *
+  * If force is true then the fact that the rule is owned by a view is ignored
+  * by the system.  It will remove it anyway.
+  */
+ void
+ RemoveRewriteRuleByTuple(Relation rewriteRelation, HeapTuple tuple, bool force, int behavior)
+ {
+ 
+ 	Relation	event_relation;
+ 	bool		hasMoreRules;
+ 	Oid			ruleId;
+ 	Oid			eventRelationOid;
+ 	AclResult	aclresult;
+ 
  	ruleId = tuple->t_data->t_oid;
  	eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
  
  	/*
  	 * We had better grab AccessExclusiveLock so that we know no other
***************
*** 87,113 ****
  		aclcheck_error(aclresult, RelationGetRelationName(event_relation));
  
  	/* do not allow the removal of a view's SELECT rule */
! 	if (event_relation->rd_rel->relkind == RELKIND_VIEW &&
  		((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1')
! 		elog(ERROR, "Cannot remove a view's SELECT rule");
  
  	hasMoreRules = event_relation->rd_rules != NULL &&
  		event_relation->rd_rules->numLocks > 1;
  
! 	/*
! 	 * Delete any comments associated with this rule
! 	 */
! 	DeleteComments(ruleId, RelationGetRelid(RewriteRelation));
  
  	/*
  	 * Now delete the pg_rewrite tuple for the rule
  	 */
! 	simple_heap_delete(RewriteRelation, &tuple->t_self);
  
- 	heap_freetuple(tuple);
- 
- 	heap_close(RewriteRelation, RowExclusiveLock);
- 
  	/*
  	 * Set pg_class 'relhasrules' field correctly for event relation.
  	 *
--- 145,165 ----
  		aclcheck_error(aclresult, RelationGetRelationName(event_relation));
  
  	/* do not allow the removal of a view's SELECT rule */
! 	if (force == false && event_relation->rd_rel->relkind == RELKIND_VIEW &&
  		((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1')
! 		elog(ERROR, "RemoveRewriteRuleByTuple: Cannot remove a view's SELECT rule");
  
  	hasMoreRules = event_relation->rd_rules != NULL &&
  		event_relation->rd_rules->numLocks > 1;
  
! 	/* Deal with dependencies */
! 	dependDeleteTuple(tuple, rewriteRelation, behavior);
  
  	/*
  	 * Now delete the pg_rewrite tuple for the rule
  	 */
! 	simple_heap_delete(rewriteRelation, &tuple->t_self);
  
  	/*
  	 * Set pg_class 'relhasrules' field correctly for event relation.
  	 *
***************
*** 119,168 ****
  
  	/* Close rel, but keep lock till commit... */
  	heap_close(event_relation, NoLock);
- }
- 
- /*
-  * RelationRemoveRules -
-  *	  removes all rules associated with the relation when the relation is
-  *	  being removed.
-  */
- void
- RelationRemoveRules(Oid relid)
- {
- 	Relation	RewriteRelation;
- 	SysScanDesc scanDesc;
- 	ScanKeyData scanKeyData;
- 	HeapTuple	tuple;
- 
- 	/*
- 	 * Open the pg_rewrite relation.
- 	 */
- 	RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
- 
- 	/*
- 	 * Scan pg_rewrite for all the tuples that have the same ev_class
- 	 * as relid (the relation to be removed).
- 	 */
- 	ScanKeyEntryInitialize(&scanKeyData,
- 						   0,
- 						   Anum_pg_rewrite_ev_class,
- 						   F_OIDEQ,
- 						   ObjectIdGetDatum(relid));
- 
- 	scanDesc = systable_beginscan(RewriteRelation,
- 								  RewriteRelRulenameIndex,
- 								  true, SnapshotNow,
- 								  1, &scanKeyData);
- 
- 	while (HeapTupleIsValid(tuple = systable_getnext(scanDesc)))
- 	{
- 		/* Delete any comments associated with this rule */
- 		DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation));
- 
- 		simple_heap_delete(RewriteRelation, &tuple->t_self);
- 	}
- 
- 	systable_endscan(scanDesc);
- 
- 	heap_close(RewriteRelation, RowExclusiveLock);
  }
--- 171,174 ----
Index: src/backend/tcop/utility.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/tcop/utility.c,v
retrieving revision 1.156
diff -c -r1.156 utility.c
*** src/backend/tcop/utility.c	2002/05/21 22:18:08	1.156
--- src/backend/tcop/utility.c	2002/06/15 16:38:58
***************
*** 289,318 ****
  						case DROP_TABLE:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_RELATION);
! 							RemoveRelation(rel);
  							break;
  
  						case DROP_SEQUENCE:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_SEQUENCE);
! 							RemoveRelation(rel);
  							break;
  
  						case DROP_VIEW:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_VIEW);
! 							RemoveView(rel);
  							break;
  
  						case DROP_INDEX:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_INDEX);
! 							RemoveIndex(rel);
  							break;
  
  						case DROP_TYPE:
  							/* RemoveType does its own permissions checks */
! 							RemoveType(names);
  							break;
  
  						case DROP_DOMAIN:
--- 289,318 ----
  						case DROP_TABLE:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_RELATION);
! 							RemoveRelation(rel, stmt->behavior);
  							break;
  
  						case DROP_SEQUENCE:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_SEQUENCE);
! 							RemoveRelation(rel, stmt->behavior);
  							break;
  
  						case DROP_VIEW:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_VIEW);
! 							RemoveView(rel, stmt->behavior);
  							break;
  
  						case DROP_INDEX:
  							rel = makeRangeVarFromNameList(names);
  							CheckDropPermissions(rel, RELKIND_INDEX);
! 							RemoveIndex(rel, stmt->behavior);
  							break;
  
  						case DROP_TYPE:
  							/* RemoveType does its own permissions checks */
! 							RemoveType(names, stmt->behavior);
  							break;
  
  						case DROP_DOMAIN:
***************
*** 605,611 ****
  			{
  				RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
  
! 				RemoveAggregate(stmt->aggname, stmt->aggtype);
  			}
  			break;
  
--- 605,611 ----
  			{
  				RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
  
! 				RemoveAggregate(stmt->aggname, stmt->aggtype, stmt->behavior);
  			}
  			break;
  
***************
*** 613,619 ****
  			{
  				RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
  
! 				RemoveFunction(stmt->funcname, stmt->args);
  			}
  			break;
  
--- 613,619 ----
  			{
  				RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
  
! 				RemoveFunction(stmt->funcname, stmt->args, stmt->behavior);
  			}
  			break;
  
***************
*** 623,629 ****
  				TypeName   *typenode1 = (TypeName *) lfirst(stmt->args);
  				TypeName   *typenode2 = (TypeName *) lsecond(stmt->args);
  
! 				RemoveOperator(stmt->opname, typenode1, typenode2);
  			}
  			break;
  
--- 623,629 ----
  				TypeName   *typenode1 = (TypeName *) lfirst(stmt->args);
  				TypeName   *typenode2 = (TypeName *) lsecond(stmt->args);
  
! 				RemoveOperator(stmt->opname, typenode1, typenode2, stmt->behavior);
  			}
  			break;
  
***************
*** 751,761 ****
  				{
  					case DROP_RULE:
  						/* RemoveRewriteRule checks permissions */
! 						RemoveRewriteRule(relId, stmt->property);
  						break;
  					case DROP_TRIGGER:
  						/* DropTrigger checks permissions */
! 						DropTrigger(relId, stmt->property);
  						break;
  				}
  			}
--- 751,761 ----
  				{
  					case DROP_RULE:
  						/* RemoveRewriteRule checks permissions */
! 						RemoveRewriteRule(relId, stmt->property, stmt->behavior);
  						break;
  					case DROP_TRIGGER:
  						/* DropTrigger checks permissions */
! 						DropTrigger(relId, stmt->property, stmt->behavior);
  						break;
  				}
  			}
Index: src/backend/utils/adt/ruleutils.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v
retrieving revision 1.108
diff -c -r1.108 ruleutils.c
*** src/backend/utils/adt/ruleutils.c	2002/06/13 03:40:49	1.108
--- src/backend/utils/adt/ruleutils.c	2002/06/15 16:39:01
***************
*** 40,48 ****
--- 40,53 ----
  #include <unistd.h>
  #include <fcntl.h>
  
+ #include "access/heapam.h"
+ #include "access/genam.h"
+ #include "catalog/catname.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
+ #include "catalog/indexing.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_constraint.h"
  #include "catalog/pg_index.h"
  #include "catalog/pg_opclass.h"
  #include "catalog/pg_operator.h"
***************
*** 59,64 ****
--- 64,71 ----
  #include "parser/parsetree.h"
  #include "rewrite/rewriteManip.h"
  #include "rewrite/rewriteSupport.h"
+ #include "utils/array.h"
+ #include "utils/fmgroids.h"
  #include "utils/lsyscache.h"
  
  
***************
*** 520,525 ****
--- 527,730 ----
  	PG_RETURN_TEXT_P(indexdef);
  }
  
+ /*
+  * pg_get_fkeydef
+  *
+  * Returns the definitition statement required to recreate the foreign
+  * key structure
+  */
+ Datum
+ pg_get_fkeydef(PG_FUNCTION_ARGS)
+ {
+ 	Oid				relId = PG_GETARG_OID(0);
+ 	Name			cname = PG_GETARG_NAME(1);
+ 	text		   *result;
+ 	StringInfoData	buf;
+ 	Relation		conDesc;
+ 	HeapTuple		tup;
+ 	Datum			val;
+ 	char		   *string = NULL;
+ 	SysScanDesc		rcscan;
+ 	ScanKeyData		skey[2];
+ 	int				i = 0;
+ 	int				len;
+ 	bool			isnull;
+ 	Form_pg_constraint	fkCon;
+ 
+ 	conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
+ 
+ 	ScanKeyEntryInitialize(&skey[i++],
+ 						   0, Anum_pg_constraint_conrelid, F_OIDEQ,
+ 						   ObjectIdGetDatum(relId));
+ 
+ 	ScanKeyEntryInitialize(&skey[i++],
+ 						   0, Anum_pg_constraint_conname, F_NAMEEQ,
+ 						   NameGetDatum(cname));
+ 
+ 	rcscan = systable_beginscan(conDesc, ConstraintRelidNameIndex, true,
+ 								SnapshotNow,
+ 								i, skey);
+ 	tup = systable_getnext(rcscan);
+ 	if (!HeapTupleIsValid(tup))
+ 		elog(ERROR, "syscache lookup for foreign key %s failed on relation %u", NameStr(*cname), relId);
+ 
+ 	fkCon = (Form_pg_constraint) GETSTRUCT(tup);
+ 
+ 
+ 	/* We only deal in foreign key constraints */
+ 	if (fkCon->contype != CONSTRAINT_FOREIGN)
+ 		elog(ERROR, "pg_get_fkeydef: %s is not a foreign key constraint", NameStr(*cname));
+ 
+ 	/* Start off the statement */
+ 	initStringInfo(&buf);
+ 	appendStringInfo(&buf, "ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (",
+ 					 generate_relation_name(fkCon->conrelid),
+ 					 quote_identifier(NameStr(fkCon->conname)));
+ 
+ 	/* Fetch and build column list */
+ 	val = heap_getattr(tup, Anum_pg_constraint_conkey,
+ 					   RelationGetDescr(conDesc), &isnull);
+ 
+ 	if (isnull)
+ 		elog(ERROR, "get_pg_fkeydef: Null conkey array for constraint %s",
+ 			 		NameStr(*cname));
+ 	else
+ 	{
+ 		Datum	   *keys;
+ 		int			j;
+ 		int			nKeys;
+ 		deconstruct_array(DatumGetArrayTypeP(val),
+ 						  true, 2, 's',
+ 						  &keys, &nKeys);
+ 
+ 		for (j = 0; j < nKeys; j++)
+ 		{
+ 			char	   *colName;
+ 
+ 			colName	= get_attname(fkCon->conrelid,
+ 								  DatumGetInt16(keys[j]));
+ 
+ 			if (j == 0)
+ 				appendStringInfo(&buf, "%s",
+ 								 quote_identifier(colName));
+ 			else
+ 				appendStringInfo(&buf, ", %s",
+ 								 quote_identifier(colName));
+ 		}
+ 	}
+ 
+ 	appendStringInfo(&buf, ")");
+ 
+ 	/* Add Foreign relation and key attributes */
+ 	appendStringInfo(&buf, " REFERENCES %s(",
+ 					 generate_relation_name(fkCon->confrelid));
+ 
+ 	/* Fetch and build column list */
+ 	val = heap_getattr(tup, Anum_pg_constraint_confkey,
+ 					   RelationGetDescr(conDesc), &isnull);
+ 
+ 	if (isnull)
+ 		elog(ERROR, "get_pg_fkeydef: Null confkey array for constraint %s",
+ 			 		NameStr(*cname));
+ 	else
+ 	{
+ 		Datum	   *keys;
+ 		int			j;
+ 		int			nKeys;
+ 		deconstruct_array(DatumGetArrayTypeP(val),
+ 						  true, 2, 's',
+ 						  &keys, &nKeys);
+ 
+ 		for (j = 0; j < nKeys; j++)
+ 		{
+ 			char	   *colName;
+ 
+ 			colName	= get_attname(fkCon->confrelid,
+ 								  DatumGetInt16(keys[j]));
+ 
+ 			if (j == 0)
+ 				appendStringInfo(&buf, "%s",
+ 								 quote_identifier(colName));
+ 			else
+ 				appendStringInfo(&buf, ", %s",
+ 								 quote_identifier(colName));
+ 		}
+ 	}
+ 
+ 
+ 
+ 	appendStringInfo(&buf, ")");
+ 
+ 	/* Add match type */
+ 	switch (fkCon->confmatchtype)
+ 	{
+ 		case 'p':
+ 			string = " MATCH PARTIAL";
+ 			break;
+ 		case 'f':
+ 			string = " MATCH FULL";
+ 			break;
+ 		default:
+ 			string = "";
+ 			break;
+ 	}
+ 	appendStringInfo(&buf, "%s", string);
+ 
+ 	/* Add ON UPDATE and ON DELETE clause */
+ 	switch (fkCon->confupdtype)
+ 	{
+ 		case 'r':
+ 			string = "RESTRICT";
+ 			break;
+ 		case 'c':
+ 			string = "CASCADE";
+ 			break;
+ 		case 'n':
+ 			string = "SET NULL";
+ 			break;
+ 		case 'd':
+ 			string = "SET DEFAULT";
+ 			break;
+ 		case 'a':
+ 			string = "NO ACTION";
+ 			break;
+ 	}
+ 	appendStringInfo(&buf, " ON UPDATE %s",
+ 					 string);
+ 
+ 	switch (fkCon->confdeltype)
+ 	{
+ 		case 'r':
+ 			string = "RESTRICT";
+ 			break;
+ 		case 'c':
+ 			string = "CASCADE";
+ 			break;
+ 		case 'n':
+ 			string = "SET NULL";
+ 			break;
+ 		case 'd':
+ 			string = "SET DEFAULT";
+ 			break;
+ 		case 'a':
+ 			string = "NO ACTION";
+ 			break;
+ 	}
+ 	appendStringInfo(&buf, " ON DELETE %s",
+ 					 string);
+ 
+ 	/* Cleanup */
+ 	systable_endscan(rcscan);
+ 	heap_close(conDesc, RowExclusiveLock);
+ 
+ 	/* Record the results */
+ 	len = buf.len + VARHDRSZ;
+ 	result = (text *) palloc(len);
+ 	VARATT_SIZEP(result) = len;
+ 	memcpy(VARDATA(result), buf.data, buf.len);
+ 
+ 	PG_RETURN_TEXT_P(result);
+ }
  
  /* ----------
   * get_expr			- Decompile an expression tree
Index: src/backend/utils/cache/relcache.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/relcache.c,v
retrieving revision 1.164
diff -c -r1.164 relcache.c
*** src/backend/utils/cache/relcache.c	2002/05/22 15:57:40	1.164
--- src/backend/utils/cache/relcache.c	2002/06/15 16:39:09
***************
*** 43,53 ****
  #include "catalog/pg_amproc.h"
  #include "catalog/pg_attrdef.h"
  #include "catalog/pg_attribute.h"
  #include "catalog/pg_index.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_opclass.h"
  #include "catalog/pg_proc.h"
- #include "catalog/pg_relcheck.h"
  #include "catalog/pg_rewrite.h"
  #include "catalog/pg_type.h"
  #include "commands/trigger.h"
--- 43,53 ----
  #include "catalog/pg_amproc.h"
  #include "catalog/pg_attrdef.h"
  #include "catalog/pg_attribute.h"
+ #include "catalog/pg_constraint.h"
  #include "catalog/pg_index.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_opclass.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_rewrite.h"
  #include "catalog/pg_type.h"
  #include "commands/trigger.h"
***************
*** 296,302 ****
  static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
  				  Relation oldrelation);
  static void AttrDefaultFetch(Relation relation);
! static void RelCheckFetch(Relation relation);
  static List *insert_ordered_oid(List *list, Oid datum);
  static void IndexSupportInitialize(Form_pg_index iform,
  								   IndexStrategy indexStrategy,
--- 296,302 ----
  static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
  				  Relation oldrelation);
  static void AttrDefaultFetch(Relation relation);
! static void CheckConstraintFetch(Relation relation);
  static List *insert_ordered_oid(List *list, Oid datum);
  static void IndexSupportInitialize(Form_pg_index iform,
  								   IndexStrategy indexStrategy,
***************
*** 451,457 ****
   *		RelationBuildTupleDesc
   *
   *		Form the relation's tuple descriptor from information in
!  *		the pg_attribute, pg_attrdef & pg_relcheck system catalogs.
   */
  static void
  RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
--- 451,457 ----
   *		RelationBuildTupleDesc
   *
   *		Form the relation's tuple descriptor from information in
!  *		the pg_attribute, pg_attrdef & pg_constraint system catalogs.
   */
  static void
  RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
***************
*** 603,609 ****
  				MemoryContextAlloc(CacheMemoryContext,
  								constr->num_check * sizeof(ConstrCheck));
  			MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
! 			RelCheckFetch(relation);
  		}
  		else
  			constr->num_check = 0;
--- 603,609 ----
  				MemoryContextAlloc(CacheMemoryContext,
  								constr->num_check * sizeof(ConstrCheck));
  			MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
! 			CheckConstraintFetch(relation);
  		}
  		else
  			constr->num_check = 0;
***************
*** 2483,2533 ****
  }
  
  static void
! RelCheckFetch(Relation relation)
  {
  	ConstrCheck *check = relation->rd_att->constr->check;
  	int			ncheck = relation->rd_att->constr->num_check;
  	Relation	rcrel;
  	SysScanDesc rcscan;
! 	ScanKeyData skey;
  	HeapTuple	htup;
- 	Name		rcname;
  	Datum		val;
  	bool		isnull;
  	int			found;
  
! 	ScanKeyEntryInitialize(&skey,
! 						   (bits16) 0x0,
! 						   (AttrNumber) Anum_pg_relcheck_rcrelid,
! 						   (RegProcedure) F_OIDEQ,
  						   ObjectIdGetDatum(RelationGetRelid(relation)));
  
! 	rcrel = heap_openr(RelCheckRelationName, AccessShareLock);
! 	rcscan = systable_beginscan(rcrel, RelCheckIndex, true,
! 								SnapshotNow,
! 								1, &skey);
! 	found = 0;
  
  	while (HeapTupleIsValid(htup = systable_getnext(rcscan)))
  	{
  		if (found == ncheck)
! 			elog(ERROR, "RelCheckFetch: unexpected record found for rel %s",
  				 RelationGetRelationName(relation));
  
- 		rcname = (Name) fastgetattr(htup,
- 									Anum_pg_relcheck_rcname,
- 									rcrel->rd_att, &isnull);
- 		if (isnull)
- 			elog(ERROR, "RelCheckFetch: rcname IS NULL for rel %s",
- 				 RelationGetRelationName(relation));
  		check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
! 												  NameStr(*rcname));
  		val = fastgetattr(htup,
! 						  Anum_pg_relcheck_rcbin,
  						  rcrel->rd_att, &isnull);
  		if (isnull)
! 			elog(ERROR, "RelCheckFetch: rcbin IS NULL for rel %s",
  				 RelationGetRelationName(relation));
  		check[found].ccbin = MemoryContextStrdup(CacheMemoryContext,
  							 DatumGetCString(DirectFunctionCall1(textout,
  																 val)));
--- 2483,2531 ----
  }
  
  static void
! CheckConstraintFetch(Relation relation)
  {
  	ConstrCheck *check = relation->rd_att->constr->check;
  	int			ncheck = relation->rd_att->constr->num_check;
  	Relation	rcrel;
  	SysScanDesc rcscan;
! 	ScanKeyData skey[2];
! 	int			skeyCount = 0;
  	HeapTuple	htup;
  	Datum		val;
  	bool		isnull;
  	int			found;
  
! 	ScanKeyEntryInitialize(&skey[skeyCount++],
! 						   0, Anum_pg_constraint_conrelid, F_OIDEQ,
  						   ObjectIdGetDatum(RelationGetRelid(relation)));
  
! 	rcrel = heap_openr(ConstraintRelationName, AccessShareLock);
! 	rcscan = systable_beginscan(rcrel, ConstraintRelidNameIndex, true,
! 								SnapshotNow, skeyCount, skey);
  
+ 	found = 0;
  	while (HeapTupleIsValid(htup = systable_getnext(rcscan)))
  	{
+ 		/* Check constraints only */
+ 		if (CONSTRAINT_CHECK != ((Form_pg_constraint) GETSTRUCT(htup))->contype)
+ 			continue;
+ 
  		if (found == ncheck)
! 			elog(ERROR, "CheckConstraintFetch: unexpected record found for rel %s",
  				 RelationGetRelationName(relation));
  
  		check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
! 								NameStr(((Form_pg_constraint) GETSTRUCT(htup))->conname));
! 
! 		/* Grab and test conbin is actually set */
  		val = fastgetattr(htup,
! 						  Anum_pg_constraint_conbin,
  						  rcrel->rd_att, &isnull);
  		if (isnull)
! 			elog(ERROR, "CheckConstraintFetch: conbin IS NULL for rel %s",
  				 RelationGetRelationName(relation));
+ 
  		check[found].ccbin = MemoryContextStrdup(CacheMemoryContext,
  							 DatumGetCString(DirectFunctionCall1(textout,
  																 val)));
***************
*** 2538,2544 ****
  	heap_close(rcrel, AccessShareLock);
  
  	if (found != ncheck)
! 		elog(ERROR, "RelCheckFetch: %d record(s) not found for rel %s",
  			 ncheck - found, RelationGetRelationName(relation));
  }
  
--- 2536,2542 ----
  	heap_close(rcrel, AccessShareLock);
  
  	if (found != ncheck)
! 		elog(ERROR, "CheckConstraintFetch: %d record(s) not found for rel %s",
  			 ncheck - found, RelationGetRelationName(relation));
  }
  
Index: src/bin/initdb/initdb.sh
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/initdb/initdb.sh,v
retrieving revision 1.155
diff -c -r1.155 initdb.sh
*** src/bin/initdb/initdb.sh	2002/05/21 19:06:00	1.155
--- src/bin/initdb/initdb.sh	2002/06/15 16:39:10
***************
*** 682,692 ****
  
  "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
  ALTER TABLE pg_attrdef CREATE TOAST TABLE;
  ALTER TABLE pg_database CREATE TOAST TABLE;
  ALTER TABLE pg_description CREATE TOAST TABLE;
  ALTER TABLE pg_group CREATE TOAST TABLE;
  ALTER TABLE pg_proc CREATE TOAST TABLE;
- ALTER TABLE pg_relcheck CREATE TOAST TABLE;
  ALTER TABLE pg_rewrite CREATE TOAST TABLE;
  ALTER TABLE pg_shadow CREATE TOAST TABLE;
  ALTER TABLE pg_statistic CREATE TOAST TABLE;
--- 682,692 ----
  
  "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
  ALTER TABLE pg_attrdef CREATE TOAST TABLE;
+ ALTER TABLE pg_constraint CREATE TOAST TABLE;
  ALTER TABLE pg_database CREATE TOAST TABLE;
  ALTER TABLE pg_description CREATE TOAST TABLE;
  ALTER TABLE pg_group CREATE TOAST TABLE;
  ALTER TABLE pg_proc CREATE TOAST TABLE;
  ALTER TABLE pg_rewrite CREATE TOAST TABLE;
  ALTER TABLE pg_shadow CREATE TOAST TABLE;
  ALTER TABLE pg_statistic CREATE TOAST TABLE;
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.266
diff -c -r1.266 pg_dump.c
*** src/bin/pg_dump/pg_dump.c	2002/06/13 20:02:31	1.266
--- src/bin/pg_dump/pg_dump.c	2002/06/15 16:39:20
***************
*** 108,113 ****
--- 108,114 ----
  					const char *acl, const char *objoid);
  
  static void dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables);
+ static void dumpConstraints(Archive *fout, TableInfo *tblinfo, int numTables);
  static void dumpRules(Archive *fout, TableInfo *tblinfo, int numTables);
  static void formatStringLiteral(PQExpBuffer buf, const char *str,
  								const formatLiteralOptions opts);
***************
*** 614,619 ****
--- 615,621 ----
  	{
  		dumpTriggers(g_fout, tblinfo, numTables);
  		dumpRules(g_fout, tblinfo, numTables);
+ 		dumpConstraints(g_fout, tblinfo, numTables);
  	}
  
  	/* Now sort the output nicely */
***************
*** 3326,3331 ****
--- 3328,3334 ----
  	}
  }
  
+ 
  /*
   * format_function_signature: generate function name and argument list
   *
***************
*** 4636,4643 ****
  		if (tbinfo->ncheck > 0)
  		{
  			PGresult   *res2;
! 			int			i_rcname,
! 						i_rcsrc;
  			int			ntups2;
  
  			if (g_verbose)
--- 4639,4646 ----
  		if (tbinfo->ncheck > 0)
  		{
  			PGresult   *res2;
! 			int			i_conname,
! 						i_consrc;
  			int			ntups2;
  
  			if (g_verbose)
***************
*** 4646,4669 ****
  
  			resetPQExpBuffer(query);
  			if (g_fout->remoteVersion >= 70300)
! 				appendPQExpBuffer(query, "SELECT rcname, rcsrc"
! 								  " from pg_catalog.pg_relcheck c1"
! 								  " where rcrelid = '%s'::pg_catalog.oid "
  								  "   and not exists "
  								  "  (select 1 from "
! 								  "    pg_catalog.pg_relcheck c2, "
  								  "    pg_catalog.pg_inherits i "
! 								  "    where i.inhrelid = c1.rcrelid "
! 								  "      and (c2.rcname = c1.rcname "
! 								  "          or (c2.rcname[0] = '$' "
! 								  "              and c1.rcname[0] = '$')"
! 								  "          )"
! 								  "      and c2.rcsrc = c1.rcsrc "
! 								  "      and c2.rcrelid = i.inhparent) "
! 								  " order by rcname ",
  								  tbinfo->oid);
  			else
! 				appendPQExpBuffer(query, "SELECT rcname, rcsrc"
  								  " from pg_relcheck c1"
  								  " where rcrelid = '%s'::oid "
  								  "   and not exists "
--- 4649,4669 ----
  
  			resetPQExpBuffer(query);
  			if (g_fout->remoteVersion >= 70300)
! 				appendPQExpBuffer(query, "SELECT conname, consrc"
! 								  " from pg_catalog.pg_constraint c1"
! 								  " where conrelid = '%s'::pg_catalog.oid "
! 								  "   and contype = 'c' "
  								  "   and not exists "
  								  "  (select 1 from "
! 								  "    pg_catalog.pg_constraint c2, "
  								  "    pg_catalog.pg_inherits i "
! 								  "    where i.inhrelid = c1.conrelid "
! 								  "      and c2.conname = c1.conname "
! 								  "      and c2.conrelid = i.inhparent) "
! 								  " order by conname ",
  								  tbinfo->oid);
  			else
! 				appendPQExpBuffer(query, "SELECT rcname as conname, rcsrc as consrc"
  								  " from pg_relcheck c1"
  								  " where rcrelid = '%s'::oid "
  								  "   and not exists "
***************
*** 4678,4683 ****
--- 4678,4684 ----
  								  "      and c2.rcrelid = i.inhparent) "
  								  " order by rcname ",
  								  tbinfo->oid);
+ 
  			res2 = PQexec(g_conn, query->data);
  			if (!res2 ||
  				PQresultStatus(res2) != PGRES_TUPLES_OK)
***************
*** 4694,4706 ****
  				exit_nicely();
  			}
  
! 			i_rcname = PQfnumber(res2, "rcname");
! 			i_rcsrc = PQfnumber(res2, "rcsrc");
  
  			for (j = 0; j < ntups2; j++)
  			{
! 				const char *name = PQgetvalue(res2, j, i_rcname);
! 				const char *expr = PQgetvalue(res2, j, i_rcsrc);
  
  				if (actual_atts + j > 0)
  					appendPQExpBuffer(q, ",\n\t");
--- 4695,4707 ----
  				exit_nicely();
  			}
  
! 			i_conname = PQfnumber(res2, "conname");
! 			i_consrc = PQfnumber(res2, "consrc");
  
  			for (j = 0; j < ntups2; j++)
  			{
! 				const char *name = PQgetvalue(res2, j, i_conname);
! 				const char *expr = PQgetvalue(res2, j, i_consrc);
  
  				if (actual_atts + j > 0)
  					appendPQExpBuffer(q, ",\n\t");
***************
*** 5226,5231 ****
--- 5227,5334 ----
  	destroyPQExpBuffer(delqry);
  }
  
+ /*
+  * dumpConstraints
+  *
+  * Dump out constraints after all table creation statements in
+  * an alter table format.  Currently handles foreign keys only.
+  *
+  * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that
+  * the current table data is not processed
+  */
+ static void
+ dumpConstraints(Archive *fout, TableInfo *tblinfo, int numTables)
+ {
+ 	int			i,
+ 				j;
+ 	PQExpBuffer query = createPQExpBuffer();
+ 	PQExpBuffer delqry = createPQExpBuffer();
+ 	PGresult   *res;
+ 	int			i_condef,
+ 				i_conoid,
+ 				i_conname;
+ 	int			ntups;
+ 
+ 	/* pg_constraint was created in 7.3 */
+ 	if (g_fout->remoteVersion >= 70300)
+ 	{
+ 
+ 		for (i = 0; i < numTables; i++)
+ 		{
+ 			TableInfo	   *tbinfo = &tblinfo[i];
+ 
+ 			if (tbinfo->ntrig == 0 || !tbinfo->dump)
+ 				continue;
+ 
+ 			if (g_verbose)
+ 				write_msg(NULL, "dumping triggers for table %s\n",
+ 						  tbinfo->relname);
+ 
+ 			/* select table schema to ensure regproc name is qualified if needed */
+ 			selectSourceSchema(tbinfo->relnamespace->nspname);
+ 
+ 			resetPQExpBuffer(query);
+ 			appendPQExpBuffer(query,
+ 							  "SELECT pg_get_fkeydef(conrelid, conname) as condef, "
+ 							  "oid, conname "
+ 							  "from pg_catalog.pg_constraint "
+ 							  "where conrelid = '%s'::pg_catalog.oid "
+ 							  "and contype = 'f'",
+ 							  tbinfo->oid);
+ 			res = PQexec(g_conn, query->data);
+ 			if (!res ||
+ 				PQresultStatus(res) != PGRES_TUPLES_OK)
+ 			{
+ 				write_msg(NULL, "query to obtain list of foreign key definitions failed: %s", PQerrorMessage(g_conn));
+ 				exit_nicely();
+ 			}
+ 			ntups = PQntuples(res);
+ 
+ 			i_condef = PQfnumber(res, "condef");
+ 			i_conoid = PQfnumber(res, "oid");
+ 			i_conname = PQfnumber(res, "conname");
+ 	
+ 			for (j = 0; j < ntups; j++)
+ 			{
+ 				const char *conName = PQgetvalue(res, j, i_conname);
+ 				const char *conOid = PQgetvalue(res, j, i_conoid);
+ 				const char *conDef = PQgetvalue(res, j, i_condef);
+ 
+ 				resetPQExpBuffer(query);
+ 				/*
+ 				 * Creation query is built by pg_get_fkeydef.
+ 				 * We don't need to DROP Foreign keys as the
+ 				 * table drop will take care of that.
+ 				 */
+ 				appendPQExpBuffer(query, "%s;",
+ 								  conDef);
+ 
+ 				ArchiveEntry(fout, conOid,
+ 							 conName,
+ 							 tbinfo->relnamespace->nspname,
+ 							 tbinfo->usename,
+ 							 "CONSTRAINT", NULL,
+ 							 query->data, delqry->data,
+ 							 NULL, NULL, NULL);
+ 
+ 				resetPQExpBuffer(query);
+ 				appendPQExpBuffer(query, "CONSTRAINT %s ",
+ 								  fmtId(conName, force_quotes));
+ 				appendPQExpBuffer(query, "ON %s",
+ 								  fmtId(tbinfo->relname, force_quotes));
+ 
+ 				dumpComment(fout, query->data,
+ 							tbinfo->relnamespace->nspname, tbinfo->usename,
+ 							conOid, "pg_constraint", 0, NULL);
+ 			}
+ 
+ 			PQclear(res);
+ 		}
+ 	}
+ 	destroyPQExpBuffer(query);
+ 	destroyPQExpBuffer(delqry);
+ }
+ 
  
  static void
  dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables)
***************
*** 5274,5280 ****
  							  "tgconstrrelid, tginitdeferred, oid, "
  							  "tgconstrrelid::pg_catalog.regclass as tgconstrrelname "
  							  "from pg_catalog.pg_trigger "
! 							  "where tgrelid = '%s'::pg_catalog.oid",
  							  tbinfo->oid);
  		}
  		else
--- 5377,5384 ----
  							  "tgconstrrelid, tginitdeferred, oid, "
  							  "tgconstrrelid::pg_catalog.regclass as tgconstrrelname "
  							  "from pg_catalog.pg_trigger "
! 							  "where tgrelid = '%s'::pg_catalog.oid "
! 							  "and tgisconstraint is false",
  							  tbinfo->oid);
  		}
  		else
***************
*** 5297,5309 ****
  			write_msg(NULL, "query to obtain list of triggers failed: %s", PQerrorMessage(g_conn));
  			exit_nicely();
  		}
  		ntups = PQntuples(res);
! 		if (ntups != tbinfo->ntrig)
  		{
  			write_msg(NULL, "expected %d triggers on table \"%s\" but found %d\n",
  					  tbinfo->ntrig, tbinfo->relname, ntups);
  			exit_nicely();
  		}
  		i_tgname = PQfnumber(res, "tgname");
  		i_tgfname = PQfnumber(res, "tgfname");
  		i_tgtype = PQfnumber(res, "tgtype");
--- 5401,5419 ----
  			write_msg(NULL, "query to obtain list of triggers failed: %s", PQerrorMessage(g_conn));
  			exit_nicely();
  		}
+ 
  		ntups = PQntuples(res);
! 		/*
! 		 * We may have less triggers than recorded due to constraint triggers
! 		 * which are dumped by dumpConstraints
! 		 */
! 		if (ntups > tbinfo->ntrig)
  		{
  			write_msg(NULL, "expected %d triggers on table \"%s\" but found %d\n",
  					  tbinfo->ntrig, tbinfo->relname, ntups);
  			exit_nicely();
  		}
+ 
  		i_tgname = PQfnumber(res, "tgname");
  		i_tgfname = PQfnumber(res, "tgfname");
  		i_tgtype = PQfnumber(res, "tgtype");
Index: src/bin/psql/command.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/command.c,v
retrieving revision 1.72
diff -c -r1.72 command.c
*** src/bin/psql/command.c	2002/04/24 05:24:00	1.72
--- src/bin/psql/command.c	2002/06/15 16:39:23
***************
*** 355,360 ****
--- 355,363 ----
  			case 'a':
  				success = describeAggregates(name);
  				break;
+ 			case 'c':
+ 				//success = describeConstraint(name);
+ 				break;
  			case 'd':
  				success = objectDescription(name);
  				break;
Index: src/bin/psql/describe.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/describe.c,v
retrieving revision 1.54
diff -c -r1.54 describe.c
*** src/bin/psql/describe.c	2002/05/13 17:45:30	1.54
--- src/bin/psql/describe.c	2002/06/15 16:39:27
***************
*** 396,402 ****
  
  			 ") AS tt,\n"
  			 "pg_description d\n"
! 			 "WHERE tt.oid = d.objoid and tt.tableoid = d.classoid and d.objsubid = 0\n",
  
  			 _("Name"), _("Object"), _("Description"),
  			 _("aggregate"), _("function"), _("operator"),
--- 396,403 ----
  
  			 ") AS tt,\n"
  			 "pg_description d\n"
! 			 "WHERE t.tgisconstraint IS FALSE\n"
! 			 "AND tt.oid = d.objoid and tt.tableoid = d.classoid and d.objsubid = 0\n",
  
  			 _("Name"), _("Object"), _("Description"),
  			 _("aggregate"), _("function"), _("operator"),
***************
*** 745,753 ****
  		PGresult   *result1 = NULL,
  				   *result2 = NULL,
  				   *result3 = NULL,
! 				   *result4 = NULL;
! 		int			index_count = 0,
! 					constr_count = 0,
  					rule_count = 0,
  					trigger_count = 0;
  		int			count_footers = 0;
--- 746,756 ----
  		PGresult   *result1 = NULL,
  				   *result2 = NULL,
  				   *result3 = NULL,
! 				   *result4 = NULL,
! 				   *result5 = NULL;
! 		int			constr_count = 0,
! 					index_count = 0,
! 					foreignkey_count = 0,
  					rule_count = 0,
  					trigger_count = 0;
  		int			count_footers = 0;
***************
*** 774,782 ****
  		if (tableinfo.checks)
  		{
  			printfPQExpBuffer(&buf,
! 					"SELECT rcsrc, rcname\n"
! 					"FROM pg_relcheck r, pg_class c\n"
! 					"WHERE c.relname='%s' AND c.oid = r.rcrelid",
  					name);
  			result2 = PSQLexec(buf.data);
  			if (!result2)
--- 777,786 ----
  		if (tableinfo.checks)
  		{
  			printfPQExpBuffer(&buf,
! 					"SELECT consrc, conname\n"
! 					"FROM pg_constraint r, pg_class c\n"
! 					"WHERE c.relname='%s' AND c.oid = r.conrelid\n"
! 					"AND contype = 'c'",
  					name);
  			result2 = PSQLexec(buf.data);
  			if (!result2)
***************
*** 800,812 ****
  				rule_count = PQntuples(result3);
  		}
  
! 		/* count triggers */
  		if (tableinfo.triggers)
  		{
  			printfPQExpBuffer(&buf,
  					"SELECT t.tgname\n"
  					"FROM pg_trigger t, pg_class c\n"
! 					"WHERE c.relname='%s' AND c.oid = t.tgrelid",
  					name);
  			result4 = PSQLexec(buf.data);
  			if (!result4)
--- 804,817 ----
  				rule_count = PQntuples(result3);
  		}
  
! 		/* count triggers but ignore foreign key triggers */
  		if (tableinfo.triggers)
  		{
  			printfPQExpBuffer(&buf,
  					"SELECT t.tgname\n"
  					"FROM pg_trigger t, pg_class c\n"
! 					"WHERE t.tgisconstraint IS FALSE\n"
! 					"AND c.relname='%s' AND c.oid = t.tgrelid",
  					name);
  			result4 = PSQLexec(buf.data);
  			if (!result4)
***************
*** 815,820 ****
--- 820,839 ----
  				trigger_count = PQntuples(result4);
  		}
  
+ 		/* Fetch the Foreign Key information */
+ 		printfPQExpBuffer(&buf,
+ 					"SELECT conname,\n"
+ 					"SUBSTR(pg_get_fkeydef(16640, 'constraint_1'), POSITION('FOREIGN KEY' in pg_get_fkeydef(16640, 'constraint_1'))) as condef\n"
+ 					"FROM pg_class as c JOIN pg_constraint ON (c.oid = conrelid)\n"
+ 					"WHERE c.relname = '%s' AND contype = 'f'",
+ 					name);
+ 		result5 = PSQLexec(buf.data);
+ 		if (!result5)
+ 			goto error_return;
+ 		else
+ 			foreignkey_count = PQntuples(result5);
+ 
+ 
  		footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1)
  						  * sizeof(*footers));
  
***************
*** 846,852 ****
  		}
  
  
! 		/* print constraints */
  		for (i = 0; i < constr_count; i++)
  		{
  			char	   *s = _("Check constraints");
--- 865,871 ----
  		}
  
  
! 		/* print check constraints */
  		for (i = 0; i < constr_count; i++)
  		{
  			char	   *s = _("Check constraints");
***************
*** 863,868 ****
--- 882,906 ----
  								  PQgetvalue(result2, i, 0));
  			footers[count_footers++] = xstrdup(buf.data);
  		}
+ 
+ 		/* print foreign key constraints */
+ 		for (i = 0; i < foreignkey_count; i++)
+ 		{
+ 			char	   *s = _("Foreign Key constraints:");
+ 
+ 			if (i == 0)
+ 				printfPQExpBuffer(&buf, _("%s: %s %s"),
+ 								  s,
+ 								  PQgetvalue(result5, i, 0),
+ 								  PQgetvalue(result5, i, 1));
+ 			else
+ 				printfPQExpBuffer(&buf, _("%*s: %s %s"),
+ 								  (int) strlen(s), "",
+ 								  PQgetvalue(result5, i, 0),
+ 								  PQgetvalue(result5, i, 1));
+ 			footers[count_footers++] = xstrdup(buf.data);
+ 		}
+ 
  
  		/* print rules */
  		for (i = 0; i < rule_count; i++)
Index: src/include/postgres.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/postgres.h,v
retrieving revision 1.57
diff -c -r1.57 postgres.h
*** src/include/postgres.h	2002/04/27 21:24:34	1.57
--- src/include/postgres.h	2002/06/15 16:39:27
***************
*** 597,608 ****
--- 597,613 ----
  #define CATALOG(x)	typedef struct CppConcat(FormData_,x)
  
  #define BOOTSTRAP
+ 
+ #define BKI_PINWRITE
+ 
  #define BKI_SHARED_RELATION
+ 
  #define BKI_WITHOUT_OIDS
  
  /* these need to expand into some harmless, repeatable declaration */
  #define DATA(x)   extern int errno
  #define DESCR(x)  extern int errno
+ #define PINTABLE(x)   extern int errno
  
  #define BKI_BEGIN
  #define BKI_END
Index: src/include/access/tupdesc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/tupdesc.h,v
retrieving revision 1.34
diff -c -r1.34 tupdesc.h
*** src/include/access/tupdesc.h	2002/03/29 19:06:16	1.34
--- src/include/access/tupdesc.h	2002/06/15 16:39:27
***************
*** 43,49 ****
  
  /*
   * This structure contains all information (i.e. from Classes
!  * pg_attribute, pg_attrdef, pg_relcheck) for a tuple.
   */
  typedef struct tupleDesc
  {
--- 43,49 ----
  
  /*
   * This structure contains all information (i.e. from Classes
!  * pg_attribute, pg_attrdef, pg_constraint) for a tuple.
   */
  typedef struct tupleDesc
  {
Index: src/include/catalog/catname.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/catname.h,v
retrieving revision 1.25
diff -c -r1.25 catname.h
*** src/include/catalog/catname.h	2002/04/27 21:24:34	1.25
--- src/include/catalog/catname.h	2002/06/15 16:39:28
***************
*** 20,26 ****
--- 20,28 ----
  #define  AccessMethodOperatorRelationName "pg_amop"
  #define  AccessMethodProcedureRelationName "pg_amproc"
  #define  AttributeRelationName "pg_attribute"
+ #define  ConstraintRelationName "pg_constraint"
  #define  DatabaseRelationName "pg_database"
+ #define  DependRelationName "pg_depend"
  #define  DescriptionRelationName "pg_description"
  #define  GroupRelationName "pg_group"
  #define  IndexRelationName "pg_index"
***************
*** 39,45 ****
  #define  TypeRelationName "pg_type"
  #define  VersionRelationName "pg_version"
  #define  AttrDefaultRelationName "pg_attrdef"
- #define  RelCheckRelationName "pg_relcheck"
  #define  TriggerRelationName "pg_trigger"
  
  #endif   /* CATNAME_H */
--- 41,46 ----
Index: src/include/catalog/heap.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/heap.h,v
retrieving revision 1.50
diff -c -r1.50 heap.h
*** src/include/catalog/heap.h	2002/04/27 21:24:34	1.50
--- src/include/catalog/heap.h	2002/06/15 16:39:28
***************
*** 44,50 ****
  						 bool relhasoids,
  						 bool allow_system_table_mods);
  
! extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods);
  
  extern void heap_truncate(Oid rid);
  
--- 44,50 ----
  						 bool relhasoids,
  						 bool allow_system_table_mods);
  
! extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods, int behavior);
  
  extern void heap_truncate(Oid rid);
  
Index: src/include/catalog/index.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/index.h,v
retrieving revision 1.47
diff -c -r1.47 index.h
*** src/include/catalog/index.h	2002/03/31 06:26:32	1.47
--- src/include/catalog/index.h	2002/06/15 16:39:28
***************
*** 37,43 ****
  			 bool primary,
  			 bool allow_system_table_mods);
  
! extern void index_drop(Oid indexId);
  
  extern IndexInfo *BuildIndexInfo(Form_pg_index indexStruct);
  
--- 37,43 ----
  			 bool primary,
  			 bool allow_system_table_mods);
  
! extern void index_drop(Oid indexId, int behavior);
  
  extern IndexInfo *BuildIndexInfo(Form_pg_index indexStruct);
  
Index: src/include/catalog/indexing.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/indexing.h,v
retrieving revision 1.66
diff -c -r1.66 indexing.h
*** src/include/catalog/indexing.h	2002/04/19 16:36:08	1.66
--- src/include/catalog/indexing.h	2002/06/15 16:39:28
***************
*** 27,33 ****
--- 27,35 ----
  #define Num_pg_attr_indices			2
  #define Num_pg_attrdef_indices		1
  #define Num_pg_class_indices		2
+ #define Num_pg_constraint_indices	2
  #define Num_pg_database_indices		2
+ #define Num_pg_depend_indices		2
  #define Num_pg_description_indices	1
  #define Num_pg_group_indices		2
  #define Num_pg_index_indices		2
***************
*** 38,44 ****
  #define Num_pg_opclass_indices		2
  #define Num_pg_operator_indices		2
  #define Num_pg_proc_indices			2
- #define Num_pg_relcheck_indices		1
  #define Num_pg_rewrite_indices		2
  #define Num_pg_shadow_indices		2
  #define Num_pg_statistic_indices	1
--- 40,45 ----
***************
*** 59,66 ****
--- 60,71 ----
  #define AttributeRelidNumIndex		"pg_attribute_relid_attnum_index"
  #define ClassNameNspIndex			"pg_class_relname_nsp_index"
  #define ClassOidIndex				"pg_class_oid_index"
+ #define ConstraintOidIndex			"pg_constraint_oid_index"
+ #define ConstraintRelidNameIndex	"pg_constraint_relid_name_index"
  #define DatabaseNameIndex			"pg_database_datname_index"
  #define DatabaseOidIndex			"pg_database_oid_index"
+ #define DependDependerIndex			"pg_depend_depender_index"
+ #define DependDependeeIndex			"pg_depend_dependee_index"
  #define DescriptionObjIndex			"pg_description_o_c_o_index"
  #define GroupNameIndex				"pg_group_name_index"
  #define GroupSysidIndex				"pg_group_sysid_index"
***************
*** 78,84 ****
  #define OperatorOidIndex			"pg_operator_oid_index"
  #define ProcedureNameNspIndex		"pg_proc_proname_args_nsp_index"
  #define ProcedureOidIndex			"pg_proc_oid_index"
- #define RelCheckIndex				"pg_relcheck_rcrelid_index"
  #define RewriteOidIndex				"pg_rewrite_oid_index"
  #define RewriteRelRulenameIndex		"pg_rewrite_rel_rulename_index"
  #define ShadowNameIndex				"pg_shadow_usename_index"
--- 83,88 ----
***************
*** 99,105 ****
--- 103,111 ----
  extern char *Name_pg_attr_indices[];
  extern char *Name_pg_attrdef_indices[];
  extern char *Name_pg_class_indices[];
+ extern char *Name_pg_constraint_indices[];
  extern char *Name_pg_database_indices[];
+ extern char *Name_pg_depend_indices[];
  extern char *Name_pg_description_indices[];
  extern char *Name_pg_group_indices[];
  extern char *Name_pg_index_indices[];
***************
*** 110,116 ****
  extern char *Name_pg_opclass_indices[];
  extern char *Name_pg_operator_indices[];
  extern char *Name_pg_proc_indices[];
- extern char *Name_pg_relcheck_indices[];
  extern char *Name_pg_rewrite_indices[];
  extern char *Name_pg_shadow_indices[];
  extern char *Name_pg_statistic_indices[];
--- 116,121 ----
***************
*** 155,160 ****
--- 160,167 ----
  DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
  DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops));
  DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index on pg_class using btree(relname name_ops, relnamespace oid_ops));
+ DECLARE_UNIQUE_INDEX(pg_constraint_oid_index on pg_constraint using btree(oid oid_ops));
+ DECLARE_UNIQUE_INDEX(pg_constraint_relid_name_index on pg_constraint using btree(conrelid oid_ops, conname name_ops));
  DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops));
  DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops));
  DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops));
***************
*** 176,182 ****
  DECLARE_UNIQUE_INDEX(pg_proc_oid_index on pg_proc using btree(oid oid_ops));
  DECLARE_UNIQUE_INDEX(pg_proc_proname_args_nsp_index on pg_proc using btree(proname name_ops, pronargs int2_ops, proargtypes oidvector_ops, pronamespace oid_ops));
  /* This following index is not used for a cache and is not unique */
- DECLARE_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops));
  DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops));
  DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
  DECLARE_UNIQUE_INDEX(pg_shadow_usename_index on pg_shadow using btree(usename name_ops));
--- 183,188 ----
***************
*** 190,195 ****
--- 196,206 ----
  DECLARE_UNIQUE_INDEX(pg_trigger_oid_index on pg_trigger using btree(oid oid_ops));
  DECLARE_UNIQUE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_ops));
  DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index on pg_type using btree(typname name_ops, typnamespace oid_ops));
+ 
+ /* This following index is not used for a cache and is not unique */
+ DECLARE_INDEX(pg_depend_depender_index on pg_depend using btree(classid oid_ops, objid oid_ops, objsubid int4_ops));
+ /* This following index is not used for a cache and is not unique */
+ DECLARE_INDEX(pg_depend_dependee_index on pg_depend using btree(depclassid oid_ops, depobjid oid_ops, depobjsubid int4_ops));
  
  /* last step of initialization script: build the indices declared above */
  BUILD_INDICES
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.241
diff -c -r1.241 pg_proc.h
*** src/include/catalog/pg_proc.h	2002/06/11 15:41:37	1.241
--- src/include/catalog/pg_proc.h	2002/06/15 16:39:38
***************
*** 94,99 ****
--- 94,102 ----
  #define Anum_pg_proc_probin				19
  #define Anum_pg_proc_proacl				20
  
+ /* Make the below functions permenant */
+ PINTABLE(1255);
+ 
  /* ----------------
   *		initial contents of pg_proc
   * ----------------
***************
*** 2171,2176 ****
--- 2174,2182 ----
  DESCR("greater-than-or-equal");
  
  /* System-view support functions */
+ DATA(insert OID = 1387 (  pg_get_fkeydef       PGNSP PGUID 12 f f f t f s 2 25 "26 19" 100 0 0 100  pg_get_fkeydef - _null_ ));
+ DESCR("alter table foreign key creation statement");
+ 
  DATA(insert OID = 1573 (  pg_get_ruledef	   PGNSP PGUID 12 f f f t f s 1 25 "26" 100 0 0 100  pg_get_ruledef - _null_ ));
  DESCR("source text of a rule");
  DATA(insert OID = 1640 (  pg_get_viewdef	   PGNSP PGUID 12 f f f t f s 1 25 "25" 100 0 0 100  pg_get_viewdef_name - _null_ ));
Index: src/include/catalog/pg_type.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_type.h,v
retrieving revision 1.122
diff -c -r1.122 pg_type.h
*** src/include/catalog/pg_type.h	2002/04/25 02:56:56	1.122
--- src/include/catalog/pg_type.h	2002/06/15 16:39:41
***************
*** 228,233 ****
--- 228,235 ----
  #define Anum_pg_type_typdefaultbin		22
  #define Anum_pg_type_typdefault			23
  
+ /* Make the below types permenant */
+ PINTABLE(1247);
  
  /* ----------------
   *		initial contents of pg_type
Index: src/include/commands/comment.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/comment.h,v
retrieving revision 1.11
diff -c -r1.11 comment.h
*** src/include/commands/comment.h	2002/04/09 20:35:54	1.11
--- src/include/commands/comment.h	2002/06/15 16:39:41
***************
*** 27,33 ****
  
  extern void CommentObject(CommentStmt *stmt);
  
! extern void DeleteComments(Oid oid, Oid classoid);
  
  extern void CreateComments(Oid oid, Oid classoid, int32 subid, char *comment);
  
--- 27,33 ----
  
  extern void CommentObject(CommentStmt *stmt);
  
! extern void DeleteComments(Oid oid, Oid classoid, int32 subid);
  
  extern void CreateComments(Oid oid, Oid classoid, int32 subid, char *comment);
  
Index: src/include/commands/defrem.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/defrem.h,v
retrieving revision 1.38
diff -c -r1.38 defrem.h
*** src/include/commands/defrem.h	2002/05/22 21:40:55	1.38
--- src/include/commands/defrem.h	2002/06/15 16:39:41
***************
*** 29,35 ****
  			bool primary,
  			Expr *predicate,
  			List *rangetable);
! extern void RemoveIndex(RangeVar *relation);
  extern void ReindexIndex(RangeVar *indexRelation, bool force);
  extern void ReindexTable(RangeVar *relation, bool force);
  extern void ReindexDatabase(const char *databaseName, bool force, bool all);
--- 29,35 ----
  			bool primary,
  			Expr *predicate,
  			List *rangetable);
! extern void RemoveIndex(RangeVar *relation, int behavior);
  extern void ReindexIndex(RangeVar *indexRelation, bool force);
  extern void ReindexTable(RangeVar *relation, bool force);
  extern void ReindexDatabase(const char *databaseName, bool force, bool all);
***************
*** 39,55 ****
   */
  
  extern void CreateFunction(CreateFunctionStmt *stmt);
! extern void RemoveFunction(List *functionName, List *argTypes);
  
  extern void DefineOperator(List *names, List *parameters);
  extern void RemoveOperator(List *operatorName,
! 						   TypeName *typeName1, TypeName *typeName2);
  
  extern void DefineAggregate(List *names, List *parameters);
! extern void RemoveAggregate(List *aggName, TypeName *aggType);
  
  extern void DefineType(List *names, List *parameters);
! extern void RemoveType(List *names);
  extern void DefineDomain(CreateDomainStmt *stmt);
  extern void RemoveDomain(List *names, int behavior);
  
--- 39,58 ----
   */
  
  extern void CreateFunction(CreateFunctionStmt *stmt);
! extern void RemoveFunction(List *functionName, List *argTypes, int behavior);
! extern void RemoveFunctionById(Oid funcOid, int behavior);
  
  extern void DefineOperator(List *names, List *parameters);
  extern void RemoveOperator(List *operatorName,
! 						   TypeName *typeName1, TypeName *typeName2, int behavior);
! extern void RemoveOperatorById(Oid operOid, int behavior);
  
  extern void DefineAggregate(List *names, List *parameters);
! extern void RemoveAggregate(List *aggName, TypeName *aggType, int behavior);
  
  extern void DefineType(List *names, List *parameters);
! extern void RemoveType(List *names, int behavior);
! extern void RemoveTypeByTypeName(TypeName *typename, int behavior);
  extern void DefineDomain(CreateDomainStmt *stmt);
  extern void RemoveDomain(List *names, int behavior);
  
Index: src/include/commands/tablecmds.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/tablecmds.h,v
retrieving revision 1.4
diff -c -r1.4 tablecmds.h
*** src/include/commands/tablecmds.h	2002/04/30 01:24:52	1.4
--- src/include/commands/tablecmds.h	2002/06/15 16:39:41
***************
*** 48,54 ****
  
  extern Oid	DefineRelation(CreateStmt *stmt, char relkind);
  
! extern void RemoveRelation(const RangeVar *relation);
  
  extern void TruncateRelation(const RangeVar *relation);
  
--- 48,54 ----
  
  extern Oid	DefineRelation(CreateStmt *stmt, char relkind);
  
! extern void RemoveRelation(const RangeVar *relation, int behavior);
  
  extern void TruncateRelation(const RangeVar *relation);
  
Index: src/include/commands/trigger.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/trigger.h,v
retrieving revision 1.35
diff -c -r1.35 trigger.h
*** src/include/commands/trigger.h	2002/04/26 19:29:47	1.35
--- src/include/commands/trigger.h	2002/06/15 16:39:41
***************
*** 101,109 ****
  #define RI_MAX_ARGUMENTS		(RI_FIRST_ATTNAME_ARGNO + (RI_MAX_NUMKEYS * 2))
  
  
! extern void CreateTrigger(CreateTrigStmt *stmt);
! extern void DropTrigger(Oid relid, const char *trigname);
! extern void RelationRemoveTriggers(Relation rel);
  
  extern void renametrig(Oid relid, const char *oldname, const char *newname);
  
--- 101,110 ----
  #define RI_MAX_ARGUMENTS		(RI_FIRST_ATTNAME_ARGNO + (RI_MAX_NUMKEYS * 2))
  
  
! extern Oid CreateTrigger(CreateTrigStmt *stmt);
! extern char *getTriggerName(Oid relId, char *prefix);
! extern void DropTrigger(Oid relid, const char *trigname, int behavior);
! extern void DropTriggerById(Oid trigId, int behavior);
  
  extern void renametrig(Oid relid, const char *oldname, const char *newname);
  
Index: src/include/commands/view.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/view.h,v
retrieving revision 1.14
diff -c -r1.14 view.h
*** src/include/commands/view.h	2002/03/29 19:06:22	1.14
--- src/include/commands/view.h	2002/06/15 16:39:41
***************
*** 17,22 ****
  #include "nodes/parsenodes.h"
  
  extern void DefineView(const RangeVar *view, Query *view_parse);
! extern void RemoveView(const RangeVar *view);
  
  #endif   /* VIEW_H */
--- 17,22 ----
  #include "nodes/parsenodes.h"
  
  extern void DefineView(const RangeVar *view, Query *view_parse);
! extern void RemoveView(const RangeVar *view, int behavior);
  
  #endif   /* VIEW_H */
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.179
diff -c -r1.179 parsenodes.h
*** src/include/nodes/parsenodes.h	2002/05/22 17:21:01	1.179
--- src/include/nodes/parsenodes.h	2002/06/15 16:39:45
***************
*** 123,128 ****
--- 123,129 ----
  	bool		pct_type;		/* %TYPE specified? */
  	int32		typmod;			/* type modifier */
  	List	   *arrayBounds;	/* array bounds */
+ 	RangeVar   *serial;			/* Serial sequence reference*/
  } TypeName;
  
  /*
***************
*** 947,953 ****
  	RangeVar   *pktable;		/* Primary key table */
  	List	   *fk_attrs;		/* Attributes of foreign key */
  	List	   *pk_attrs;		/* Corresponding attrs in PK table */
! 	char	   *match_type;		/* FULL or PARTIAL */
  	int32		actions;		/* ON DELETE/UPDATE actions */
  	bool		deferrable;		/* DEFERRABLE */
  	bool		initdeferred;	/* INITIALLY DEFERRED */
--- 948,954 ----
  	RangeVar   *pktable;		/* Primary key table */
  	List	   *fk_attrs;		/* Attributes of foreign key */
  	List	   *pk_attrs;		/* Corresponding attrs in PK table */
! 	char		match_type;		/* FULL, PARTIAL, or UNSPECIFIED */
  	int32		actions;		/* ON DELETE/UPDATE actions */
  	bool		deferrable;		/* DEFERRABLE */
  	bool		initdeferred;	/* INITIALLY DEFERRED */
***************
*** 999,1004 ****
--- 1000,1006 ----
  {
  	NodeTag		type;
  	char	   *plname;			/* PL name */
+ 	int			behavior;
  } DropPLangStmt;
  
  /* ----------------------
***************
*** 1131,1136 ****
--- 1133,1139 ----
  	RangeVar   *relation;		/* owning relation */
  	char	   *property;		/* name of rule, trigger, etc */
  	int			removeType;
+ 	int			behavior;
  } DropPropertyStmt;
  
  /* ----------------------
***************
*** 1221,1226 ****
--- 1224,1230 ----
  	NodeTag		type;
  	List	   *aggname;		/* aggregate to drop */
  	TypeName   *aggtype;		/* TypeName for input datatype, or NULL */
+ 	int			behavior;
  } RemoveAggrStmt;
  
  /* ----------------------
***************
*** 1232,1237 ****
--- 1236,1242 ----
  	NodeTag		type;
  	List	   *funcname;		/* function to drop */
  	List	   *args;			/* types of the arguments */
+ 	int			behavior;
  } RemoveFuncStmt;
  
  /* ----------------------
***************
*** 1243,1248 ****
--- 1248,1254 ----
  	NodeTag		type;
  	List	   *opname;			/* operator to drop */
  	List	   *args;			/* types of the arguments */
+ 	int			behavior;
  } RemoveOperStmt;
  
  /* ----------------------
Index: src/include/rewrite/rewriteRemove.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/rewrite/rewriteRemove.h,v
retrieving revision 1.13
diff -c -r1.13 rewriteRemove.h
*** src/include/rewrite/rewriteRemove.h	2002/04/18 20:01:11	1.13
--- src/include/rewrite/rewriteRemove.h	2002/06/15 16:39:45
***************
*** 14,20 ****
  #ifndef REWRITEREMOVE_H
  #define REWRITEREMOVE_H
  
! extern void RemoveRewriteRule(Oid owningRel, const char *ruleName);
! extern void RelationRemoveRules(Oid relid);
  
  #endif   /* REWRITEREMOVE_H */
--- 14,20 ----
  #ifndef REWRITEREMOVE_H
  #define REWRITEREMOVE_H
  
! extern void RemoveRewriteRule(Oid owningRel, const char *ruleName, int behavior);
! extern void RemoveRewriteRuleById(Oid ruleId, int behavior);
  
  #endif   /* REWRITEREMOVE_H */
Index: src/include/utils/builtins.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/builtins.h,v
retrieving revision 1.184
diff -c -r1.184 builtins.h
*** src/include/utils/builtins.h	2002/06/13 03:40:49	1.184
--- src/include/utils/builtins.h	2002/06/15 16:39:47
***************
*** 344,349 ****
--- 344,350 ----
  extern Datum regtypeout(PG_FUNCTION_ARGS);
  
  /* ruleutils.c */
+ extern Datum pg_get_fkeydef(PG_FUNCTION_ARGS);
  extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
  extern Datum pg_get_viewdef(PG_FUNCTION_ARGS);
  extern Datum pg_get_viewdef_name(PG_FUNCTION_ARGS);
Index: src/test/regress/parallel_schedule
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/parallel_schedule,v
retrieving revision 1.9
diff -c -r1.9 parallel_schedule
*** src/test/regress/parallel_schedule	2002/04/05 11:56:55	1.9
--- src/test/regress/parallel_schedule	2002/06/15 16:39:50
***************
*** 75,77 ****
--- 75,79 ----
  # ----------
  # "plpgsql" cannot run concurrently with "rules"
  test: limit plpgsql temp domain
+ 
+ test: drop
Index: src/test/regress/serial_schedule
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/serial_schedule,v
retrieving revision 1.9
diff -c -r1.9 serial_schedule
*** src/test/regress/serial_schedule	2002/04/05 11:56:55	1.9
--- src/test/regress/serial_schedule	2002/06/15 16:39:50
***************
*** 82,85 ****
--- 82,86 ----
  test: plpgsql
  test: temp
  test: domain
+ test: drop
  
Index: src/test/regress/expected/alter_table.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/alter_table.out,v
retrieving revision 1.41
diff -c -r1.41 alter_table.out
*** src/test/regress/expected/alter_table.out	2002/05/03 00:32:18	1.41
--- src/test/regress/expected/alter_table.out	2002/06/15 16:39:50
***************
*** 332,347 ****
  -- Try (and succeed)
  ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
  NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on
  -- tmp4 is a,b
  ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
  NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  ERROR:  UNIQUE constraint matching given keys for referenced table "tmp4" not found
  DROP TABLE tmp5;
  DROP TABLE tmp4;
  DROP TABLE tmp3;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "tmp2"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "tmp2"
  DROP TABLE tmp2;
  -- Foreign key adding test with mixed types
  -- Note: these tables are TEMP to avoid name conflicts when this test
--- 332,354 ----
  -- Try (and succeed)
  ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
  NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
+ -- Fail to add check constraint of same name as foreign key constraint
+ ALTER TABLE tmp3 add constraint tmpconstr check(a is not null);
+ ERROR:  constraint "tmpconstr" already exists
  -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on
  -- tmp4 is a,b
  ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
  NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  ERROR:  UNIQUE constraint matching given keys for referenced table "tmp4" not found
+ -- Drop a few constraints
+ ALTER TABLE tmp5 DROP CONSTRAINT tmpconstr RESTRICT;
+ ERROR:  ALTER TABLE / DROP CONSTRAINT: tmpconstr does not exist
+ ALTER TABLE tmp3 DROP CONSTRAINT tmpconstr CASCADE;
+ -- Attempt to add the previously failing row now that constraint is gone
+ INSERT INTO tmp3 values (5,50);
  DROP TABLE tmp5;
  DROP TABLE tmp4;
  DROP TABLE tmp3;
  DROP TABLE tmp2;
  -- Foreign key adding test with mixed types
  -- Note: these tables are TEMP to avoid name conflicts when this test
***************
*** 369,378 ****
  -- As should this
  ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
  NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
! DROP TABLE pktable;
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "fktable"
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "fktable"
  DROP TABLE fktable;
  CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
                             PRIMARY KEY(ptest1, ptest2));
  NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
--- 376,387 ----
  -- As should this
  ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
  NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
! DROP TABLE pktable restrict;
! ERROR:  Drop Restricted as Table fktable Depends on Table pktable
! DROP TABLE pktable cascade;
! NOTICE:  Cascading drop to Table fktable
  DROP TABLE fktable;
+ ERROR:  table "fktable" does not exist
  CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
                             PRIMARY KEY(ptest1, ptest2));
  NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
***************
*** 414,419 ****
--- 423,434 ----
  ERROR:  ExecAppend: rejected due to CHECK constraint atacc_test1
  -- should succeed
  insert into atacc1 (test) values (4);
+ -- should fail
+ alter table atacc1 DROP constraint unknown_constraint;
+ ERROR:  ALTER TABLE / DROP CONSTRAINT: unknown_constraint does not exist
+ -- should succeed
+ alter table atacc1 drop constraint atacc_test1;
+ insert into atacc1 (test) values (2);
  drop table atacc1;
  -- let's do one where the check fails when added
  create table atacc1 ( test int );
***************
*** 445,451 ****
  alter table atacc1 add check (test2>test);
  -- should fail for $2
  insert into atacc1 (test2, test) values (3, 4);
! ERROR:  ExecAppend: rejected due to CHECK constraint $2
  drop table atacc1;
  -- inheritance related tests
  create table atacc1 (test int);
--- 460,466 ----
  alter table atacc1 add check (test2>test);
  -- should fail for $2
  insert into atacc1 (test2, test) values (3, 4);
! ERROR:  ExecAppend: rejected due to CHECK constraint constraint_1
  drop table atacc1;
  -- inheritance related tests
  create table atacc1 (test int);
***************
*** 493,498 ****
--- 508,516 ----
  -- try adding a unique oid constraint
  alter table atacc1 add constraint atacc_oid1 unique(oid);
  NOTICE:  ALTER TABLE / ADD UNIQUE will create implicit index 'atacc_oid1' for table 'atacc1'
+ -- Remove the constraint and ensure we pass the failed test
+ alter table atacc1 drop constraint atacc_test1;
+ insert into atacc1 (test) values (2);
  drop table atacc1;
  -- let's do one where the unique constraint fails when added
  create table atacc1 ( test int );
Index: src/test/regress/expected/create_misc.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/create_misc.out,v
retrieving revision 1.13
diff -c -r1.13 create_misc.out
*** src/test/regress/expected/create_misc.out	2002/03/06 06:10:52	1.13
--- src/test/regress/expected/create_misc.out	2002/06/15 16:39:50
***************
*** 151,153 ****
--- 151,159 ----
   force | 100
  (3 rows)
  
+ DROP TABLE serialTest;
+ -- Ensure that Serial sequences are dropped with the table
+ CREATE TABLE serialTest (f1 text, f2 serial);
+ NOTICE:  CREATE TABLE will create implicit sequence 'serialtest_f2_seq' for SERIAL column 'serialtest.f2'
+ NOTICE:  CREATE TABLE / UNIQUE will create implicit index 'serialtest_f2_key' for table 'serialtest'
+ DROP TABLE serialTest;
Index: src/test/regress/expected/domain.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/domain.out,v
retrieving revision 1.2
diff -c -r1.2 domain.out
*** src/test/regress/expected/domain.out	2002/03/20 19:45:12	1.2
--- src/test/regress/expected/domain.out	2002/06/15 16:39:51
***************
*** 3,10 ****
  comment on domain domaindroptest is 'About to drop this..';
  create domain basetypetest domaindroptest;
  ERROR:  DefineDomain: domaindroptest is not a basetype
- drop domain domaindroptest cascade;
- ERROR:  DROP DOMAIN does not support the CASCADE keyword
  drop domain domaindroptest;
  -- TEST Domains.
  create domain domainvarchar varchar(5);
--- 3,8 ----
***************
*** 135,144 ****
   3    | 12   | 5    | 3    | 3    | 88   | 8000 | 12.12
  (3 rows)
  
- drop sequence ddef4_seq;
- drop table defaulttest;
- drop domain ddef1 restrict;
- drop domain ddef2 restrict;
- drop domain ddef3 restrict;
- drop domain ddef4 restrict;
- drop domain ddef5 restrict;
--- 133,135 ----
Index: src/test/regress/expected/foreign_key.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/foreign_key.out,v
retrieving revision 1.16
diff -c -r1.16 foreign_key.out
*** src/test/regress/expected/foreign_key.out	2002/05/03 00:32:19	1.16
--- src/test/regress/expected/foreign_key.out	2002/06/15 16:39:54
***************
*** 22,28 ****
  INSERT INTO FKTABLE VALUES (NULL, 1);
  -- Insert a failed row into FK TABLE
  INSERT INTO FKTABLE VALUES (100, 2);
! ERROR:  <unnamed> referential integrity violation - key referenced from fktable not found in pktable
  -- Check FKTABLE
  SELECT * FROM FKTABLE;
   ftest1 | ftest2 
--- 22,28 ----
  INSERT INTO FKTABLE VALUES (NULL, 1);
  -- Insert a failed row into FK TABLE
  INSERT INTO FKTABLE VALUES (100, 2);
! ERROR:  constraint_1 referential integrity violation - key referenced from fktable not found in pktable
  -- Check FKTABLE
  SELECT * FROM FKTABLE;
   ftest1 | ftest2 
***************
*** 55,63 ****
        1 |      3
  (3 rows)
  
! DROP TABLE PKTABLE;
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "fktable"
! DROP TABLE FKTABLE;
  --
  -- check set NULL and table constraint on multiple columns
  --
--- 55,62 ----
        1 |      3
  (3 rows)
  
! DROP TABLE PKTABLE CASCADE;
! NOTICE:  Cascading drop to Table fktable
  --
  -- check set NULL and table constraint on multiple columns
  --
***************
*** 138,146 ****
          |        |      8
  (5 rows)
  
! DROP TABLE PKTABLE;
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "fktable"
! DROP TABLE FKTABLE;
  --
  -- check set default and table constraint on multiple columns
  --
--- 137,144 ----
          |        |      8
  (5 rows)
  
! DROP TABLE PKTABLE CASCADE;
! NOTICE:  Cascading drop to Table fktable
  --
  -- check set default and table constraint on multiple columns
  --
***************
*** 223,231 ****
       -1 |     -2 |      8
  (5 rows)
  
! DROP TABLE PKTABLE;
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "fktable"
! DROP TABLE FKTABLE;
  --
  -- First test, check with no on delete or on update
  --
--- 221,228 ----
       -1 |     -2 |      8
  (5 rows)
  
! DROP TABLE PKTABLE CASCADE;
! NOTICE:  Cascading drop to Table fktable
  --
  -- First test, check with no on delete or on update
  --
***************
*** 246,252 ****
  INSERT INTO FKTABLE VALUES (NULL, 1);
  -- Insert a failed row into FK TABLE
  INSERT INTO FKTABLE VALUES (100, 2);
! ERROR:  <unnamed> referential integrity violation - key referenced from fktable not found in pktable
  -- Check FKTABLE
  SELECT * FROM FKTABLE;
   ftest1 | ftest2 
--- 243,249 ----
  INSERT INTO FKTABLE VALUES (NULL, 1);
  -- Insert a failed row into FK TABLE
  INSERT INTO FKTABLE VALUES (100, 2);
! ERROR:  constraint_1 referential integrity violation - key referenced from fktable not found in pktable
  -- Check FKTABLE
  SELECT * FROM FKTABLE;
   ftest1 | ftest2 
***************
*** 270,276 ****
  
  -- Delete a row from PK TABLE (should fail)
  DELETE FROM PKTABLE WHERE ptest1=1;
! ERROR:  <unnamed> referential integrity violation - key in pktable still referenced from fktable
  -- Delete a row from PK TABLE (should succeed)
  DELETE FROM PKTABLE WHERE ptest1=5;
  -- Check PKTABLE for deletes
--- 267,273 ----
  
  -- Delete a row from PK TABLE (should fail)
  DELETE FROM PKTABLE WHERE ptest1=1;
! ERROR:  constraint_1 referential integrity violation - key in pktable still referenced from fktable
  -- Delete a row from PK TABLE (should succeed)
  DELETE FROM PKTABLE WHERE ptest1=5;
  -- Check PKTABLE for deletes
***************
*** 285,291 ****
  
  -- Update a row from PK TABLE (should fail)
  UPDATE PKTABLE SET ptest1=0 WHERE ptest1=2;
! ERROR:  <unnamed> referential integrity violation - key in pktable still referenced from fktable
  -- Update a row from PK TABLE (should succeed)
  UPDATE PKTABLE SET ptest1=0 WHERE ptest1=4;
  -- Check PKTABLE for updates
--- 282,288 ----
  
  -- Update a row from PK TABLE (should fail)
  UPDATE PKTABLE SET ptest1=0 WHERE ptest1=2;
! ERROR:  constraint_1 referential integrity violation - key in pktable still referenced from fktable
  -- Update a row from PK TABLE (should succeed)
  UPDATE PKTABLE SET ptest1=0 WHERE ptest1=4;
  -- Check PKTABLE for updates
***************
*** 298,306 ****
        0 | Test4
  (4 rows)
  
! DROP TABLE PKTABLE;
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "fktable"
! DROP TABLE FKTABLE;
  -- MATCH unspecified
  -- Base test restricting update/delete
  CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
--- 295,302 ----
        0 | Test4
  (4 rows)
  
! DROP TABLE PKTABLE CASCADE;
! NOTICE:  Cascading drop to Table fktable
  -- MATCH unspecified
  -- Base test restricting update/delete
  CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
***************
*** 363,370 ****
  (5 rows)
  
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  DROP TABLE PKTABLE;
  -- cascade update/delete
  CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
--- 359,364 ----
***************
*** 462,469 ****
  (4 rows)
  
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  DROP TABLE PKTABLE;
  -- set null update / set default delete
  CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
--- 456,461 ----
***************
*** 568,575 ****
  (6 rows)
  
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  DROP TABLE PKTABLE;
  -- set default update / set null delete
  CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
--- 560,565 ----
***************
*** 687,694 ****
  (7 rows)
  
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  DROP TABLE PKTABLE;
  CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY);
  NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
--- 677,682 ----
***************
*** 734,747 ****
  CREATE TABLE FKTABLE (ftest1 varchar REFERENCES pktable);
  NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  -- As should this
  CREATE TABLE FKTABLE (ftest1 varchar REFERENCES pktable(ptest1));
  NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  DROP TABLE PKTABLE;
  -- Two columns, two tables
  CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2));
--- 722,731 ----
***************
*** 775,788 ****
  CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
  NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  -- As does this
  CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
  NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  DROP TABLE FKTABLE;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  DROP TABLE PKTABLE;
  -- Two columns, same table
  -- Make sure this still works...
--- 759,768 ----
***************
*** 832,856 ****
  insert into pktable(base1) values (2);
  --  let's insert a non-existant fktable value
  insert into fktable(ftest1) values (3);
! ERROR:  <unnamed> referential integrity violation - key referenced from fktable not found in pktable
  --  let's make a valid row for that
  insert into pktable(base1) values (3);
  insert into fktable(ftest1) values (3);
  -- let's try removing a row that should fail from pktable
  delete from pktable where base1>2;
! ERROR:  <unnamed> referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try updating all of the base1 values to *4
  -- which should fail.
  update pktable set base1=base1*4;
! ERROR:  <unnamed> referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try an update that should work.
  update pktable set base1=base1*4 where base1<3;
  -- and a delete that should work
  delete from pktable where base1>3;
  -- cleanup
  drop table fktable;
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
  delete from pktable;
  -- Now 2 columns 2 tables, matching types
  create table fktable (ftest1 int, ftest2 int, foreign key(ftest1, ftest2) references pktable(base1, ptest1));
--- 812,834 ----
  insert into pktable(base1) values (2);
  --  let's insert a non-existant fktable value
  insert into fktable(ftest1) values (3);
! ERROR:  constraint_1 referential integrity violation - key referenced from fktable not found in pktable
  --  let's make a valid row for that
  insert into pktable(base1) values (3);
  insert into fktable(ftest1) values (3);
  -- let's try removing a row that should fail from pktable
  delete from pktable where base1>2;
! ERROR:  constraint_1 referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try updating all of the base1 values to *4
  -- which should fail.
  update pktable set base1=base1*4;
! ERROR:  constraint_1 referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try an update that should work.
  update pktable set base1=base1*4 where base1<3;
  -- and a delete that should work
  delete from pktable where base1>3;
  -- cleanup
  drop table fktable;
  delete from pktable;
  -- Now 2 columns 2 tables, matching types
  create table fktable (ftest1 int, ftest2 int, foreign key(ftest1, ftest2) references pktable(base1, ptest1));
***************
*** 860,885 ****
  insert into pktable(base1, ptest1) values (2, 2);
  --  let's insert a non-existant fktable value
  insert into fktable(ftest1, ftest2) values (3, 1);
! ERROR:  <unnamed> referential integrity violation - key referenced from fktable not found in pktable
  --  let's make a valid row for that
  insert into pktable(base1,ptest1) values (3, 1);
  insert into fktable(ftest1, ftest2) values (3, 1);
  -- let's try removing a row that should fail from pktable
  delete from pktable where base1>2;
! ERROR:  <unnamed> referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try updating all of the base1 values to *4
  -- which should fail.
  update pktable set base1=base1*4;
! ERROR:  <unnamed> referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try an update that should work.
  update pktable set base1=base1*4 where base1<3;
  -- and a delete that should work
  delete from pktable where base1>3;
  -- cleanup
  drop table fktable;
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
! NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "pktable"
! drop table pktable;
  drop table pktable_base;
  -- Now we'll do one all in 1 table with 2 columns of matching types
  create table pktable_base(base1 int not null, base2 int);
--- 838,861 ----
  insert into pktable(base1, ptest1) values (2, 2);
  --  let's insert a non-existant fktable value
  insert into fktable(ftest1, ftest2) values (3, 1);
! ERROR:  constraint_1 referential integrity violation - key referenced from fktable not found in pktable
  --  let's make a valid row for that
  insert into pktable(base1,ptest1) values (3, 1);
  insert into fktable(ftest1, ftest2) values (3, 1);
  -- let's try removing a row that should fail from pktable
  delete from pktable where base1>2;
! ERROR:  constraint_1 referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try updating all of the base1 values to *4
  -- which should fail.
  update pktable set base1=base1*4;
! ERROR:  constraint_1 referential integrity violation - key in pktable still referenced from fktable
  -- okay, let's try an update that should work.
  update pktable set base1=base1*4 where base1<3;
  -- and a delete that should work
  delete from pktable where base1>3;
  -- cleanup
  drop table fktable;
! drop table pktable cascade;
  drop table pktable_base;
  -- Now we'll do one all in 1 table with 2 columns of matching types
  create table pktable_base(base1 int not null, base2 int);
***************
*** 893,909 ****
  insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2);
  -- fails (3,2) isn't in base1, ptest1
  insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2);
! ERROR:  <unnamed> referential integrity violation - key referenced from pktable not found in pktable
  -- fails (2,2) is being referenced
  delete from pktable where base1=2;
! ERROR:  <unnamed> referential integrity violation - key in pktable still referenced from pktable
  -- fails (1,1) is being referenced (twice)
  update pktable set base1=3 where base1=1;
! ERROR:  <unnamed> referential integrity violation - key referenced from pktable not found in pktable
  -- this sequence of two deletes will work, since after the first there will be no (2,*) references
  delete from pktable where base2=2;
  delete from pktable where base1=2;
! drop table pktable;
  drop table pktable_base;
  -- 2 columns (2 tables), mismatched types
  create table pktable_base(base1 int not null);
--- 869,885 ----
  insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2);
  -- fails (3,2) isn't in base1, ptest1
  insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2);
! ERROR:  constraint_1 referential integrity violation - key referenced from pktable not found in pktable
  -- fails (2,2) is being referenced
  delete from pktable where base1=2;
! ERROR:  constraint_1 referential integrity violation - key in pktable still referenced from pktable
  -- fails (1,1) is being referenced (twice)
  update pktable set base1=3 where base1=1;
! ERROR:  constraint_1 referential integrity violation - key referenced from pktable not found in pktable
  -- this sequence of two deletes will work, since after the first there will be no (2,*) references
  delete from pktable where base2=2;
  delete from pktable where base1=2;
! drop table pktable cascade;
  drop table pktable_base;
  -- 2 columns (2 tables), mismatched types
  create table pktable_base(base1 int not null);
***************
*** 931,937 ****
  NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  ERROR:  Unable to identify an operator '=' for types 'integer' and 'inet'
  	You will have to retype this query using an explicit cast
! drop table pktable;
  drop table pktable_base;
  -- 2 columns (1 table), mismatched types
  create table pktable_base(base1 int not null, base2 int);
--- 907,913 ----
  NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  ERROR:  Unable to identify an operator '=' for types 'integer' and 'inet'
  	You will have to retype this query using an explicit cast
! drop table pktable cascade;
  drop table pktable_base;
  -- 2 columns (1 table), mismatched types
  create table pktable_base(base1 int not null, base2 int);
***************
*** 959,964 ****
  NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
  ERROR:  Unable to identify an operator '=' for types 'inet' and 'integer'
  	You will have to retype this query using an explicit cast
- drop table pktable;
- ERROR:  table "pktable" does not exist
  drop table pktable_base;
--- 935,938 ----
Index: src/test/regress/expected/sanity_check.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/sanity_check.out,v
retrieving revision 1.17
diff -c -r1.17 sanity_check.out
*** src/test/regress/expected/sanity_check.out	2002/03/22 21:34:44	1.17
--- src/test/regress/expected/sanity_check.out	2002/06/15 16:39:54
***************
*** 38,44 ****
--- 38,46 ----
   pg_attrdef          | t
   pg_attribute        | t
   pg_class            | t
+  pg_constraint       | t
   pg_database         | t
+  pg_depend           | t
   pg_description      | t
   pg_group            | t
   pg_index            | t
***************
*** 49,62 ****
   pg_opclass          | t
   pg_operator         | t
   pg_proc             | t
-  pg_relcheck         | t
   pg_rewrite          | t
   pg_shadow           | t
   pg_statistic        | t
   pg_trigger          | t
   pg_type             | t
   road                | t
-  serialtest          | t
   shighway            | t
   tenk1               | t
   tenk2               | t
--- 51,62 ----
Index: src/test/regress/sql/alter_table.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/alter_table.sql,v
retrieving revision 1.28
diff -c -r1.28 alter_table.sql
*** src/test/regress/sql/alter_table.sql	2002/05/03 00:32:19	1.28
--- src/test/regress/sql/alter_table.sql	2002/06/15 16:39:54
***************
*** 218,228 ****
  -- Try (and succeed)
  ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
  
  -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on
  -- tmp4 is a,b
- 
  ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
  
  DROP TABLE tmp5;
  
  DROP TABLE tmp4;
--- 218,235 ----
  -- Try (and succeed)
  ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
  
+ -- Fail to add check constraint of same name as foreign key constraint
+ ALTER TABLE tmp3 add constraint tmpconstr check(a is not null);
+ 
  -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on
  -- tmp4 is a,b
  ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
  
+ -- Drop a few constraints
+ ALTER TABLE tmp5 DROP CONSTRAINT tmpconstr RESTRICT;
+ ALTER TABLE tmp3 DROP CONSTRAINT tmpconstr CASCADE;
+ -- Attempt to add the previously failing row now that constraint is gone
+ INSERT INTO tmp3 values (5,50);
  DROP TABLE tmp5;
  
  DROP TABLE tmp4;
***************
*** 250,256 ****
  ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
  -- As should this
  ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
! DROP TABLE pktable;
  DROP TABLE fktable;
  
  CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
--- 257,264 ----
  ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
  -- As should this
  ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
! DROP TABLE pktable restrict;
! DROP TABLE pktable cascade;
  DROP TABLE fktable;
  
  CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
***************
*** 283,288 ****
--- 291,301 ----
  insert into atacc1 (test) values (2);
  -- should succeed
  insert into atacc1 (test) values (4);
+ -- should fail
+ alter table atacc1 DROP constraint unknown_constraint;
+ -- should succeed
+ alter table atacc1 drop constraint atacc_test1;
+ insert into atacc1 (test) values (2);
  drop table atacc1;
  
  -- let's do one where the check fails when added
***************
*** 361,366 ****
--- 374,382 ----
  insert into atacc1 (test) values (4);
  -- try adding a unique oid constraint
  alter table atacc1 add constraint atacc_oid1 unique(oid);
+ -- Remove the constraint and ensure we pass the failed test
+ alter table atacc1 drop constraint atacc_test1;
+ insert into atacc1 (test) values (2);
  drop table atacc1;
  
  -- let's do one where the unique constraint fails when added
Index: src/test/regress/sql/create_misc.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/create_misc.sql,v
retrieving revision 1.9
diff -c -r1.9 create_misc.sql
*** src/test/regress/sql/create_misc.sql	2001/05/21 16:54:46	1.9
--- src/test/regress/sql/create_misc.sql	2002/06/15 16:39:54
***************
*** 217,219 ****
--- 217,226 ----
  INSERT INTO serialTest VALUES ('wrong', NULL);
  
  SELECT * FROM serialTest;
+ 
+ DROP TABLE serialTest;
+ 
+ -- Ensure that Serial sequences are dropped with the table
+ CREATE TABLE serialTest (f1 text, f2 serial);
+ 
+ DROP TABLE serialTest;
Index: src/test/regress/sql/create_view.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/create_view.sql,v
retrieving revision 1.3
diff -c -r1.3 create_view.sql
*** src/test/regress/sql/create_view.sql	2000/06/10 05:19:26	1.3
--- src/test/regress/sql/create_view.sql	2002/06/15 16:39:54
***************
*** 17,21 ****
  
  CREATE VIEW toyemp AS
     SELECT name, age, location, 12*salary AS annualsal
!    FROM emp;
! 
--- 17,20 ----
  
  CREATE VIEW toyemp AS
     SELECT name, age, location, 12*salary AS annualsal
!    FROM emp;
\ No newline at end of file
Index: src/test/regress/sql/domain.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/domain.sql,v
retrieving revision 1.2
diff -c -r1.2 domain.sql
*** src/test/regress/sql/domain.sql	2002/03/20 19:45:13	1.2
--- src/test/regress/sql/domain.sql	2002/06/15 16:39:54
***************
*** 6,12 ****
  
  create domain basetypetest domaindroptest;
  
- drop domain domaindroptest cascade;
  drop domain domaindroptest;
  
  
--- 6,11 ----
***************
*** 108,118 ****
  insert into defaulttest default values;
  insert into defaulttest default values;
  select * from defaulttest;
- 
- drop sequence ddef4_seq;
- drop table defaulttest;
- drop domain ddef1 restrict;
- drop domain ddef2 restrict;
- drop domain ddef3 restrict;
- drop domain ddef4 restrict;
- drop domain ddef5 restrict;
--- 107,109 ----
Index: src/test/regress/sql/drop.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/drop.sql,v
retrieving revision 1.5
diff -c -r1.5 drop.sql
*** src/test/regress/sql/drop.sql	2001/10/03 20:54:22	1.5
--- src/test/regress/sql/drop.sql	2002/06/15 16:39:54
***************
*** 1,247 ****
  --
! -- drop.source
  --
  
! --
! -- this will fail if the user is not the postgres superuser.
! -- if it does, don't worry about it (you can turn usersuper
! -- back on as "postgres").  too many people don't follow 
! -- directions and run this as "postgres", though...
! --
! UPDATE pg_user
!    SET usesuper = 't'::bool
!    WHERE usename = 'postgres';
! 
! 
! --
! -- FUNCTION REMOVAL
! --
! DROP FUNCTION hobbies(person);
! 
! DROP FUNCTION hobby_construct(text,text);
! 
! DROP FUNCTION equipment(hobbies_r);
! 
! DROP FUNCTION user_relns();
! 
! DROP FUNCTION widget_in(opaque);
! 
! DROP FUNCTION widget_out(opaque);
! 
! DROP FUNCTION pt_in_widget(point,widget);
! 
! DROP FUNCTION overpaid(emp);
! 
! DROP FUNCTION boxarea(box);
! 
! DROP FUNCTION interpt_pp(path,path);
! 
! DROP FUNCTION reverse_name(name);
! 
! DROP FUNCTION oldstyle_length(int4, text);
! 
! --
! -- OPERATOR REMOVAL
! --
! DROP OPERATOR ## (path, path);
! 
! DROP OPERATOR <% (point, widget);
! 
! -- left unary 
! DROP OPERATOR @#@ (none, int4);
! 
! -- right unary 
! DROP OPERATOR #@# (int4, none);	
! 
! -- right unary 
! DROP OPERATOR #%# (int4, none);	
! 
! 
! --
! -- ABSTRACT DATA TYPE REMOVAL
! --
! DROP TYPE city_budget;
! 
! DROP TYPE widget;
! 
! 
! --
! -- RULE REMOVAL
! --	(is also tested in queries.source)
! --
! 
! --
! -- AGGREGATE REMOVAL
! --
! DROP AGGREGATE newavg (int4);
! 
! DROP AGGREGATE newsum (int4);
! 
! DROP AGGREGATE newcnt (int4);
! 
! 
! --
! -- CLASS REMOVAL
! --	(inheritance hierarchies are deleted in reverse order)
! --
! 
! --
! -- DROP ancillary data structures (i.e. indices)
! --
! DROP INDEX onek_unique1;
! 
! DROP INDEX onek_unique2;
! 
! DROP INDEX onek_hundred;
! 
! DROP INDEX onek_stringu1;
! 
! DROP INDEX tenk1_unique1;
! 
! DROP INDEX tenk1_unique2;
! 
! DROP INDEX tenk1_hundred;
! 
! DROP INDEX tenk2_unique1;
! 
! DROP INDEX tenk2_unique2;
! 
! DROP INDEX tenk2_hundred;
! 
! -- DROP INDEX onek2_u1_prtl;
! 
! -- DROP INDEX onek2_u2_prtl;
  
- -- DROP INDEX onek2_stu1_prtl;
  
! DROP INDEX rect2ind;
  
- DROP INDEX rix;
  
! DROP INDEX iix;
  
- DROP INDEX six;
  
! DROP INDEX hash_i4_index;
  
- DROP INDEX hash_name_index;
  
! DROP INDEX hash_txt_index;
  
- DROP INDEX hash_f8_index;
  
! -- DROP INDEX hash_ovfl_index;
  
- DROP INDEX bt_i4_index;
  
- DROP INDEX bt_name_index;
  
- DROP INDEX bt_txt_index;
- 
- DROP INDEX bt_f8_index;
- 
- 
- DROP TABLE  onek;
- 
- DROP TABLE  onek2;
- 
- DROP TABLE  tenk1;
- 
- DROP TABLE  tenk2;
- 
- DROP TABLE  Bprime;
- 
- 
- DROP TABLE  hobbies_r;
- 
- DROP TABLE  equipment_r;
- 
- 
- DROP TABLE  aggtest;
- 
- DROP TABLE  xacttest;
- 
- DROP TABLE  arrtest;
- 
- DROP TABLE  iportaltest;
- 
- 
- DROP TABLE  f_star;
- 
- DROP TABLE  e_star;
- 
- DROP TABLE  d_star;
- 
- DROP TABLE  c_star;
- 
- DROP TABLE  b_star;
- 
- DROP TABLE  a_star;
- 
- 
- --
- -- must be in reverse inheritance order
- --
- DROP TABLE  stud_emp;
- 
- DROP TABLE  student;
- 
- DROP TABLE  slow_emp4000;
- 
- DROP TABLE  fast_emp4000;
- 
- DROP TABLE  emp;
- 
- DROP TABLE  person;
- 
- 
- DROP TABLE  ramp;
- 
- DROP TABLE  real_city;
- 
- DROP TABLE  dept;
- 
- DROP TABLE  ihighway;
- 
- DROP TABLE  shighway;
- 
- DROP TABLE  road;
- 
- DROP TABLE  city;
- 
- 
- DROP TABLE  hash_i4_heap;
- 
- DROP TABLE  hash_name_heap;
- 
- DROP TABLE  hash_txt_heap;
- 
- DROP TABLE  hash_f8_heap;
- 
- -- DROP TABLE  hash_ovfl_heap;
- 
- DROP TABLE  bt_i4_heap;
- 
- DROP TABLE  bt_name_heap;
- 
- DROP TABLE  bt_txt_heap;
- 
- DROP TABLE  bt_f8_heap;
- 
- 
- DROP TABLE  ABSTIME_TBL;
- 
- DROP TABLE  RELTIME_TBL;
- 
- DROP TABLE  TINTERVAL_TBL;
- 
- --
- -- VIRTUAL CLASS REMOVAL
- --	(also tests removal of rewrite rules)
- --
- DROP VIEW street;
  
- DROP VIEW iexit;
  
- DROP VIEW toyemp;
  
--- 1,43 ----
  --
! -- Test RESTRICT and CASCADE keywords.
  --
  
! -- Ensure system types cannot be removed
! DROP TYPE int4 CASCADE;
! DROP FUNCTION nextval(text) CASCADE;
! DROP TABLE pg_type CASCADE;
  
  
! -- Function RESTRICT / CASCADE
! DROP FUNCTION widget_in(opaque) RESTRICT; -- fail
! DROP TYPE widget RESTRICT; -- fail
! DROP FUNCTION widget_in(opaque) CASCADE;
! DROP TYPE widget RESTRICT; -- doesn't exist
  
  
! -- Type RESTRICT / CASCADE
! DROP TYPE city_budget RESTRICT; -- fail
! DROP TYPE city_budget CASCADE;
! DROP TABLE city RESTRICT; -- doesn't exist
  
  
! -- Domain RESTRICT / CASCADE
! DROP DOMAIN ddef1 RESTRICT; -- fail
! DROP DOMAIN ddef1 CASCADE;
! DROP TABLE defaulttest RESTRICT; -- doesn't exist
  
  
! -- Procedural languge RESTRICT / CASCADE
! DROP LANGUAGE plpgsql RESTRICT; -- fail
! DROP LANGUAGE plpgsql CASCADE;
! SELECT recursion_test(2,3);  -- doesn't exist
  
  
! -- Foreign Key RESTRICT / CASCADE
! -- See alter table pktable and fktable tests
  
  
  
  
  
  
Index: src/test/regress/sql/foreign_key.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/foreign_key.sql,v
retrieving revision 1.6
diff -c -r1.6 foreign_key.sql
*** src/test/regress/sql/foreign_key.sql	2002/05/03 00:32:19	1.6
--- src/test/regress/sql/foreign_key.sql	2002/06/15 16:39:57
***************
*** 40,47 ****
  -- Check FKTABLE for update of matched row
  SELECT * FROM FKTABLE;
  
! DROP TABLE PKTABLE;
! DROP TABLE FKTABLE;
  
  --
  -- check set NULL and table constraint on multiple columns
--- 40,46 ----
  -- Check FKTABLE for update of matched row
  SELECT * FROM FKTABLE;
  
! DROP TABLE PKTABLE CASCADE;
  
  --
  -- check set NULL and table constraint on multiple columns
***************
*** 92,99 ****
  -- Check FKTABLE for update of matched row
  SELECT * FROM FKTABLE;
  
! DROP TABLE PKTABLE;
! DROP TABLE FKTABLE;
  
  --
  -- check set default and table constraint on multiple columns
--- 91,97 ----
  -- Check FKTABLE for update of matched row
  SELECT * FROM FKTABLE;
  
! DROP TABLE PKTABLE CASCADE;
  
  --
  -- check set default and table constraint on multiple columns
***************
*** 147,154 ****
  -- Check FKTABLE for update of matched row
  SELECT * FROM FKTABLE;
  
! DROP TABLE PKTABLE;
! DROP TABLE FKTABLE;
  
  
  --
--- 145,151 ----
  -- Check FKTABLE for update of matched row
  SELECT * FROM FKTABLE;
  
! DROP TABLE PKTABLE CASCADE;
  
  
  --
***************
*** 197,204 ****
  -- Check PKTABLE for updates
  SELECT * FROM PKTABLE;
  
! DROP TABLE PKTABLE;
! DROP TABLE FKTABLE;
  
  
  -- MATCH unspecified
--- 194,200 ----
  -- Check PKTABLE for updates
  SELECT * FROM PKTABLE;
  
! DROP TABLE PKTABLE CASCADE;
  
  
  -- MATCH unspecified
***************
*** 532,538 ****
  delete from pktable where base1>3;
  -- cleanup
  drop table fktable;
! drop table pktable;
  drop table pktable_base;
  
  -- Now we'll do one all in 1 table with 2 columns of matching types
--- 528,534 ----
  delete from pktable where base1>3;
  -- cleanup
  drop table fktable;
! drop table pktable cascade;
  drop table pktable_base;
  
  -- Now we'll do one all in 1 table with 2 columns of matching types
***************
*** 552,558 ****
  -- this sequence of two deletes will work, since after the first there will be no (2,*) references
  delete from pktable where base2=2;
  delete from pktable where base1=2;
! drop table pktable;
  drop table pktable_base;
  
  -- 2 columns (2 tables), mismatched types
--- 548,554 ----
  -- this sequence of two deletes will work, since after the first there will be no (2,*) references
  delete from pktable where base2=2;
  delete from pktable where base1=2;
! drop table pktable cascade;
  drop table pktable_base;
  
  -- 2 columns (2 tables), mismatched types
***************
*** 565,571 ****
  create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable);
  create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
  create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
! drop table pktable;
  drop table pktable_base;
  
  -- 2 columns (1 table), mismatched types
--- 561,567 ----
  create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable);
  create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
  create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
! drop table pktable cascade;
  drop table pktable_base;
  
  -- 2 columns (1 table), mismatched types
***************
*** 578,583 ****
                                               pktable(base1, ptest1)) inherits (pktable_base);
  create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
                                               pktable(base1, ptest1)) inherits (pktable_base);
- drop table pktable;
  drop table pktable_base;
  
--- 574,578 ----
