This patch adds a few additional commands to the list of expressions
accepted by CREATE SCHEMA: CREATE INDEX, CREATE SEQUENCE, and CREATE
TRIGGER are now supported. The latter two are required by SQL 200x,
while the first is merely useful.

Unless anyone objects, I intend to apply this patch by the end of the
week (I might add a few more commands to the set of allowed
expressions first).

-Neil
Index: doc/src/sgml/ref/create_schema.sgml
===================================================================
RCS file: /var/lib/cvs/pgsql-server/doc/src/sgml/ref/create_schema.sgml,v
retrieving revision 1.9
diff -c -r1.9 create_schema.sgml
*** doc/src/sgml/ref/create_schema.sgml	29 Nov 2003 19:51:38 -0000	1.9
--- doc/src/sgml/ref/create_schema.sgml	5 Jan 2004 21:14:36 -0000
***************
*** 84,94 ****
        <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.
         </para>
        </listitem>
       </varlistentry>
--- 84,96 ----
        <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</>, <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>
Index: src/backend/parser/analyze.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/parser/analyze.c,v
retrieving revision 1.292
diff -c -r1.292 analyze.c
*** src/backend/parser/analyze.c	29 Nov 2003 19:51:51 -0000	1.292
--- src/backend/parser/analyze.c	5 Jan 2004 21:15:42 -0000
***************
*** 53,60 ****
--- 53,63 ----
  	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 */
***************
*** 3126,3138 ****
  	ReleaseSysCache(ctype);
  }
  
  /*
   * 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).
   *
   * SQL92 also allows constraints to make forward references, so thumb through
   * the table columns and move forward references to a posterior alter-table
--- 3129,3156 ----
  	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). 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
***************
*** 3142,3148 ****
   * 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
   */
  List *
  analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
--- 3160,3166 ----
   * 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/schemacmds.c
   */
  List *
  analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
***************
*** 3154,3162 ****
--- 3172,3183 ----
  	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;
***************
*** 3172,3194 ****
  
  		switch (nodeTag(element))
  		{
  			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)));
  
  					/*
  					 * XXX todo: deal with constraints
  					 */
- 
  					cxt.tables = lappend(cxt.tables, element);
  				}
  				break;
--- 3193,3216 ----
  
  		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;
  
! 					setSchemaName(cxt.schemaname, &elp->relation->schemaname);
  
  					/*
  					 * XXX todo: deal with constraints
  					 */
  					cxt.tables = lappend(cxt.tables, element);
  				}
  				break;
***************
*** 3197,3219 ****
  				{
  					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)));
  
  					/*
  					 * XXX todo: deal with references between views
  					 */
- 
  					cxt.views = lappend(cxt.views, element);
  				}
  				break;
  
  			case T_GrantStmt:
  				cxt.grants = lappend(cxt.grants, element);
  				break;
--- 3219,3251 ----
  				{
  					ViewStmt   *elp = (ViewStmt *) element;
  
! 					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;
***************
*** 3225,3232 ****
--- 3257,3267 ----
  	}
  
  	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;
Index: src/backend/parser/gram.y
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/parser/gram.y,v
retrieving revision 2.441
diff -c -r2.441 gram.y
*** src/backend/parser/gram.y	1 Dec 2003 22:07:58 -0000	2.441
--- src/backend/parser/gram.y	5 Jan 2004 21:14:36 -0000
***************
*** 811,816 ****
--- 811,819 ----
   */
  schema_stmt:
  			CreateStmt
+ 			| IndexStmt
+ 			| CreateSeqStmt
+ 			| CreateTrigStmt
  			| GrantStmt
  			| ViewStmt
  		;
---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
      joining column's datatypes do not match

Reply via email to