aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/allfiles.sgml3
-rw-r--r--doc/src/sgml/ref/drop_schema.sgml184
-rw-r--r--doc/src/sgml/reference.sgml3
-rw-r--r--src/backend/catalog/dependency.c31
-rw-r--r--src/backend/catalog/heap.c21
-rw-r--r--src/backend/catalog/index.c5
-rw-r--r--src/backend/catalog/pg_operator.c13
-rw-r--r--src/backend/catalog/pg_proc.c8
-rw-r--r--src/backend/catalog/pg_type.c133
-rw-r--r--src/backend/commands/schemacmds.c75
-rw-r--r--src/backend/parser/gram.y24
-rw-r--r--src/backend/tcop/postgres.c9
-rw-r--r--src/backend/tcop/utility.c21
-rw-r--r--src/bin/initdb/initdb.sh5
-rw-r--r--src/include/commands/schemacmds.h5
-rw-r--r--src/include/nodes/parsenodes.h5
16 files changed, 438 insertions, 107 deletions
diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
index c039f661b0c..c9ece5af561 100644
--- a/doc/src/sgml/ref/allfiles.sgml
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -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
index 00000000000..8c69893ae2f
--- /dev/null
+++ b/doc/src/sgml/ref/drop_schema.sgml
@@ -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:
+-->
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
index d1d40f3a72b..8249039826c 100644
--- a/doc/src/sgml/reference.sgml
+++ b/doc/src/sgml/reference.sgml
@@ -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;
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 527cca3a85b..d2dc8b3795a 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -25,12 +25,14 @@
#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,
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 51933d32ede..076e1e0462b 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -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
@@ -743,6 +743,25 @@ heap_create_with_catalog(const char *relname,
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.
*
* NB: this may do a CommandCounterIncrement and rebuild the relcache
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index c827edfb3e5..92d4d361a5b 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -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.
*/
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 09c3f6be76f..a2a591f1e62 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -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))
{
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 18746d9e219..f8693fa7fec 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -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;
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 88f113beb01..5cd5d291d7e 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -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);
+ }
}
/*
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index a790a28bccd..621006758c5 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -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);
+}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 17a3b61e762..d7af8d956af 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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:
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 154e478687b..862faf34cae 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -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 = "???";
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 86373943667..8ba7466ee28 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -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;
diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh
index a88eed353b1..9902a24fc4f 100644
--- a/src/bin/initdb/initdb.sh
+++ b/src/bin/initdb/initdb.sh
@@ -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
diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h
index 6adf9a4517e..63205500c27 100644
--- a/src/include/commands/schemacmds.h
+++ b/src/include/commands/schemacmds.h
@@ -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 */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index e6b27d03af4..26e2e0ab299 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -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
{