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.
This commit is contained in:
parent
4cdf51e646
commit
e97b8f2da9
@ -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>
|
||||
|
@ -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
|
||||
;
|
||||
|
52
src/test/regress/expected/namespace.out
Normal file
52
src/test/regress/expected/namespace.out
Normal file
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
31
src/test/regress/sql/namespace.sql
Normal file
31
src/test/regress/sql/namespace.sql
Normal file
@ -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');
|
Loading…
x
Reference in New Issue
Block a user