? src/backend/commands/.typecmds.c.swp Index: doc/src/sgml/ref/alter_domain.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/ref/alter_domain.sgml,v retrieving revision 1.6 diff -c -r1.6 alter_domain.sgml *** doc/src/sgml/ref/alter_domain.sgml 2002/12/06 16:40:13 1.6 --- doc/src/sgml/ref/alter_domain.sgml 2002/12/09 02:00:12 *************** *** 29,34 **** --- 29,36 ---- ADD domain_constraint ALTER DOMAIN domain DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ] + ALTER DOMAIN domain + OWNER TO new_owner *************** *** 70,75 **** --- 72,86 ---- + new_owner + + + The user name of the new owner of the domain. + + + + + CASCADE *************** *** 179,189 **** ! You must own the domain to use ALTER DOMAIN; except for ! ALTER TABLE OWNER, which may only be executed by a superuser. --- 190,208 ---- + + OWNER + + + This form changes the owner of the domain to the specified user. + + + ! You must own the domain or the schema the domain is in, in order ! to use ALTER DOMAIN. Index: src/backend/commands/typecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/commands/typecmds.c,v retrieving revision 1.20 diff -c -r1.20 typecmds.c *** src/backend/commands/typecmds.c 2002/12/06 05:00:11 1.20 --- src/backend/commands/typecmds.c 2002/12/09 02:00:46 *************** *** 1664,1666 **** --- 1664,1744 ---- break; } } + + /* + * ALTER DOMAIN .. OWNER TO + * + * Currently only useful for domains as I'm unsure of the + * consequences of allowing owner changes of the other types. + */ + void + AlterTypeOwner(List *names, int32 newOwnerSysId) + { + TypeName *typename; + Oid typeOid; + HeapTuple tup; + Relation rel; + Datum new_record[Natts_pg_type]; + char new_record_nulls[Natts_pg_type]; + char new_record_repl[Natts_pg_type]; + HeapTuple newtuple; + 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 removed. */ + 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); + + /* Permission check: must be a superuser or own the namespace */ + if (!pg_namespace_ownercheck(typTup->typnamespace, + GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, TypeNameToString(typename)); + + /* Check that this is actually a domain */ + if (typTup->typtype != 'd') + elog(ERROR, "%s is not a domain", + TypeNameToString(typename)); + + + /* Modify the owner of the domain */ + typTup->typowner = newOwnerSysId; + + /* Setup new tuple */ + MemSet(new_record, (Datum) 0, sizeof(new_record)); + MemSet(new_record_nulls, ' ', sizeof(new_record_nulls)); + MemSet(new_record_repl, ' ', sizeof(new_record_repl)); + + new_record[Anum_pg_type_typowner - 1] = Int32GetDatum(newOwnerSysId); + new_record_repl[Anum_pg_type_typowner - 1] = 'r'; + + /* Build the new tuple */ + newtuple = heap_modifytuple(tup, rel, + new_record, new_record_nulls, new_record_repl); + + simple_heap_update(rel, &tup->t_self, newtuple); + + CatalogUpdateIndexes(rel, newtuple); + + /* Clean up */ + heap_close(rel, NoLock); + } Index: src/backend/parser/gram.y =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/parser/gram.y,v retrieving revision 2.386 diff -c -r2.386 gram.y *** src/backend/parser/gram.y 2002/12/06 05:00:22 2.386 --- src/backend/parser/gram.y 2002/12/09 02:02:55 *************** *** 3775,3780 **** --- 3775,3789 ---- 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: src/backend/tcop/utility.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/tcop/utility.c,v retrieving revision 1.185 diff -c -r1.185 utility.c *** src/backend/tcop/utility.c 2002/12/06 05:00:31 1.185 --- src/backend/tcop/utility.c 2002/12/09 02:03:11 *************** *** 597,602 **** --- 597,606 ---- stmt->name, stmt->behavior); break; + case 'U': /* OWNER TO */ + AlterTypeOwner(stmt->typename, + get_usesysid(stmt->name)); + break; default: /* oops */ elog(ERROR, "T_AlterDomainStmt: unknown subtype"); break; Index: src/include/commands/typecmds.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/commands/typecmds.h,v retrieving revision 1.1 diff -c -r1.1 typecmds.h *** src/include/commands/typecmds.h 2002/12/06 05:00:31 1.1 --- src/include/commands/typecmds.h 2002/12/09 02:03:29 *************** *** 27,30 **** --- 27,32 ---- extern void AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior); + extern void AlterTypeOwner(List *names, int32 newOwnerSysId); + #endif /* TYPECMDS_H */