mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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