Commit e97b8f2d authored by Neil Conway's avatar Neil Conway

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.
parent 4cdf51e6
<!--
$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>
......
......@@ -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;
......
......@@ -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
;
......
--
-- 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)
......@@ -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
......
# $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
......
--
-- 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');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment