summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Conway2004-01-11 04:58:17 +0000
committerNeil Conway2004-01-11 04:58:17 +0000
commite97b8f2da9ee93f3f957bf5bc92b07f5d9e1e1dd (patch)
tree1b48f8067214786c9e7d163d6ff7f0ddc4d33d95
parent4cdf51e64627823088a3f94d21bafbb5fc87f9ea (diff)
Add CREATE TRIGGER, CREATE INDEX, and CREATE SEQUENCE to the list of
expressions supported by CREATE SCHEMA. Also added the beginning of some regression tests for CREATE SCHEMA; plenty more work is needed here.
-rw-r--r--doc/src/sgml/ref/create_schema.sgml14
-rw-r--r--src/backend/parser/analyze.c79
-rw-r--r--src/backend/parser/gram.y5
-rw-r--r--src/test/regress/expected/namespace.out52
-rw-r--r--src/test/regress/parallel_schedule2
-rw-r--r--src/test/regress/serial_schedule3
-rw-r--r--src/test/regress/sql/namespace.sql31
7 files changed, 155 insertions, 31 deletions
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 @@
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_schema.sgml,v 1.9 2003/11/29 19:51:38 pgsql Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_schema.sgml,v 1.10 2004/01/11 04:58:17 neilc Exp $
PostgreSQL documentation
-->
@@ -84,11 +84,13 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable
<term><replaceable class="parameter">schema_element</replaceable></term>
<listitem>
<para>
- An SQL statement defining an object to be created within the schema.
- Currently, only <command>CREATE TABLE</>, <command>CREATE VIEW</>,
- and <command>GRANT</> are accepted as clauses within
- <command>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 <command>CREATE
+ TABLE</>, <command>CREATE VIEW</>, <command>CREATE
+ INDEX</>, <command>CREATE SEQUENCE</>, <command>CREATE
+ TRIGGER</> and <command>GRANT</> are accepted as clauses
+ within <command>CREATE SCHEMA</>. Other kinds of objects may
+ be created in separate commands after the schema is created.
</para>
</listitem>
</varlistentry>
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');