*
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.170 2010/08/13 20:10:51 rhaas Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.171 2010/08/18 18:35:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
    stmt->tablespacename = NULL;
    stmt->if_not_exists = false;
 
-   seqoid = DefineRelation(stmt, RELKIND_SEQUENCE);
+   seqoid = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId);
    Assert(seqoid != InvalidOid);
 
    rel = heap_open(seqoid, AccessExclusiveLock);
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.340 2010/08/13 20:10:51 rhaas Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.341 2010/08/18 18:35:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
  *     DefineRelation
  *             Creates a new relation.
  *
+ * stmt carries parsetree information from an ordinary CREATE TABLE statement.
+ * The other arguments are used to extend the behavior for other cases:
+ * relkind: relkind to assign to the new relation
+ * ownerId: if not InvalidOid, use this as the new relation's owner.
+ *
+ * Note that permissions checks are done against current user regardless of
+ * ownerId.  A nonzero ownerId is used when someone is creating a relation
+ * "on behalf of" someone else, so we still want to see that the current user
+ * has permissions to do it.
+ *
  * If successful, returns the OID of the new relation.
  * ----------------------------------------------------------------
  */
 Oid
-DefineRelation(CreateStmt *stmt, char relkind)
+DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 {
    char        relname[NAMEDATALEN];
    Oid         namespaceId;
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("only shared relations can be placed in pg_global tablespace")));
 
+   /* Identify user ID that will own the table */
+   if (!OidIsValid(ownerId))
+       ownerId = GetUserId();
+
    /*
     * Parse and validate reloptions, if any.
     */
                                          InvalidOid,
                                          InvalidOid,
                                          ofTypeId,
-                                         GetUserId(),
+                                         ownerId,
                                          descriptor,
                                          list_concat(cookedDefaults,
                                                      old_constraints),
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.150 2010/07/28 05:22:24 sriggs Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.151 2010/08/18 18:35:19 tgl Exp $
  *
  * DESCRIPTION
  *   The "DefineFoo" routines take the parse tree and pick out the
    /*
     * Finally create the relation.  This also creates the type.
     */
-   relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE);
+   relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE, InvalidOid);
    Assert(relid != InvalidOid);
    return relid;
 }
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.121 2010/07/25 23:21:21 rhaas Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.122 2010/08/18 18:35:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
         * existing view, so we don't need more code to complain if "replace"
         * is false).
         */
-       relid = DefineRelation(createStmt, RELKIND_VIEW);
+       relid = DefineRelation(createStmt, RELKIND_VIEW, InvalidOid);
        Assert(relid != InvalidOid);
        return relid;
    }
 
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.468 2010/08/18 15:21:54 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.469 2010/08/18 18:35:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
    COPY_NODE_FIELD(sequence);
    COPY_NODE_FIELD(options);
+   COPY_SCALAR_FIELD(ownerId);
 
    return newnode;
 }
 
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.387 2010/08/07 02:44:06 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.388 2010/08/18 18:35:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 {
    COMPARE_NODE_FIELD(sequence);
    COMPARE_NODE_FIELD(options);
+   COMPARE_SCALAR_FIELD(ownerId);
 
    return true;
 }
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.715 2010/08/05 04:21:53 petere Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.716 2010/08/18 18:35:20 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
                    $4->istemp = $2;
                    n->sequence = $4;
                    n->options = $5;
+                   n->ownerId = InvalidOid;
                    $$ = (Node *)n;
                }
        ;
 
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.42 2010/08/05 15:25:35 rhaas Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.43 2010/08/18 18:35:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
        seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
        seqstmt->options = NIL;
 
+       /*
+        * If this is ALTER ADD COLUMN, make sure the sequence will be owned
+        * by the table's owner.  The current user might be someone else
+        * (perhaps a superuser, or someone who's only a member of the owning
+        * role), but the SEQUENCE OWNED BY mechanisms will bleat unless
+        * table and sequence have exactly the same owning role.
+        */
+       if (cxt->rel)
+           seqstmt->ownerId = cxt->rel->rd_rel->relowner;
+       else
+           seqstmt->ownerId = InvalidOid;
+
        cxt->blist = lappend(cxt->blist, seqstmt);
 
        /*
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.336 2010/07/25 23:21:22 rhaas Exp $
+ *   $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.337 2010/08/18 18:35:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
                        /* Create the table itself */
                        relOid = DefineRelation((CreateStmt *) stmt,
-                                               RELKIND_RELATION);
+                                               RELKIND_RELATION,
+                                               InvalidOid);
 
                        /*
                         * If "IF NOT EXISTS" was specified and the relation
 
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/tablecmds.h,v 1.47 2010/07/28 05:22:24 sriggs Exp $
+ * $PostgreSQL: pgsql/src/include/commands/tablecmds.h,v 1.48 2010/08/18 18:35:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "utils/relcache.h"
 
 
-extern Oid DefineRelation(CreateStmt *stmt, char relkind);
+extern Oid DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId);
 
 extern void RemoveRelations(DropStmt *drop);
 
 
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.434 2010/08/07 02:44:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.435 2010/08/18 18:35:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
    NodeTag     type;
    RangeVar   *sequence;       /* the sequence to create */
    List       *options;
+   Oid         ownerId;        /* ID of owner, or InvalidOid for default */
 } CreateSeqStmt;
 
 typedef struct AlterSeqStmt