]> granicus.if.org Git - postgresql/commitdiff
Implement DROP SCHEMA. It lacks support for dropping conversions and
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 18 Jul 2002 16:47:26 +0000 (16:47 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 18 Jul 2002 16:47:26 +0000 (16:47 +0000)
operator classes, both of which are schema-local and so should really
be droppable.

16 files changed:
doc/src/sgml/ref/allfiles.sgml
doc/src/sgml/ref/drop_schema.sgml [new file with mode: 0644]
doc/src/sgml/reference.sgml
src/backend/catalog/dependency.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/pg_operator.c
src/backend/catalog/pg_proc.c
src/backend/catalog/pg_type.c
src/backend/commands/schemacmds.c
src/backend/parser/gram.y
src/backend/tcop/postgres.c
src/backend/tcop/utility.c
src/bin/initdb/initdb.sh
src/include/commands/schemacmds.h
src/include/nodes/parsenodes.h

index c039f661b0cdf94a3bced27829721f0d23dd874e..c9ece5af561b559127569f474f1db22de4416842 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.39 2002/04/25 21:47:07 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.40 2002/07/18 16:47:22 tgl Exp $
 PostgreSQL documentation
 Complete list of usable sgml source files in this directory.
 -->
@@ -79,6 +79,7 @@ Complete list of usable sgml source files in this directory.
 <!entity dropLanguage       system "drop_language.sgml">
 <!entity dropOperator       system "drop_operator.sgml">
 <!entity dropRule           system "drop_rule.sgml">
+<!entity dropSchema         system "drop_schema.sgml">
 <!entity dropSequence       system "drop_sequence.sgml">
 <!entity dropTable          system "drop_table.sgml">
 <!entity dropTrigger        system "drop_trigger.sgml">
diff --git a/doc/src/sgml/ref/drop_schema.sgml b/doc/src/sgml/ref/drop_schema.sgml
new file mode 100644 (file)
index 0000000..8c69893
--- /dev/null
@@ -0,0 +1,184 @@
+<!--
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_schema.sgml,v 1.1 2002/07/18 16:47:22 tgl Exp $
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-DROPSCHEMA">
+ <refmeta>
+  <refentrytitle id="SQL-DROPSCHEMA-TITLE">DROP SCHEMA</refentrytitle>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+ <refnamediv>
+  <refname>
+   DROP SCHEMA
+  </refname>
+  <refpurpose>
+   remove a schema
+  </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+  <refsynopsisdivinfo>
+   <date>2002-07-18</date>
+  </refsynopsisdivinfo>
+  <synopsis>
+DROP SCHEMA <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+
+  </synopsis>
+  
+  <refsect2 id="R2-SQL-DROPSCHEMA-1">
+   <refsect2info>
+    <date>2002-07-18</date>
+   </refsect2info>
+   <title>
+    Inputs
+   </title>
+   <para>
+    <variablelist>
+     <varlistentry>
+      <term><replaceable class="PARAMETER">name</replaceable></term>
+      <listitem>
+       <para>
+       The name of a schema.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term>CASCADE</term>
+      <listitem>
+       <para>
+        Automatically drop objects (tables, functions, etc) that are contained
+       in the schema.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term>RESTRICT</term>
+      <listitem>
+       <para>
+        Refuse to drop the schema if it contains any objects.
+       This is the default.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
+  </refsect2>
+
+  <refsect2 id="R2-SQL-DROPSCHEMA-2">
+   <refsect2info>
+    <date>2002-07-18</date>
+   </refsect2info>
+   <title>
+    Outputs
+   </title>
+   <para>
+
+    <variablelist>
+     <varlistentry>
+      <term><computeroutput>
+DROP SCHEMA
+       </computeroutput></term>
+      <listitem>
+       <para>
+       The message returned if the schema is successfully dropped.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><computeroutput>
+ERROR: Schema "<replaceable class="parameter">name</replaceable>" does not exist
+       </computeroutput></term>
+      <listitem>
+       <para>
+       This message occurs if the specified schema does not exist.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+
+   </para>
+  </refsect2>
+ </refsynopsisdiv>
+
+ <refsect1 id="R1-SQL-DROPSCHEMA-1">
+  <refsect1info>
+   <date>2002-07-18</date>
+  </refsect1info>
+  <title>
+   Description
+  </title>
+  <para>
+   <command>DROP SCHEMA</command> removes schemas from the data base.
+  </para>
+
+  <para>
+   A schema can only be dropped by its owner or a superuser.  Note that
+   the owner can drop the schema (and thereby all contained objects)
+   even if he does not own some of the objects within the schema.
+  </para>
+
+  <refsect2 id="R2-SQL-DROPSCHEMA-3">
+   <refsect2info>
+    <date>2002-07-18</date>
+   </refsect2info>
+   <title>
+    Notes
+   </title>
+   <para>
+    Refer to the <command>CREATE SCHEMA</command> statement for
+    information on how to create a schema.
+   </para>
+  </refsect2>
+ </refsect1>
+
+ <refsect1 id="R1-SQL-DROPSCHEMA-2">
+  <title>
+   Usage
+  </title>
+  <para>
+   To remove schema <literal>mystuff</literal> from the database,
+   along with everything it contains:
+
+   <programlisting>
+DROP SCHEMA mystuff CASCADE;
+   </programlisting>
+  </para>
+ </refsect1>
+ <refsect1 id="R1-SQL-DROPSCHEMA-3">
+  <title>
+   Compatibility
+  </title>
+  
+  <refsect2 id="R2-SQL-DROPSCHEMA-4">
+   <refsect2info>
+    <date>2002-07-18</date>
+   </refsect2info>
+   <title>
+    SQL92
+   </title>
+   <para>
+    <command>DROP SCHEMA</command> is fully compatible with
+    <acronym>SQL92</acronym>, except that the standard only allows
+    one schema to be dropped per command.
+   </para>
+  </refsect2>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"../reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:"/usr/lib/sgml/catalog"
+sgml-local-ecat-files:nil
+End:
+-->
index d1d40f3a72b6aadec1b8163cb01834d0f6f422e4..8249039826ced554fb9356f5812e61a6bdb700a4 100644 (file)
@@ -1,5 +1,5 @@
 <!-- reference.sgml
-$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.28 2002/04/25 21:47:06 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.29 2002/07/18 16:47:22 tgl Exp $
 
 PostgreSQL Reference Manual
 -->
@@ -88,6 +88,7 @@ PostgreSQL Reference Manual
    &dropLanguage;
    &dropOperator;
    &dropRule;
+   &dropSchema;
    &dropSequence;
    &dropTable;
    &dropTrigger;
index 527cca3a85b89d26dc03782a0c4301b7f846d7e3..d2dc8b3795ade3c2f83f5db66e8a19a7982a248c 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.3 2002/07/16 05:53:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.4 2002/07/18 16:47:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "catalog/pg_constraint.h"
 #include "catalog/pg_depend.h"
 #include "catalog/pg_language.h"
+#include "catalog/pg_namespace.h"
 #include "catalog/pg_rewrite.h"
 #include "catalog/pg_trigger.h"
 #include "catalog/pg_type.h"
 #include "commands/comment.h"
 #include "commands/defrem.h"
 #include "commands/proclang.h"
+#include "commands/schemacmds.h"
 #include "commands/trigger.h"
 #include "lib/stringinfo.h"
 #include "miscadmin.h"
@@ -54,6 +56,7 @@ typedef enum ObjectClasses
        OCLASS_OPERATOR,                        /* pg_operator */
        OCLASS_REWRITE,                         /* pg_rewrite */
        OCLASS_TRIGGER,                         /* pg_trigger */
+       OCLASS_SCHEMA,                          /* pg_namespace */
        MAX_OCLASS                                      /* MUST BE LAST */
 } ObjectClasses;
 
@@ -597,6 +600,10 @@ doDeletion(const ObjectAddress *object)
                        RemoveTriggerById(object->objectId);
                        break;
 
+               case OCLASS_SCHEMA:
+                       RemoveSchemaById(object->objectId);
+                       break;
+
                default:
                        elog(ERROR, "doDeletion: Unsupported object class %u",
                                 object->classId);
@@ -981,6 +988,7 @@ init_object_classes(void)
        object_classes[OCLASS_OPERATOR] = get_system_catalog_relid(OperatorRelationName);
        object_classes[OCLASS_REWRITE] = get_system_catalog_relid(RewriteRelationName);
        object_classes[OCLASS_TRIGGER] = get_system_catalog_relid(TriggerRelationName);
+       object_classes[OCLASS_SCHEMA] = get_system_catalog_relid(NamespaceRelationName);
        object_classes_initialized = true;
 }
 
@@ -1045,6 +1053,11 @@ getObjectClass(const ObjectAddress *object)
                Assert(object->objectSubId == 0);
                return OCLASS_TRIGGER;
        }
+       if (object->classId == object_classes[OCLASS_SCHEMA])
+       {
+               Assert(object->objectSubId == 0);
+               return OCLASS_SCHEMA;
+       }
 
        elog(ERROR, "getObjectClass: Unknown object class %u",
                 object->classId);
@@ -1265,6 +1278,22 @@ getObjectDescription(const ObjectAddress *object)
                        break;
                }
 
+               case OCLASS_SCHEMA:
+               {
+                       HeapTuple               schemaTup;
+
+                       schemaTup = SearchSysCache(NAMESPACEOID,
+                                                                          ObjectIdGetDatum(object->objectId),
+                                                                          0, 0, 0);
+                       if (!HeapTupleIsValid(schemaTup))
+                               elog(ERROR, "getObjectDescription: Schema %u does not exist",
+                                        object->objectId);
+                       appendStringInfo(&buffer, "schema %s",
+                                                        NameStr(((Form_pg_namespace) GETSTRUCT(schemaTup))->nspname));
+                       ReleaseSysCache(schemaTup);
+                       break;
+               }
+
                default:
                        appendStringInfo(&buffer, "unknown object %u %u %d",
                                                         object->classId,
index 51933d32ede8891df61e5f1be660bb77a4dd3437..076e1e0462bc3346795f7ea943f50c659d7eea17 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.209 2002/07/16 22:12:18 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.210 2002/07/18 16:47:22 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -742,6 +742,25 @@ heap_create_with_catalog(const char *relname,
        AddNewAttributeTuples(new_rel_oid, new_rel_desc->rd_att,
                                                  relhasoids, relkind);
 
+       /*
+        * make a dependency link to force the relation to be deleted if
+        * its namespace is.  Skip this in bootstrap mode, since we don't
+        * make dependencies while bootstrapping.
+        */
+       if (!IsBootstrapProcessingMode())
+       {
+               ObjectAddress   myself,
+                                               referenced;
+
+               myself.classId = RelOid_pg_class;
+               myself.objectId = new_rel_oid;
+               myself.objectSubId = 0;
+               referenced.classId = get_system_catalog_relid(NamespaceRelationName);
+               referenced.objectId = relnamespace;
+               referenced.objectSubId = 0;
+               recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+       }
+
        /*
         * store constraints and defaults passed in the tupdesc, if any.
         *
index c827edfb3e5a8fa2a558c9205e5442d1bc0ab4f7..92d4d361a5bdf28826a4ea35559085d4c2375016 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.184 2002/07/16 05:53:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.185 2002/07/18 16:47:23 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -670,6 +670,9 @@ index_create(Oid heapRelationId,
         * linked to the table.  If it's not a CONSTRAINT, make the dependency
         * directly on the table.
         *
+        * We don't need a dependency on the namespace, because there'll be
+        * an indirect dependency via our parent table.
+        *
         * During bootstrap we can't register any dependencies, and we don't
         * try to make a constraint either.
         */
index 09c3f6be76fb8b653b0e68d1d2f059e4b01de20b..a2a591f1e627cf61367341ad369a5c102fa88eca 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.71 2002/07/16 22:12:18 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.72 2002/07/18 16:47:23 tgl Exp $
  *
  * NOTES
  *       these routines moved here from commands/define.c and somewhat cleaned up.
@@ -907,7 +907,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
  * Create dependencies for a new operator (either a freshly inserted
  * complete operator, a new shell operator, or a just-updated shell).
  *
- * NB: the OidIsValid tests in this routine are *all* necessary, in case
+ * NB: the OidIsValid tests in this routine are necessary, in case
  * the given operator is a shell.
  */
 static void
@@ -924,6 +924,15 @@ makeOperatorDependencies(HeapTuple tuple, Oid pg_operator_relid)
        /* In case we are updating a shell, delete any existing entries */
        deleteDependencyRecordsFor(myself.classId, myself.objectId);
 
+       /* Dependency on namespace */
+       if (OidIsValid(oper->oprnamespace))
+       {
+               referenced.classId = get_system_catalog_relid(NamespaceRelationName);
+               referenced.objectId = oper->oprnamespace;
+               referenced.objectSubId = 0;
+               recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+       }
+
        /* Dependency on left type */
        if (OidIsValid(oper->oprleft))
        {
index 18746d9e2196d058b14c3be0990c1f9ecf9e85d2..f8693fa7fece1ca54a79e970f70b1e6b61ea2b21 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.77 2002/07/16 22:12:19 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.78 2002/07/18 16:47:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -268,6 +268,12 @@ ProcedureCreate(const char *procedureName,
        myself.objectId = retval;
        myself.objectSubId = 0;
 
+       /* dependency on namespace */
+       referenced.classId = get_system_catalog_relid(NamespaceRelationName);
+       referenced.objectId = procNamespace;
+       referenced.objectSubId = 0;
+       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
        /* dependency on implementation language */
        referenced.classId = get_system_catalog_relid(LanguageRelationName);
        referenced.objectId = languageObjectId;
index 88f113beb01c6c645e8f7c4b2b9880d80e2bca53..5cd5d291d7e6e150193ba262d26dd1e5697497ce 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.73 2002/07/12 18:43:15 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.74 2002/07/18 16:47:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,6 +21,7 @@
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
 #include "utils/builtins.h"
+#include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
 
@@ -167,8 +168,6 @@ TypeCreate(const char *typeName,
        NameData        name;
        TupleDesc       tupDesc;
        int                     i;
-       ObjectAddress   myself,
-                                       referenced;
 
        /*
         * validate size specifications: either positive (fixed-length) or -1
@@ -302,74 +301,90 @@ TypeCreate(const char *typeName,
        }
 
        /*
-        * Create dependencies
+        * Create dependencies.  We can/must skip this in bootstrap mode.
         */
-       myself.classId = RelOid_pg_type;
-       myself.objectId = typeObjectId;
-       myself.objectSubId = 0;
-
-       /* Normal dependencies on the I/O functions */
-       referenced.classId = RelOid_pg_proc;
-       referenced.objectId = inputProcedure;
-       referenced.objectSubId = 0;
-       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
-       referenced.classId = RelOid_pg_proc;
-       referenced.objectId = outputProcedure;
-       referenced.objectSubId = 0;
-       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
-       if (receiveProcedure != inputProcedure)
+       if (!IsBootstrapProcessingMode())
        {
+               ObjectAddress   myself,
+                                               referenced;
+
+               myself.classId = RelOid_pg_type;
+               myself.objectId = typeObjectId;
+               myself.objectSubId = 0;
+
+               /* dependency on namespace */
+               /* skip for relation rowtype, since we have indirect dependency */
+               if (!OidIsValid(relationOid))
+               {
+                       referenced.classId = get_system_catalog_relid(NamespaceRelationName);
+                       referenced.objectId = typeNamespace;
+                       referenced.objectSubId = 0;
+                       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+               }
+
+               /* Normal dependencies on the I/O functions */
                referenced.classId = RelOid_pg_proc;
-               referenced.objectId = receiveProcedure;
+               referenced.objectId = inputProcedure;
                referenced.objectSubId = 0;
                recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-       }
 
-       if (sendProcedure != outputProcedure)
-       {
                referenced.classId = RelOid_pg_proc;
-               referenced.objectId = sendProcedure;
+               referenced.objectId = outputProcedure;
                referenced.objectSubId = 0;
                recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-       }
 
-       /*
-        * If the type is a rowtype for a relation, mark it as internally
-        * dependent on the relation.  This allows it to be auto-dropped
-        * when the relation is, and not otherwise.
-        */
-       if (OidIsValid(relationOid))
-       {
-               referenced.classId = RelOid_pg_class;
-               referenced.objectId = relationOid;
-               referenced.objectSubId = 0;
-               recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
-       }
+               if (receiveProcedure != inputProcedure)
+               {
+                       referenced.classId = RelOid_pg_proc;
+                       referenced.objectId = receiveProcedure;
+                       referenced.objectSubId = 0;
+                       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+               }
+
+               if (sendProcedure != outputProcedure)
+               {
+                       referenced.classId = RelOid_pg_proc;
+                       referenced.objectId = sendProcedure;
+                       referenced.objectSubId = 0;
+                       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+               }
 
-       /*
-        * If the type is an array type, mark it auto-dependent on the
-        * base type.  (This is a compromise between the typical case where the
-        * array type is automatically generated and the case where it is manually
-        * created: we'd prefer INTERNAL for the former case and NORMAL for the
-        * latter.)
-        */
-       if (OidIsValid(elementType))
-       {
-               referenced.classId = RelOid_pg_type;
-               referenced.objectId = elementType;
-               referenced.objectSubId = 0;
-               recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
-       }
+               /*
+                * If the type is a rowtype for a relation, mark it as internally
+                * dependent on the relation.  This allows it to be auto-dropped
+                * when the relation is, and not otherwise.
+                */
+               if (OidIsValid(relationOid))
+               {
+                       referenced.classId = RelOid_pg_class;
+                       referenced.objectId = relationOid;
+                       referenced.objectSubId = 0;
+                       recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
+               }
 
-       /* Normal dependency from a domain to its base type. */
-       if (OidIsValid(baseType))
-       {
-               referenced.classId = RelOid_pg_type;
-               referenced.objectId = baseType;
-               referenced.objectSubId = 0;
-               recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+               /*
+                * If the type is an array type, mark it auto-dependent on the base
+                * type.  (This is a compromise between the typical case where the
+                * array type is automatically generated and the case where it is
+                * manually created: we'd prefer INTERNAL for the former case and
+                * NORMAL for the latter.)
+                */
+               if (OidIsValid(elementType))
+               {
+                       referenced.classId = RelOid_pg_type;
+                       referenced.objectId = elementType;
+                       referenced.objectSubId = 0;
+                       recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
+               }
+
+               /* Normal dependency from a domain to its base type. */
+               if (OidIsValid(baseType))
+               {
+                       referenced.classId = RelOid_pg_type;
+                       referenced.objectId = baseType;
+                       referenced.objectSubId = 0;
+                       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+               }
        }
 
        /*
index a790a28bccd7ea32b2a669c4e5312729a4ef5ec6..621006758c54f18a090c81c0656813f441fd3f2c 100644 (file)
@@ -1,20 +1,23 @@
 /*-------------------------------------------------------------------------
  *
  * schemacmds.c
- *       schema creation command support code
+ *       schema creation/manipulation commands
  *
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.4 2002/06/11 13:40:50 wieck Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.5 2002/07/18 16:47:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
+#include "access/heapam.h"
 #include "catalog/catalog.h"
+#include "catalog/catname.h"
+#include "catalog/dependency.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_namespace.h"
 #include "commands/schemacmds.h"
@@ -23,6 +26,7 @@
 #include "tcop/utility.h"
 #include "utils/acl.h"
 #include "utils/lsyscache.h"
+#include "utils/syscache.h"
 
 
 /*
@@ -139,3 +143,70 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
        /* Reset current user */
        SetUserId(saved_userid);
 }
+
+
+/*
+ *     RemoveSchema
+ *             Removes a schema.
+ */
+void
+RemoveSchema(List *names, DropBehavior behavior)
+{
+       char       *namespaceName;
+       Oid                     namespaceId;
+       ObjectAddress object;
+
+       if (length(names) != 1)
+               elog(ERROR, "Schema name may not be qualified");
+       namespaceName = strVal(lfirst(names));
+
+       namespaceId = GetSysCacheOid(NAMESPACENAME,
+                                                                CStringGetDatum(namespaceName),
+                                                                0, 0, 0);
+       if (!OidIsValid(namespaceId))
+               elog(ERROR, "Schema \"%s\" does not exist", namespaceName);
+
+       /* Permission check */
+       if (!pg_namespace_ownercheck(namespaceId, GetUserId()))
+               aclcheck_error(ACLCHECK_NOT_OWNER, namespaceName);
+
+       /*
+        * Do the deletion.  Objects contained in the schema are removed
+        * by means of their dependency links to the schema.
+        *
+        * XXX currently, index opclasses don't have creation/deletion
+        * commands, so they will not get removed when the containing
+        * schema is removed.  This is annoying but not fatal.
+        */
+       object.classId = get_system_catalog_relid(NamespaceRelationName);
+       object.objectId = namespaceId;
+       object.objectSubId = 0;
+
+       performDeletion(&object, behavior);
+}
+
+
+/*
+ * Guts of schema deletion.
+ */
+void
+RemoveSchemaById(Oid schemaOid)
+{
+       Relation        relation;
+       HeapTuple       tup;
+
+       relation = heap_openr(NamespaceRelationName, RowExclusiveLock);
+
+       tup = SearchSysCache(NAMESPACEOID,
+                                                ObjectIdGetDatum(schemaOid),
+                                                0, 0, 0);
+       if (!HeapTupleIsValid(tup))
+               elog(ERROR, "RemoveSchemaById: schema %u not found",
+                        schemaOid);
+
+       simple_heap_delete(relation, &tup->t_self);
+
+       ReleaseSysCache(tup);
+
+       heap_close(relation, RowExclusiveLock);
+}
index 17a3b61e76226607a4ca024cf22c8f43f5458a6b..d7af8d956aff3693e29dcd96c118c60ea128f21e 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.344 2002/07/18 04:43:50 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.345 2002/07/18 16:47:24 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -132,7 +132,7 @@ static void doNegateFloat(Value *v);
 }
 
 %type <node>   stmt, schema_stmt,
-               AlterDatabaseSetStmt, AlterGroupStmt, AlterSchemaStmt,
+               AlterDatabaseSetStmt, AlterGroupStmt,
                AlterTableStmt, AlterUserStmt, AlterUserSetStmt,
                AnalyzeStmt, ClosePortalStmt, ClusterStmt, CommentStmt,
                ConstraintsSetStmt, CopyStmt, CreateAsStmt,
@@ -140,7 +140,7 @@ static void doNegateFloat(Value *v);
                CreateSchemaStmt, CreateSeqStmt, CreateStmt,
                CreateAssertStmt, CreateTrigStmt, CreateUserStmt,
                CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
-               DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt,
+               DropGroupStmt, DropPLangStmt, DropStmt,
                DropAssertStmt, DropTrigStmt, DropRuleStmt,
                DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
                GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt,
@@ -468,7 +468,6 @@ stmtmulti:  stmtmulti ';' stmt
 stmt :
                        AlterDatabaseSetStmt
                        | AlterGroupStmt
-                       | AlterSchemaStmt
                        | AlterTableStmt
                        | AlterUserStmt
                        | AlterUserSetStmt
@@ -488,7 +487,6 @@ stmt :
                        | ClusterStmt
                        | DefineStmt
                        | DropStmt
-                       | DropSchemaStmt
                        | TruncateStmt
                        | CommentStmt
                        | DropGroupStmt
@@ -746,7 +744,6 @@ DropGroupStmt:
  *
  * Manipulate a schema
  *
- *
  *****************************************************************************/
 
 CreateSchemaStmt:
@@ -773,20 +770,6 @@ CreateSchemaStmt:
                                }
                ;
 
-AlterSchemaStmt:
-                       ALTER SCHEMA ColId
-                               {
-                                       elog(ERROR, "ALTER SCHEMA not yet supported");
-                               }
-               ;
-
-DropSchemaStmt:
-                       DROP SCHEMA ColId opt_drop_behavior
-                               {
-                                       elog(ERROR, "DROP SCHEMA not yet supported");
-                               }
-               ;
-
 OptSchemaName:
                        ColId                                                                   { $$ = $1; }
                        | /* EMPTY */                                                   { $$ = NULL; }
@@ -2306,6 +2289,7 @@ drop_type:        TABLE                                                                   { $$ = DROP_TABLE; }
                        | TYPE_P                                                                { $$ = DROP_TYPE; }
                        | DOMAIN_P                                                              { $$ = DROP_DOMAIN; }
                        | CONVERSION_P                                                  { $$ = DROP_CONVERSION; }
+                       | SCHEMA                                                                { $$ = DROP_SCHEMA; }
                ;
 
 any_name_list:
index 154e478687b673a28be8d6085f67e45ab6610879..862faf34cae8b9b735592f6ecdc954e4b455e6ec 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.270 2002/07/13 01:02:14 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.271 2002/07/18 16:47:25 tgl Exp $
  *
  * NOTES
  *       this is the "main" module of the postgres backend and
@@ -1693,7 +1693,7 @@ PostgresMain(int argc, char *argv[], const char *username)
        if (!IsUnderPostmaster)
        {
                puts("\nPOSTGRES backend interactive interface ");
-               puts("$Revision: 1.270 $ $Date: 2002/07/13 01:02:14 $\n");
+               puts("$Revision: 1.271 $ $Date: 2002/07/18 16:47:25 $\n");
        }
 
        /*
@@ -2220,7 +2220,10 @@ CreateCommandTag(Node *parsetree)
                                        tag = "DROP DOMAIN";
                                        break;
                                case DROP_CONVERSION:
-                                       tag = "DROP CONVERSON";
+                                       tag = "DROP CONVERSION";
+                                       break;
+                               case DROP_SCHEMA:
+                                       tag = "DROP SCHEMA";
                                        break;
                                default:
                                        tag = "???";
index 8637394366703bee1a5a7d8459c90f832eeda8b7..8ba7466ee286b663b4ead170fe06e8ca231df270 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.162 2002/07/12 18:43:17 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.163 2002/07/18 16:47:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -252,11 +252,7 @@ ProcessUtility(Node *parsetree,
                         * relation and attribute manipulation
                         */
                case T_CreateSchemaStmt:
-                       {
-                               CreateSchemaStmt  *stmt = (CreateSchemaStmt *) parsetree;
-
-                               CreateSchemaCommand(stmt);
-                       }
+                       CreateSchemaCommand((CreateSchemaStmt *) parsetree);
                        break;
 
                case T_CreateStmt:
@@ -322,17 +318,20 @@ ProcessUtility(Node *parsetree,
                                                        break;
 
                                                case DROP_CONVERSION:
-                                                       /* RemoveDomain does its own permissions checks */
+                                                       /* does its own permissions checks */
                                                        DropConversionCommand(names);
                                                        break;
+
+                                               case DROP_SCHEMA:
+                                                       /* RemoveSchema does its own permissions checks */
+                                                       RemoveSchema(names, stmt->behavior);
+                                                       break;
                                        }
 
                                        /*
-                                        * Make sure subsequent loop iterations will see
-                                        * results of this one; needed if removing multiple
-                                        * rules for same table, for example.
+                                        * We used to need to do CommandCounterIncrement()
+                                        * here, but now it's done inside performDeletion().
                                         */
-                                       CommandCounterIncrement();
                                }
                        }
                        break;
index a88eed353b19bb1636a550bc4a04b6dae8caa2e6..9902a24fc4f498b5206b44c403a26ab363b4c81b 100644 (file)
@@ -27,7 +27,7 @@
 # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.159 2002/07/18 02:02:30 ishii Exp $
+# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.160 2002/07/18 16:47:25 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -717,6 +717,9 @@ INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_language;
 INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_operator;
 INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_rewrite;
 INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_trigger;
+-- restriction here to avoid pinning the public namespace
+INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_namespace \
+    WHERE nspname LIKE 'pg%';
 EOF
 if [ "$?" -ne 0 ]; then
     exit_nicely
index 6adf9a4517ea0357520cb7858d8957b0d8171865..63205500c27ac038a26ffabf8dea5f119ff7e742 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: schemacmds.h,v 1.1 2002/04/15 05:22:04 tgl Exp $
+ * $Id: schemacmds.h,v 1.2 2002/07/18 16:47:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,4 +19,7 @@
 
 extern void CreateSchemaCommand(CreateSchemaStmt *parsetree);
 
+extern void RemoveSchema(List *names, DropBehavior behavior);
+extern void RemoveSchemaById(Oid schemaOid);
+
 #endif  /* SCHEMACMDS_H */
index e6b27d03af486ef485a78813c59f9701fddf5f13..26e2e0ab29961481c74444ef70d9e76ec2e031ec 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.190 2002/07/18 04:43:51 momjian Exp $
+ * $Id: parsenodes.h,v 1.191 2002/07/18 16:47:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1136,7 +1136,7 @@ typedef struct CreateDomainStmt
 } CreateDomainStmt;
 
 /* ----------------------
- *             Drop Table|Sequence|View|Index|Type|Domain Statement
+ *             Drop Table|Sequence|View|Index|Type|Domain|Conversion|Schema Statement
  * ----------------------
  */
 
@@ -1147,6 +1147,7 @@ typedef struct CreateDomainStmt
 #define DROP_TYPE     5
 #define DROP_DOMAIN      6
 #define DROP_CONVERSION          7
+#define DROP_SCHEMA      8
 
 typedef struct DropStmt
 {