aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/typecmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-08-04 01:09:29 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-08-04 01:09:29 +0000
commit33f5bf97009811d7f6b5408e37c6ad68110985b0 (patch)
treeaf599eafaa4b01a044de0e8e98f5eb16bbcd19aa /src/backend/commands/typecmds.c
parente48b28b688c9dd1ad2d74fcfeed7d76fe63d0047 (diff)
downloadpostgresql-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.c44
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