ALTER DOMAIN OWNER, from Rod Taylor.
authorTom Lane
Mon, 6 Jan 2003 00:31:45 +0000 (00:31 +0000)
committerTom Lane
Mon, 6 Jan 2003 00:31:45 +0000 (00:31 +0000)
doc/src/sgml/ref/alter_domain.sgml
src/backend/commands/typecmds.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/commands/typecmds.h
src/include/nodes/parsenodes.h

index 4735d4240590acc2a1dc18baa86b9b9b703af97c..fdbf08e6d484aa3ee05086572a4cbb802803cce2 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -29,6 +29,8 @@ ALTER DOMAIN domain
     ADD domain_constraint
 ALTER DOMAIN domain
     DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]
+ALTER DOMAIN domain
+    OWNER TO new_owner 
   
 
   
@@ -73,7 +75,7 @@ ALTER DOMAIN domain
       CASCADE
       
        
-        Automatically drop objects that depend constraint.
+        Automatically drop objects that depend on the constraint.
        
       
      
@@ -88,6 +90,15 @@ ALTER DOMAIN domain
       
      
 
+     
+      new_owner
+      
+       
+   The user name of the new owner of the domain.
+       
+      
+     
+
     
    
   
@@ -141,9 +152,9 @@ ALTER DOMAIN domain
     SET/DROP DEFAULT
     
      
-      These forms set or remove the default value for a column. Note
+      These forms set or remove the default value for a domain. Note
       that defaults only apply to subsequent INSERT
-      commands; they do not cause rows already in a table using the domain.
+      commands; they do not affect rows already in a table using the domain.
      
     
    
@@ -154,8 +165,7 @@ ALTER DOMAIN domain
      
       These forms change whether a domain is marked to allow NULL
       values or to reject NULL values.  You may only SET NOT NULL
-      when the tables using the domain contain no null values in the domain
-      based column.
+      when the columns using the domain contain no null values.
      
     
    
@@ -164,8 +174,10 @@ ALTER DOMAIN domain
     ADD domain_constraint
     
      
-      This form adds a new constraint to a table using the same syntax as
-      
+      This form adds a new constraint to a domain using the same syntax as
+      .
+      This will only succeed if all columns using the domain satisfy the
+      new constraint.
      
     
    
@@ -179,11 +191,19 @@ ALTER DOMAIN domain
     
    
 
+   
+    OWNER
+    
+     
+      This form changes the owner of the domain to the specified user.
+     
+    
+   
   
 
   
    You must own the domain to use ALTER DOMAIN; except for
-   ALTER TABLE OWNER, which may only be executed by a superuser.
+   ALTER DOMAIN OWNER, which may only be executed by a superuser.
   
  
 
index 33f2fa7c2bfaffa78caa11f81c9aec89f77f4b9b..bd29033c729b6c859fb8ea7512f04b73e360eb6b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.26 2003/01/04 00:46:08 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.27 2003/01/06 00:31:44 tgl Exp $
  *
  * DESCRIPTION
  *   The "DefineFoo" routines take the parse tree and pick out the
@@ -1673,3 +1673,61 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
     */
    return ccbin;
 }
+
+/*
+ * ALTER DOMAIN .. OWNER TO
+ *
+ * Eventually this should allow changing ownership of other kinds of types,
+ * but some thought must be given to handling complex types.  (A table's
+ * rowtype probably shouldn't be allowed as target, but what of a standalone
+ * composite type?)
+ *
+ * Assumes that permission checks have been completed earlier.
+ */
+void
+AlterTypeOwner(List *names, AclId newOwnerSysId)
+{
+   TypeName   *typename;
+   Oid         typeOid;
+   Relation    rel;
+   HeapTuple   tup;
+   Form_pg_type    typTup;
+
+   /* Make a TypeName so we can use standard type lookup machinery */
+   typename = makeNode(TypeName);
+   typename->names = names;
+   typename->typmod = -1;
+   typename->arrayBounds = NIL;
+
+   /* Lock the type table */
+   rel = heap_openr(TypeRelationName, RowExclusiveLock);
+
+   /* Use LookupTypeName here so that shell types can be processed (why?) */
+   typeOid = LookupTypeName(typename);
+   if (!OidIsValid(typeOid))
+       elog(ERROR, "Type \"%s\" does not exist",
+            TypeNameToString(typename));
+
+   tup = SearchSysCacheCopy(TYPEOID,
+                            ObjectIdGetDatum(typeOid),
+                            0, 0, 0);
+   if (!HeapTupleIsValid(tup))
+       elog(ERROR, "AlterDomain: type \"%s\" does not exist",
+            TypeNameToString(typename));
+   typTup = (Form_pg_type) GETSTRUCT(tup);
+
+   /* Check that this is actually a domain */
+   if (typTup->typtype != 'd')
+       elog(ERROR, "%s is not a domain",
+            TypeNameToString(typename));
+
+   /* Modify the owner --- okay to scribble on typTup because it's a copy */
+   typTup->typowner = newOwnerSysId;
+
+   simple_heap_update(rel, &tup->t_self, tup);
+
+   CatalogUpdateIndexes(rel, tup);
+
+   /* Clean up */
+   heap_close(rel, RowExclusiveLock);
+}
index c19673fc42287e51b2646e69a9592a6f10ac8983..921099b79267768871a172d4aef9a8b3723ef054 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.389 2002/12/30 15:31:47 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.390 2003/01/06 00:31:44 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -3764,6 +3764,15 @@ AlterDomainStmt:
                    n->behavior = $7;
                    $$ = (Node *)n;
                }
+           /* ALTER DOMAIN  OWNER TO UserId */
+           | ALTER DOMAIN_P any_name OWNER TO UserId
+               {
+                   AlterDomainStmt *n = makeNode(AlterDomainStmt);
+                   n->subtype = 'U';
+                   n->typename = $3;
+                   n->name = $6;
+                   $$ = (Node *)n;
+               }
            ;
 
 opt_as:        AS                                      {}
index 962c5311500d791c0aac23e17be3fe26ff68eb5b..68c02c5f62d6a36aaf8d438a1736fcd8b7370ec7 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.187 2002/12/30 18:42:16 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.188 2003/01/06 00:31:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -439,11 +439,11 @@ ProcessUtility(Node *parsetree,
                                   stmt->newname);      /* new att name */
                        break;
                    case RENAME_RULE:
-                       elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d",
+                       elog(ERROR, "ProcessUtility: Invalid type for RENAME: %d",
                             stmt->renameType);
                        break;
                    default:
-                       elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d",
+                       elog(ERROR, "ProcessUtility: Invalid type for RENAME: %d",
                             stmt->renameType);
                }
            }
@@ -553,7 +553,8 @@ ProcessUtility(Node *parsetree,
                                        get_usesysid(stmt->name));
                        break;
                    default:    /* oops */
-                       elog(ERROR, "T_AlterTableStmt: unknown subtype");
+                       elog(ERROR, "ProcessUtility: Invalid type for AlterTableStmt: %d",
+                            stmt->subtype);
                        break;
                }
            }
@@ -595,8 +596,17 @@ ProcessUtility(Node *parsetree,
                                                  stmt->name,
                                                  stmt->behavior);
                        break;
+                   case 'U':   /* OWNER TO */
+                       /* check that we are the superuser */
+                       if (!superuser())
+                           elog(ERROR, "ALTER DOMAIN: permission denied");
+                       /* get_usesysid raises an error if no such user */
+                       AlterTypeOwner(stmt->typename,
+                                      get_usesysid(stmt->name));
+                       break;
                    default:    /* oops */
-                       elog(ERROR, "T_AlterDomainStmt: unknown subtype");
+                       elog(ERROR, "ProcessUtility: Invalid type for AlterDomainStmt: %d",
+                            stmt->subtype);
                        break;
                }
            }
index 2757d54276dcb54752e7616f856b4115186910dd..8f21aef7f4160ab8b80092a095c4ecf40130a127 100644 (file)
@@ -7,15 +7,17 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: typecmds.h,v 1.2 2002/12/10 16:12:53 tgl Exp $
+ * $Id: typecmds.h,v 1.3 2003/01/06 00:31:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #ifndef TYPECMDS_H
 #define TYPECMDS_H
 
+#include "miscadmin.h"
 #include "nodes/parsenodes.h"
 
+
 #define DEFAULT_TYPDELIM       ','
 
 extern void DefineType(List *names, List *parameters);
@@ -31,4 +33,6 @@ extern void AlterDomainAddConstraint(List *names, Node *constr);
 extern void AlterDomainDropConstraint(List *names, const char *constrName,
                                      DropBehavior behavior);
 
+extern void AlterTypeOwner(List *names, AclId newOwnerSysId);
+
 #endif   /* TYPECMDS_H */
index 0f9b7613a007cef63c5728710164be38c48f31e2..6ca3894b0daf0fcec3628cbd7689e09fa53854e9 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.224 2002/12/30 15:31:51 momjian Exp $
+ * $Id: parsenodes.h,v 1.225 2003/01/06 00:31:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -711,7 +711,7 @@ typedef struct AlterTableStmt
  * Alter Domain
  *
  * The fields are used in different ways by the different variants of
- * this command. Subtypes should match AlterTable subtypes
+ * this command. Subtypes should match AlterTable subtypes where possible.
  * ----------------------
  */
 typedef struct AlterDomainStmt