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

Reply via email to