diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-08-04 01:09:29 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-08-04 01:09:29 +0000 |
commit | 33f5bf97009811d7f6b5408e37c6ad68110985b0 (patch) | |
tree | af599eafaa4b01a044de0e8e98f5eb16bbcd19aa /src/backend/commands/typecmds.c | |
parent | e48b28b688c9dd1ad2d74fcfeed7d76fe63d0047 (diff) | |
download | postgresql-33f5bf97009811d7f6b5408e37c6ad68110985b0.tar.gz postgresql-33f5bf97009811d7f6b5408e37c6ad68110985b0.zip |
ALTER TABLE OWNER must change the ownership of the table's rowtype too.
This was not especially critical before, but it is now that we track
ownership dependencies --- the dependency for the rowtype *must* shift
to the new owner. Spotted by Bernd Helmle.
Also fix a problem introduced by recent change to allow non-superusers
to do ALTER OWNER in some cases: if the table had a toast table, ALTER
OWNER failed *even for superusers*, because the test being applied would
conclude that the new would-be owner had no create rights on pg_toast.
A side-effect of the fix is to disallow changing the ownership of indexes
or toast tables separately from their parent table, which seems a good
idea on the whole.
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r-- | src/backend/commands/typecmds.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 80d394b2933..31e43cd4281 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.77 2005/08/01 04:03:55 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.78 2005/08/04 01:09:28 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -2057,7 +2057,8 @@ AlterTypeOwner(List *names, Oid newOwnerId) * free-standing composite type, and not a table's underlying type. We * want people to use ALTER TABLE not ALTER TYPE for that case. */ - if (typTup->typtype == 'c' && get_rel_relkind(typTup->typrelid) != 'c') + if (typTup->typtype == 'c' && + get_rel_relkind(typTup->typrelid) != RELKIND_COMPOSITE_TYPE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is a table's row type", @@ -2103,6 +2104,45 @@ AlterTypeOwner(List *names, Oid newOwnerId) } /* + * AlterTypeOwnerInternal - change type owner unconditionally + * + * This is currently only used to propagate ALTER TABLE OWNER to the + * table's rowtype. It assumes the caller has done all needed checks. + */ +void +AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId) +{ + Relation rel; + HeapTuple tup; + Form_pg_type typTup; + + rel = heap_open(TypeRelationId, RowExclusiveLock); + + tup = SearchSysCacheCopy(TYPEOID, + ObjectIdGetDatum(typeOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for type %u", typeOid); + typTup = (Form_pg_type) GETSTRUCT(tup); + + /* + * Modify the owner --- okay to scribble on typTup because it's a + * copy + */ + typTup->typowner = newOwnerId; + + simple_heap_update(rel, &tup->t_self, tup); + + CatalogUpdateIndexes(rel, tup); + + /* Update owner dependency reference */ + changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId); + + /* Clean up */ + heap_close(rel, RowExclusiveLock); +} + +/* * Execute ALTER TYPE SET SCHEMA */ void |