On Thu, Mar 15, 2012 at 11:23:43AM -0300, Alvaro Herrera wrote: > Excerpts from David Fetter's message of jue mar 15 02:28:28 -0300 2012: > > On Wed, Mar 14, 2012 at 12:06:20PM -0400, Robert Haas wrote: > > > On Wed, Mar 14, 2012 at 10:22 AM, David Fetter <da...@fetter.org> wrote: > > > >> I think that instead of inventing new grammar productions and a new > > > >> node type for this, you should just reuse the existing productions for > > > >> LIKE clauses and then reject invalid options during parse analysis. > > > > > > > > OK. Should I first merge CREATE FOREIGN TABLE with CREATE TABLE and > > > > submit that as a separate patch? > > > > > > I don't see any reason to do that. I merely meant that you could > > > reuse TableLikeClause or maybe even TableElement in the grammer for > > > CreateForeignTableStmt. > > > > Next WIP patch attached implementing this via reusing TableLikeClause > > and refactoring transformTableLikeClause(). > > > > What say? > > Looks much better to me, but the use of strcmp() doesn't look good. > ISTM that stmtType is mostly used for error messages. I think you > should add some kind of identifier (such as the original parser Node) > into the CreateStmtContext so that you can do a IsA() test instead -- a > bit more invasive as a patch, but much cleaner. > > Also the error messages need more work.
How about this one? Cheers, David. -- David Fetter <da...@fetter.org> http://fetter.org/ Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter Skype: davidfetter XMPP: david.fet...@gmail.com iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics Remember to vote! Consider donating to Postgres: http://www.postgresql.org/about/donate
*** a/doc/src/sgml/ref/create_foreign_table.sgml --- b/doc/src/sgml/ref/create_foreign_table.sgml *************** *** 19,26 **** <refsynopsisdiv> <synopsis> CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> ( [ ! { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ] [ NULL | NOT NULL ] } ! [, ... ] ] ) SERVER <replaceable class="parameter">server_name</replaceable> [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ] --- 19,26 ---- <refsynopsisdiv> <synopsis> CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> ( [ ! { { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ NULL | NOT NULL ] | LIKE <replaceable>source_table</replaceable> } [, ... ] ! [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ] } ] ) SERVER <replaceable class="parameter">server_name</replaceable> [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ] *** a/src/backend/parser/gram.y --- b/src/backend/parser/gram.y *************** *** 3945,3950 **** ForeignTableElementList: --- 3945,3951 ---- ForeignTableElement: columnDef { $$ = $1; } + | TableLikeClause { $$ = $1; } ; /***************************************************************************** *** a/src/backend/parser/parse_utilcmd.c --- b/src/backend/parser/parse_utilcmd.c *************** *** 66,71 **** typedef struct --- 66,72 ---- { ParseState *pstate; /* overall parser state */ const char *stmtType; /* "CREATE [FOREIGN] TABLE" or "ALTER TABLE" */ + char relkind; /* r = ordinary table, f = foreign table, cf. pg_catalog.pg_class */ RangeVar *relation; /* relation to create */ Relation rel; /* opened/locked rel, if ALTER */ List *inhRelations; /* relations to inherit from */ *************** *** 194,202 **** transformCreateStmt(CreateStmt *stmt, const char *queryString) --- 195,209 ---- cxt.pstate = pstate; if (IsA(stmt, CreateForeignTableStmt)) + { cxt.stmtType = "CREATE FOREIGN TABLE"; + cxt.relkind = 'f'; + } else + { cxt.stmtType = "CREATE TABLE"; + cxt.relkind = 'r'; + } cxt.relation = stmt->relation; cxt.rel = NULL; cxt.inhRelations = stmt->inhRelations; *************** *** 623,629 **** transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint) /* * transformTableLikeClause * ! * Change the LIKE <srctable> portion of a CREATE TABLE statement into * column definitions which recreate the user defined column portions of * <srctable>. */ --- 630,636 ---- /* * transformTableLikeClause * ! * Change the LIKE <srctable> portion of a CREATE [FOREIGN] TABLE statement into * column definitions which recreate the user defined column portions of * <srctable>. */ *************** *** 652,657 **** transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla --- 659,683 ---- table_like_clause->relation->relname))); cancel_parser_errposition_callback(&pcbstate); + + /* + * For foreign tables, disallow some options. + */ + if (cxt->relkind == 'f') + { + if (table_like_clause->options & CREATE_TABLE_LIKE_CONSTRAINTS) + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ERROR: foreign tables do not support LIKE INCLUDING CONSTRAINTS"))); + } + else if (table_like_clause->options & CREATE_TABLE_LIKE_INDEXES) + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ERROR: foreign tables do not support LIKE INCLUDING INDEXES"))); + } + } /* * Check for privileges
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers