diff --git a/doc/src/sgml/ref/create_schema.sgml b/doc/src/sgml/ref/create_schema.sgml
index e348ff58797..4c0f61ad95a 100644
--- a/doc/src/sgml/ref/create_schema.sgml
+++ b/doc/src/sgml/ref/create_schema.sgml
@@ -1,5 +1,5 @@
@@ -84,11 +84,13 @@ CREATE SCHEMA AUTHORIZATION usernameschema_element
- An SQL statement defining an object to be created within the schema.
- Currently, only CREATE TABLE>, CREATE VIEW>,
- and GRANT> are accepted as clauses within
- CREATE SCHEMA>. Other kinds of objects may be created
- in separate commands after the schema is created.
+ An SQL statement defining an object to be created within the
+ schema. Currently, only CREATE
+ TABLE>, CREATE VIEW>, CREATE
+ INDEX>, CREATE SEQUENCE>, CREATE
+ TRIGGER> and GRANT> are accepted as clauses
+ within CREATE SCHEMA>. Other kinds of objects may
+ be created in separate commands after the schema is created.
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index bc70cca429a..33f32c1b377 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.294 2004/01/10 23:28:45 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.295 2004/01/11 04:58:17 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@@ -54,8 +54,11 @@ typedef struct
const char *stmtType; /* "CREATE SCHEMA" or "ALTER SCHEMA" */
char *schemaname; /* name of schema */
char *authid; /* owner of schema */
+ List *sequences; /* CREATE SEQUENCE items */
List *tables; /* CREATE TABLE items */
List *views; /* CREATE VIEW items */
+ List *indexes; /* CREATE INDEX items */
+ List *triggers; /* CREATE TRIGGER items */
List *grants; /* GRANT items */
List *fwconstraints; /* Forward referencing FOREIGN KEY
* constraints */
@@ -3152,13 +3155,28 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
ReleaseSysCache(ctype);
}
+static void
+setSchemaName(char *context_schema, char **stmt_schema_name)
+{
+ if (*stmt_schema_name == NULL)
+ *stmt_schema_name = context_schema;
+ else if (strcmp(context_schema, *stmt_schema_name) != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_SCHEMA_DEFINITION),
+ errmsg("CREATE specifies a schema (%s) "
+ "different from the one being created (%s)",
+ *stmt_schema_name, context_schema)));
+}
+
/*
* analyzeCreateSchemaStmt -
* analyzes the "create schema" statement
*
* Split the schema element list into individual commands and place
- * them in the result list in an order such that there are no
- * forward references (e.g. GRANT to a table created later in the list).
+ * them in the result list in an order such that there are no forward
+ * references (e.g. GRANT to a table created later in the list). Note
+ * that the logic we use for determining forward references is
+ * presently quite incomplete.
*
* SQL92 also allows constraints to make forward references, so thumb through
* the table columns and move forward references to a posterior alter-table
@@ -3168,7 +3186,7 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
* but we can't analyze the later commands until we've executed the earlier
* ones, because of possible inter-object references.
*
- * Note: Called from commands/command.c
+ * Note: Called from commands/schemacmds.c
*/
List *
analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
@@ -3180,9 +3198,12 @@ analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
cxt.stmtType = "CREATE SCHEMA";
cxt.schemaname = stmt->schemaname;
cxt.authid = stmt->authid;
+ cxt.sequences = NIL;
cxt.tables = NIL;
cxt.views = NIL;
+ cxt.indexes = NIL;
cxt.grants = NIL;
+ cxt.triggers = NIL;
cxt.fwconstraints = NIL;
cxt.alters = NIL;
cxt.blist = NIL;
@@ -3198,23 +3219,24 @@ analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
switch (nodeTag(element))
{
+ case T_CreateSeqStmt:
+ {
+ CreateSeqStmt *elp = (CreateSeqStmt *) element;
+
+ setSchemaName(cxt.schemaname, &elp->sequence->schemaname);
+ cxt.sequences = lappend(cxt.sequences, element);
+ }
+ break;
+
case T_CreateStmt:
{
CreateStmt *elp = (CreateStmt *) element;
- if (elp->relation->schemaname == NULL)
- elp->relation->schemaname = cxt.schemaname;
- else if (strcmp(cxt.schemaname, elp->relation->schemaname) != 0)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_SCHEMA_DEFINITION),
- errmsg("CREATE specifies a schema (%s)"
- " different from the one being created (%s)",
- elp->relation->schemaname, cxt.schemaname)));
+ setSchemaName(cxt.schemaname, &elp->relation->schemaname);
/*
* XXX todo: deal with constraints
*/
-
cxt.tables = lappend(cxt.tables, element);
}
break;
@@ -3223,23 +3245,33 @@ analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
{
ViewStmt *elp = (ViewStmt *) element;
- if (elp->view->schemaname == NULL)
- elp->view->schemaname = cxt.schemaname;
- else if (strcmp(cxt.schemaname, elp->view->schemaname) != 0)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_SCHEMA_DEFINITION),
- errmsg("CREATE specifies a schema (%s)"
- " different from the one being created (%s)",
- elp->view->schemaname, cxt.schemaname)));
+ setSchemaName(cxt.schemaname, &elp->view->schemaname);
/*
* XXX todo: deal with references between views
*/
-
cxt.views = lappend(cxt.views, element);
}
break;
+ case T_IndexStmt:
+ {
+ IndexStmt *elp = (IndexStmt *) element;
+
+ setSchemaName(cxt.schemaname, &elp->relation->schemaname);
+ cxt.indexes = lappend(cxt.indexes, element);
+ }
+ break;
+
+ case T_CreateTrigStmt:
+ {
+ CreateTrigStmt *elp = (CreateTrigStmt *) element;
+
+ setSchemaName(cxt.schemaname, &elp->relation->schemaname);
+ cxt.triggers = lappend(cxt.triggers, element);
+ }
+ break;
+
case T_GrantStmt:
cxt.grants = lappend(cxt.grants, element);
break;
@@ -3251,8 +3283,11 @@ analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
}
result = NIL;
+ result = nconc(result, cxt.sequences);
result = nconc(result, cxt.tables);
result = nconc(result, cxt.views);
+ result = nconc(result, cxt.indexes);
+ result = nconc(result, cxt.triggers);
result = nconc(result, cxt.grants);
return result;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 535da4f2b50..60570716537 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.445 2004/01/10 23:28:45 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.446 2004/01/11 04:58:17 neilc Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -815,6 +815,9 @@ OptSchemaEltList:
*/
schema_stmt:
CreateStmt
+ | IndexStmt
+ | CreateSeqStmt
+ | CreateTrigStmt
| GrantStmt
| ViewStmt
;
diff --git a/src/test/regress/expected/namespace.out b/src/test/regress/expected/namespace.out
new file mode 100644
index 00000000000..60e3a82ea34
--- /dev/null
+++ b/src/test/regress/expected/namespace.out
@@ -0,0 +1,52 @@
+--
+-- Regression tests for schemas (namespaces)
+--
+CREATE SCHEMA test_schema_1
+ CREATE UNIQUE INDEX abc_a_idx ON abc (a)
+ CREATE VIEW abc_view AS
+ SELECT a+1 AS a, b+1 AS b FROM abc
+ CREATE TABLE abc (
+ a serial,
+ b int UNIQUE
+ );
+NOTICE: CREATE TABLE will create implicit sequence "abc_a_seq" for "serial" column "abc.a"
+NOTICE: CREATE TABLE / UNIQUE will create implicit index "abc_b_key" for table "abc"
+-- verify that the objects were created
+SELECT COUNT(*) FROM pg_class WHERE relnamespace =
+ (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
+ count
+-------
+ 5
+(1 row)
+
+INSERT INTO test_schema_1.abc DEFAULT VALUES;
+INSERT INTO test_schema_1.abc DEFAULT VALUES;
+INSERT INTO test_schema_1.abc DEFAULT VALUES;
+SELECT * FROM test_schema_1.abc;
+ a | b
+---+---
+ 1 |
+ 2 |
+ 3 |
+(3 rows)
+
+SELECT * FROM test_schema_1.abc_view;
+ a | b
+---+---
+ 2 |
+ 3 |
+ 4 |
+(3 rows)
+
+DROP SCHEMA test_schema_1 CASCADE;
+NOTICE: drop cascades to view test_schema_1.abc_view
+NOTICE: drop cascades to rule _RETURN on view test_schema_1.abc_view
+NOTICE: drop cascades to table test_schema_1.abc
+-- verify that the objects were dropped
+SELECT COUNT(*) FROM pg_class WHERE relnamespace =
+ (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
+ count
+-------
+ 0
+(1 row)
+
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index a2e34d0f2ab..43a7bcff9ac 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -60,7 +60,7 @@ ignore: random
# ----------
# The fourth group of parallel test
# ----------
-test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update
+test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace
test: privileges
test: misc
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 5f3a7bba9a5..61ac9eff335 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -1,4 +1,4 @@
-# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.23 2003/11/29 19:52:14 pgsql Exp $
+# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.24 2004/01/11 04:58:17 neilc Exp $
# This should probably be in an order similar to parallel_schedule.
test: boolean
test: char
@@ -73,6 +73,7 @@ test: arrays
test: btree_index
test: hash_index
test: update
+test: namespace
test: privileges
test: misc
test: select_views
diff --git a/src/test/regress/sql/namespace.sql b/src/test/regress/sql/namespace.sql
new file mode 100644
index 00000000000..919f72ada2b
--- /dev/null
+++ b/src/test/regress/sql/namespace.sql
@@ -0,0 +1,31 @@
+--
+-- Regression tests for schemas (namespaces)
+--
+
+CREATE SCHEMA test_schema_1
+ CREATE UNIQUE INDEX abc_a_idx ON abc (a)
+
+ CREATE VIEW abc_view AS
+ SELECT a+1 AS a, b+1 AS b FROM abc
+
+ CREATE TABLE abc (
+ a serial,
+ b int UNIQUE
+ );
+
+-- verify that the objects were created
+SELECT COUNT(*) FROM pg_class WHERE relnamespace =
+ (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
+
+INSERT INTO test_schema_1.abc DEFAULT VALUES;
+INSERT INTO test_schema_1.abc DEFAULT VALUES;
+INSERT INTO test_schema_1.abc DEFAULT VALUES;
+
+SELECT * FROM test_schema_1.abc;
+SELECT * FROM test_schema_1.abc_view;
+
+DROP SCHEMA test_schema_1 CASCADE;
+
+-- verify that the objects were dropped
+SELECT COUNT(*) FROM pg_class WHERE relnamespace =
+ (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');