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