]> granicus.if.org Git - postgresql/commitdiff
Allow default expressions to be attached to columns of foreign tables.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 12 Mar 2013 21:37:07 +0000 (17:37 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 12 Mar 2013 21:37:07 +0000 (17:37 -0400)
There's still some discussion about exactly how postgres_fdw ought to
handle this case, but there seems no debate that we want to allow defaults
to be used for inserts into foreign tables.  So remove the core-code
restrictions that prevented it.

While at it, get rid of the special grammar productions for CREATE FOREIGN
TABLE, and instead add explicit FEATURE_NOT_SUPPORTED error checks for the
disallowed cases.  This makes the grammar a shade smaller, and more
importantly results in much more intelligible error messages for
unsupported cases.  It's also one less thing to fix if we ever start
supporting constraints on foreign tables.

doc/src/sgml/ref/alter_foreign_table.sgml
doc/src/sgml/ref/create_foreign_table.sgml
src/backend/commands/tablecmds.c
src/backend/parser/gram.y
src/backend/parser/parse_utilcmd.c
src/test/regress/expected/foreign_data.out
src/test/regress/sql/foreign_data.sql

index f0b3129ab090a285700a6f2750c990e40b5d4018..723aa075c5794c64bd00d3f2ae209935ddf49889 100644 (file)
@@ -32,9 +32,11 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
 
 <phrase>where <replaceable class="PARAMETER">action</replaceable> is one of:</phrase>
 
-    ADD [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ NULL | NOT NULL ]
+    ADD [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ COLLATE <replaceable class="PARAMETER">collation</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
     DROP [ COLUMN ] [ IF EXISTS ] <replaceable class="PARAMETER">column_name</replaceable> [ RESTRICT | CASCADE ]
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> [ SET DATA ] TYPE <replaceable class="PARAMETER">data_type</replaceable>
+    ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> SET DEFAULT <replaceable class="PARAMETER">expression</replaceable>
+    ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> DROP DEFAULT
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> { SET | DROP } NOT NULL
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
     ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> SET ( <replaceable class="PARAMETER">attribute_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
@@ -59,6 +61,9 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
      <para>
       This form adds a new column to the foreign table, using the same syntax as
       <xref linkend="SQL-CREATEFOREIGNTABLE">.
+      Unlike the case when adding a column to a regular table, nothing happens
+      to the underlying storage: this action simply declares that
+      some new column is now accessible through the foreign table.
      </para>
     </listitem>
    </varlistentry>
@@ -97,6 +102,18 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>SET</literal>/<literal>DROP DEFAULT</literal></term>
+    <listitem>
+     <para>
+      These forms set or remove the default value for a column.
+      Default values only apply in subsequent <command>INSERT</command>
+      or <command>UPDATE</> commands; they do not cause rows already in the
+      table to change.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><literal>SET</literal>/<literal>DROP NOT NULL</literal></term>
     <listitem>
index 0a6ac29d4d995c306b133d9c84ea9bdd40cab42f..1ef4b5e9d7427e1babad14a5c329e03c0bd6604a 100644 (file)
  <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 ] }
+    <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ] [ COLLATE <replaceable>collation</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
     [, ... ]
 ] )
   SERVER <replaceable class="parameter">server_name</replaceable>
 [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ]
 
+<phrase>where <replaceable class="PARAMETER">column_constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
+{ NOT NULL |
+  NULL |
+  DEFAULT <replaceable>default_expr</replaceable> }
 </synopsis>
  </refsynopsisdiv>
 
@@ -131,6 +137,27 @@ CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>DEFAULT
+    <replaceable>default_expr</replaceable></literal></term>
+    <listitem>
+     <para>
+      The <literal>DEFAULT</> clause assigns a default data value for
+      the column whose column definition it appears within.  The value
+      is any variable-free expression (subqueries and cross-references
+      to other columns in the current table are not allowed).  The
+      data type of the default expression must match the data type of the
+      column.
+     </para>
+
+     <para>
+      The default expression will be used in any insert operation that
+      does not specify a value for the column.  If there is no default
+      for a column, then the default is null.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><replaceable class="PARAMETER">server_name</replaceable></term>
     <listitem>
@@ -190,6 +217,8 @@ SERVER film_server;
    <acronym>SQL</acronym> standard; however, much as with
    <link linkend="sql-createtable"><command>CREATE TABLE</></link>,
    <literal>NULL</> constraints and zero-column foreign tables are permitted.
+   The ability to specify a default value is also a <productname>PostgreSQL</>
+   extension.
   </para>
 
  </refsect1>
index 47b6233a80d39204a51d45bf5b76b675dc0167f1..8bb8f54ae52d23f398e085872c4729dd013a5c78 100644 (file)
@@ -465,7 +465,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
        if (stmt->constraints != NIL && relkind == RELKIND_FOREIGN_TABLE)
                ereport(ERROR,
                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                                errmsg("constraints on foreign tables are not supported")));
+                                errmsg("constraints are not supported on foreign tables")));
 
        /*
         * Look up the namespace in which we are supposed to create the relation,
@@ -588,11 +588,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
                {
                        RawColumnDefault *rawEnt;
 
-                       if (relkind == RELKIND_FOREIGN_TABLE)
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                                                errmsg("default values on foreign tables are not supported")));
-
                        Assert(colDef->cooked_default == NULL);
 
                        rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
@@ -2978,7 +2973,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                         * substitutes default values into INSERTs before it expands
                         * rules.
                         */
-                       ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW);
+                       ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
                        /* No command-specific prep needed */
                        pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP;
@@ -4528,11 +4523,6 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
        {
                RawColumnDefault *rawEnt;
 
-               if (relkind == RELKIND_FOREIGN_TABLE)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                         errmsg("default values on foreign tables are not supported")));
-
                rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
                rawEnt->attnum = attribute.attnum;
                rawEnt->raw_default = copyObject(colDef->raw_default);
index 0787d2f5061c34b63d02b6601935175b839eefd1..9d07f30906c4bfeaa7625e6c0a3e54f343bf9d02 100644 (file)
@@ -330,7 +330,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <list>   stmtblock stmtmulti
                                OptTableElementList TableElementList OptInherit definition
                                OptTypedTableElementList TypedTableElementList
-                               OptForeignTableElementList ForeignTableElementList
                                reloptions opt_reloptions
                                OptWith opt_distinct opt_definition func_args func_args_list
                                func_args_with_defaults func_args_with_defaults_list
@@ -408,7 +407,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <vsetstmt> set_rest set_rest_more SetResetClause FunctionSetResetClause
 
 %type <node>   TableElement TypedTableElement ConstraintElem TableFuncElement
-                               ForeignTableElement
 %type <node>   columnDef columnOptions
 %type <defelt> def_elem reloption_elem old_aggr_elem
 %type <node>   def_arg columnElem where_clause where_or_current_clause
@@ -4137,57 +4135,37 @@ AlterForeignServerStmt: ALTER SERVER name foreign_server_version alter_generic_o
 
 CreateForeignTableStmt:
                CREATE FOREIGN TABLE qualified_name
-                       OptForeignTableElementList
+                       '(' OptTableElementList ')'
                        SERVER name create_generic_options
                                {
                                        CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
                                        $4->relpersistence = RELPERSISTENCE_PERMANENT;
                                        n->base.relation = $4;
-                                       n->base.tableElts = $5;
+                                       n->base.tableElts = $6;
                                        n->base.inhRelations = NIL;
                                        n->base.if_not_exists = false;
                                        /* FDW-specific data */
-                                       n->servername = $7;
-                                       n->options = $8;
+                                       n->servername = $9;
+                                       n->options = $10;
                                        $$ = (Node *) n;
                                }
                | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name
-                       OptForeignTableElementList
+                       '(' OptTableElementList ')'
                        SERVER name create_generic_options
                                {
                                        CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
                                        $7->relpersistence = RELPERSISTENCE_PERMANENT;
                                        n->base.relation = $7;
-                                       n->base.tableElts = $8;
+                                       n->base.tableElts = $9;
                                        n->base.inhRelations = NIL;
                                        n->base.if_not_exists = true;
                                        /* FDW-specific data */
-                                       n->servername = $10;
-                                       n->options = $11;
+                                       n->servername = $12;
+                                       n->options = $13;
                                        $$ = (Node *) n;
                                }
                ;
 
-OptForeignTableElementList:
-                       '(' ForeignTableElementList ')'                 { $$ = $2; }
-                       | '(' ')'                                                               { $$ = NIL; }
-               ;
-
-ForeignTableElementList:
-                       ForeignTableElement
-                               {
-                                       $$ = list_make1($1);
-                               }
-                       | ForeignTableElementList ',' ForeignTableElement
-                               {
-                                       $$ = lappend($1, $3);
-                               }
-               ;
-
-ForeignTableElement:
-                       columnDef                                       { $$ = $1; }
-               ;
-
 /*****************************************************************************
  *
  *             QUERY:
index 8a1876c8a39529c3fdbaf62b06e4091396b7979e..4fdcf180fa448aea97801b2418fcb31d835f3a3d 100644 (file)
@@ -70,6 +70,7 @@ typedef struct
        RangeVar   *relation;           /* relation to create */
        Relation        rel;                    /* opened/locked rel, if ALTER */
        List       *inhRelations;       /* relations to inherit from */
+       bool            isforeign;              /* true if CREATE/ALTER FOREIGN TABLE */
        bool            isalter;                /* true if altering existing table */
        bool            hasoids;                /* does relation have an OID column? */
        List       *columns;            /* ColumnDef items */
@@ -195,9 +196,15 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 
        cxt.pstate = pstate;
        if (IsA(stmt, CreateForeignTableStmt))
+       {
                cxt.stmtType = "CREATE FOREIGN TABLE";
+               cxt.isforeign = true;
+       }
        else
+       {
                cxt.stmtType = "CREATE TABLE";
+               cxt.isforeign = false;
+       }
        cxt.relation = stmt->relation;
        cxt.rel = NULL;
        cxt.inhRelations = stmt->inhRelations;
@@ -515,11 +522,23 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
                                break;
 
                        case CONSTR_CHECK:
+                               if (cxt->isforeign)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                        errmsg("constraints are not supported on foreign tables"),
+                                                        parser_errposition(cxt->pstate,
+                                                                                               constraint->location)));
                                cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
                                break;
 
                        case CONSTR_PRIMARY:
                        case CONSTR_UNIQUE:
+                               if (cxt->isforeign)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                        errmsg("constraints are not supported on foreign tables"),
+                                                        parser_errposition(cxt->pstate,
+                                                                                               constraint->location)));
                                if (constraint->keys == NIL)
                                        constraint->keys = list_make1(makeString(column->colname));
                                cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
@@ -531,7 +550,12 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
                                break;
 
                        case CONSTR_FOREIGN:
-
+                               if (cxt->isforeign)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                        errmsg("constraints are not supported on foreign tables"),
+                                                        parser_errposition(cxt->pstate,
+                                                                                               constraint->location)));
                                /*
                                 * Fill in the current attribute's name and throw it into the
                                 * list of FK constraints to be processed later.
@@ -555,8 +579,8 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
        }
 
        /*
-        * Generate ALTER FOREIGN TABLE ALTER COLUMN statement which adds
-        * per-column foreign data wrapper options for this column.
+        * If needed, generate ALTER FOREIGN TABLE ALTER COLUMN statement to add
+        * per-column foreign data wrapper options to this column after creation.
         */
        if (column->fdwoptions != NIL)
        {
@@ -587,6 +611,13 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 static void
 transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint)
 {
+       if (cxt->isforeign)
+               ereport(ERROR,
+                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                errmsg("constraints are not supported on foreign tables"),
+                                parser_errposition(cxt->pstate,
+                                                                       constraint->location)));
+
        switch (constraint->contype)
        {
                case CONSTR_PRIMARY:
@@ -640,7 +671,14 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
        char       *comment;
        ParseCallbackState pcbstate;
 
-       setup_parser_errposition_callback(&pcbstate, cxt->pstate, table_like_clause->relation->location);
+       setup_parser_errposition_callback(&pcbstate, cxt->pstate,
+                                                                         table_like_clause->relation->location);
+
+       /* we could support LIKE in many cases, but worry about it another day */
+       if (cxt->isforeign)
+               ereport(ERROR,
+                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                errmsg("LIKE is not supported for foreign tables")));
 
        relation = relation_openrv(table_like_clause->relation, AccessShareLock);
 
@@ -2334,7 +2372,16 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
        pstate->p_sourcetext = queryString;
 
        cxt.pstate = pstate;
-       cxt.stmtType = "ALTER TABLE";
+       if (stmt->relkind == OBJECT_FOREIGN_TABLE)
+       {
+               cxt.stmtType = "ALTER FOREIGN TABLE";
+               cxt.isforeign = true;
+       }
+       else
+       {
+               cxt.stmtType = "ALTER TABLE";
+               cxt.isforeign = false;
+       }
        cxt.relation = stmt->relation;
        cxt.rel = rel;
        cxt.inhRelations = NIL;
index 1bfdca134bb6d9ab05628c169b035cca77658f45..60506e07b1c94fcfb6e9ab8adb6f016b4a84b7f2 100644 (file)
@@ -664,8 +664,6 @@ LINE 1: CREATE FOREIGN TABLE ft1 ();
                                    ^
 CREATE FOREIGN TABLE ft1 () SERVER no_server;                   -- ERROR
 ERROR:  server "no_server" does not exist
-CREATE FOREIGN TABLE ft1 (c1 serial) SERVER sc;                 -- ERROR
-ERROR:  default values on foreign tables are not supported
 CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS;                -- ERROR
 ERROR:  syntax error at or near "WITH OIDS"
 LINE 1: CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS;
@@ -707,17 +705,14 @@ COMMENT ON FOREIGN TABLE ft1 IS NULL;
 COMMENT ON COLUMN ft1.c1 IS 'foreign column';
 COMMENT ON COLUMN ft1.c1 IS NULL;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c4 integer;
-ALTER FOREIGN TABLE ft1 ADD COLUMN c5 integer DEFAULT 0;        -- ERROR
-ERROR:  default values on foreign tables are not supported
+ALTER FOREIGN TABLE ft1 ADD COLUMN c5 integer DEFAULT 0;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c6 integer;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c7 integer NOT NULL;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c9 integer;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1');
-ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0;          -- ERROR
-ERROR:  "ft1" is not a table or view
-ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT;           -- ERROR
-ERROR:  "ft1" is not a table or view
+ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0;
+ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT;
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c6 SET NOT NULL;
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 DROP NOT NULL;
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) USING '0'; -- ERROR
@@ -739,7 +734,8 @@ ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STATISTICS -1;
  c1     | integer | not null  | ("param 1" 'val1')             | plain    | 10000        | 
  c2     | text    |           | (param2 'val2', param3 'val3') | extended |              | 
  c3     | date    |           |                                | plain    |              | 
- c4     | integer |           |                                | plain    |              | 
+ c4     | integer | default 0 |                                | plain    |              | 
+ c5     | integer |           |                                | plain    |              | 
  c6     | integer | not null  |                                | plain    |              | 
  c7     | integer |           | (p1 'v1', p2 'v2')             | plain    |              | 
  c8     | text    |           | (p2 'V2')                      | extended |              | 
@@ -755,7 +751,9 @@ ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET DATA TYPE integer;      -- ERROR
 ERROR:  cannot alter foreign table "ft1" because column "use_ft1_column_type.x" uses its row type
 DROP TABLE use_ft1_column_type;
 ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c9_check CHECK (c9 < 0); -- ERROR
-ERROR:  "ft1" is not a table
+ERROR:  constraints are not supported on foreign tables
+LINE 1: ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c9_check CHECK (c...
+                                    ^
 ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const;               -- ERROR
 ERROR:  "ft1" is not a table
 ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const;
@@ -783,7 +781,8 @@ ALTER FOREIGN TABLE foreign_schema.ft1 RENAME TO foreign_table_1;
  foreign_column_1 | integer | not null  | ("param 1" 'val1')
  c2               | text    |           | (param2 'val2', param3 'val3')
  c3               | date    |           | 
- c4               | integer |           | 
+ c4               | integer | default 0 | 
+ c5               | integer |           | 
  c6               | integer | not null  | 
  c7               | integer |           | (p1 'v1', p2 'v2')
  c8               | text    |           | (p2 'V2')
index 38057db7b449e0c9d4ecb81b3ec7c63b56d981e3..f819eb1b8eb3c9eed49533fd1c287b57fe8632d1 100644 (file)
@@ -267,7 +267,6 @@ CREATE SCHEMA foreign_schema;
 CREATE SERVER s0 FOREIGN DATA WRAPPER dummy;
 CREATE FOREIGN TABLE ft1 ();                                    -- ERROR
 CREATE FOREIGN TABLE ft1 () SERVER no_server;                   -- ERROR
-CREATE FOREIGN TABLE ft1 (c1 serial) SERVER sc;                 -- ERROR
 CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS;                -- ERROR
 CREATE FOREIGN TABLE ft1 (
        c1 integer OPTIONS ("param 1" 'val1') NOT NULL,
@@ -289,15 +288,15 @@ COMMENT ON COLUMN ft1.c1 IS 'foreign column';
 COMMENT ON COLUMN ft1.c1 IS NULL;
 
 ALTER FOREIGN TABLE ft1 ADD COLUMN c4 integer;
-ALTER FOREIGN TABLE ft1 ADD COLUMN c5 integer DEFAULT 0;        -- ERROR
+ALTER FOREIGN TABLE ft1 ADD COLUMN c5 integer DEFAULT 0;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c6 integer;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c7 integer NOT NULL;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c9 integer;
 ALTER FOREIGN TABLE ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1');
 
-ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0;          -- ERROR
-ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT;           -- ERROR
+ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0;
+ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT;
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c6 SET NOT NULL;
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 DROP NOT NULL;
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) USING '0'; -- ERROR