diff options
Diffstat (limited to 'src')
23 files changed, 869 insertions, 177 deletions
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index c8865b3dbde..a787f7ad43f 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.18 2004/05/26 04:41:09 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.19 2004/06/25 21:55:53 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -223,10 +223,9 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname) /* * if a basetype is passed in, then attempt to find an aggregate for - * that specific type. - * - * else attempt to find an aggregate with a basetype of ANYOID. This - * means that the aggregate is to apply to all basetypes (eg, COUNT). + * that specific type; else attempt to find an aggregate with a basetype + * of ANYOID. This means that the aggregate applies to all basetypes + * (eg, COUNT). */ if (basetype) basetypeOid = typenameTypeId(basetype); @@ -288,3 +287,60 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname) heap_close(rel, NoLock); heap_freetuple(tup); } + +/* + * Change aggregate owner + */ +void +AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) +{ + Oid basetypeOid; + Oid procOid; + HeapTuple tup; + Form_pg_proc procForm; + Relation rel; + + /* + * if a basetype is passed in, then attempt to find an aggregate for + * that specific type; else attempt to find an aggregate with a basetype + * of ANYOID. This means that the aggregate applies to all basetypes + * (eg, COUNT). + */ + if (basetype) + basetypeOid = typenameTypeId(basetype); + else + basetypeOid = ANYOID; + + rel = heap_openr(ProcedureRelationName, RowExclusiveLock); + + procOid = find_aggregate_func(name, basetypeOid, false); + + tup = SearchSysCacheCopy(PROCOID, + ObjectIdGetDatum(procOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for function %u", procOid); + procForm = (Form_pg_proc) GETSTRUCT(tup); + + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (procForm->proowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner --- okay to scribble on tup because it's a copy */ + procForm->proowner = newOwnerSysId; + + simple_heap_update(rel, &tup->t_self, tup); + CatalogUpdateIndexes(rel, tup); + } + + heap_close(rel, NoLock); + heap_freetuple(tup); +} diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 40a28103c77..50516e1f046 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.7 2004/05/26 04:41:09 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.8 2004/06/25 21:55:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,7 +25,9 @@ #include "commands/proclang.h" #include "commands/schemacmds.h" #include "commands/tablecmds.h" +#include "commands/tablespace.h" #include "commands/trigger.h" +#include "commands/typecmds.h" #include "commands/user.h" #include "miscadmin.h" #include "parser/parse_clause.h" @@ -35,6 +37,10 @@ #include "utils/syscache.h" +/* + * Executes an ALTER OBJECT / RENAME TO statement. Based on the object + * type, the function appropriate to that type is executed. + */ void ExecRenameStmt(RenameStmt *stmt) { @@ -74,6 +80,10 @@ ExecRenameStmt(RenameStmt *stmt) RenameSchema(stmt->subname, stmt->newname); break; + case OBJECT_TABLESPACE: + RenameTableSpace(stmt->subname, stmt->newname); + break; + case OBJECT_USER: RenameUser(stmt->subname, stmt->newname); break; @@ -133,3 +143,62 @@ ExecRenameStmt(RenameStmt *stmt) (int) stmt->renameType); } } + +/* + * Executes an ALTER OBJECT / OWNER TO statement. Based on the object + * type, the function appropriate to that type is executed. + */ +void +ExecAlterOwnerStmt(AlterOwnerStmt *stmt) +{ + AclId newowner = get_usesysid(stmt->newowner); + + switch (stmt->objectType) + { + case OBJECT_AGGREGATE: + AlterAggregateOwner(stmt->object, + (TypeName *) linitial(stmt->objarg), + newowner); + break; + + case OBJECT_CONVERSION: + AlterConversionOwner(stmt->object, newowner); + break; + + case OBJECT_DATABASE: + AlterDatabaseOwner((char *) linitial(stmt->object), newowner); + break; + + case OBJECT_FUNCTION: + AlterFunctionOwner(stmt->object, stmt->objarg, newowner); + break; + + case OBJECT_OPERATOR: + AlterOperatorOwner(stmt->object, + (TypeName *) linitial(stmt->objarg), + (TypeName *) lsecond(stmt->objarg), + newowner); + break; + + case OBJECT_OPCLASS: + AlterOpClassOwner(stmt->object, stmt->addname, newowner); + break; + + case OBJECT_SCHEMA: + AlterSchemaOwner((char *) linitial(stmt->object), newowner); + break; + + case OBJECT_TABLESPACE: + AlterTableSpaceOwner((char *) linitial(stmt->object), newowner); + break; + + case OBJECT_TYPE: + case OBJECT_DOMAIN: /* same as TYPE */ + AlterTypeOwner(stmt->object, newowner); + break; + + default: + elog(ERROR, "unrecognized AlterOwnerStmt type: %d", + (int) stmt->objectType); + } +} diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c index 1e55398f86e..298085f160b 100644 --- a/src/backend/commands/conversioncmds.c +++ b/src/backend/commands/conversioncmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.12 2003/11/29 19:51:47 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.13 2004/06/25 21:55:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -171,3 +171,55 @@ RenameConversion(List *name, const char *newname) heap_close(rel, NoLock); heap_freetuple(tup); } + +/* + * Change conversion owner + */ +void +AlterConversionOwner(List *name, AclId newOwnerSysId) +{ + Oid conversionOid; + HeapTuple tup; + Relation rel; + Form_pg_conversion convForm; + + rel = heap_openr(ConversionRelationName, RowExclusiveLock); + + conversionOid = FindConversionByName(name); + if (!OidIsValid(conversionOid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("conversion \"%s\" does not exist", + NameListToString(name)))); + + tup = SearchSysCacheCopy(CONOID, + ObjectIdGetDatum(conversionOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for conversion %u", conversionOid); + + convForm = (Form_pg_conversion) GETSTRUCT(tup); + + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (convForm->conowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner --- okay to scribble on tup because it's a copy */ + convForm->conowner = newOwnerSysId; + + simple_heap_update(rel, &tup->t_self, tup); + + CatalogUpdateIndexes(rel, tup); + } + + heap_close(rel, NoLock); + heap_freetuple(tup); +} diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 8fbebecd874..b9e8c836274 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.136 2004/06/18 06:13:22 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.137 2004/06/25 21:55:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -666,7 +666,7 @@ RenameDatabase(const char *oldname, const char *newname) /* rename */ newtup = heap_copytuple(tup); namestrcpy(&(((Form_pg_database) GETSTRUCT(newtup))->datname), newname); - simple_heap_update(rel, &tup->t_self, newtup); + simple_heap_update(rel, &newtup->t_self, newtup); CatalogUpdateIndexes(rel, newtup); systable_endscan(scan); @@ -758,7 +758,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) CatalogUpdateIndexes(rel, newtuple); systable_endscan(scan); - heap_close(rel, RowExclusiveLock); + heap_close(rel, NoLock); } @@ -766,14 +766,14 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) * ALTER DATABASE name OWNER TO newowner */ void -AlterDatabaseOwner(const char *dbname, const char *newowner) +AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) { - AclId newdatdba; HeapTuple tuple, newtuple; Relation rel; ScanKeyData scankey; SysScanDesc scan; + Form_pg_database datForm; rel = heap_openr(DatabaseRelationName, RowExclusiveLock); ScanKeyInit(&scankey, @@ -788,21 +788,27 @@ AlterDatabaseOwner(const char *dbname, const char *newowner) (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", dbname))); - /* obtain sysid of proposed owner */ - newdatdba = get_usesysid(newowner); /* will ereport if no such user */ + newtuple = heap_copytuple(tuple); + datForm = (Form_pg_database) GETSTRUCT(newtuple); - /* changing owner's database for someone else: must be superuser */ - /* note that the someone else need not have any permissions */ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to change owner's database for another user"))); + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is to be consistent with other objects. + */ + if (datForm->datdba != newOwnerSysId) + { + /* changing owner's database for someone else: must be superuser */ + /* note that the someone else need not have any permissions */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); - /* change owner */ - newtuple = heap_copytuple(tuple); - ((Form_pg_database) GETSTRUCT(newtuple))->datdba = newdatdba; - simple_heap_update(rel, &tuple->t_self, newtuple); - CatalogUpdateIndexes(rel, newtuple); + /* change owner */ + datForm->datdba = newOwnerSysId; + simple_heap_update(rel, &newtuple->t_self, newtuple); + CatalogUpdateIndexes(rel, newtuple); + } systable_endscan(scan); heap_close(rel, NoLock); diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 7747eb1d776..20ee9fa3445 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.48 2004/06/16 01:26:42 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.49 2004/06/25 21:55:53 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -723,6 +723,60 @@ RenameFunction(List *name, List *argtypes, const char *newname) heap_freetuple(tup); } +/* + * Change function owner + */ +void +AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId) +{ + Oid procOid; + HeapTuple tup; + Form_pg_proc procForm; + Relation rel; + + rel = heap_openr(ProcedureRelationName, RowExclusiveLock); + + procOid = LookupFuncNameTypeNames(name, argtypes, false); + + tup = SearchSysCacheCopy(PROCOID, + ObjectIdGetDatum(procOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for function %u", procOid); + procForm = (Form_pg_proc) GETSTRUCT(tup); + + if (procForm->proisagg) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an aggregate function", + NameListToString(name)), + errhint("Use ALTER AGGREGATE to change owner of aggregate functions."))); + + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (procForm->proowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner --- okay to scribble on tup because it's a copy */ + procForm->proowner = newOwnerSysId; + + simple_heap_update(rel, &tup->t_self, tup); + + CatalogUpdateIndexes(rel, tup); + } + + heap_close(rel, NoLock); + heap_freetuple(tup); +} + + /* * SetFunctionReturnType - change declared return type of a function diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index db5c2ccabc9..d9c0c1deade 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.25 2004/05/26 04:41:11 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.26 2004/06/25 21:55:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -871,3 +871,92 @@ RenameOpClass(List *name, const char *access_method, const char *newname) heap_close(rel, NoLock); heap_freetuple(tup); } + +/* + * Change opclass owner + */ +void +AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId) +{ + Oid opcOid; + Oid amOid; + Oid namespaceOid; + char *schemaname; + char *opcname; + HeapTuple tup; + Relation rel; + Form_pg_opclass opcForm; + + amOid = GetSysCacheOid(AMNAME, + CStringGetDatum(access_method), + 0, 0, 0); + if (!OidIsValid(amOid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("access method \"%s\" does not exist", + access_method))); + + rel = heap_openr(OperatorClassRelationName, RowExclusiveLock); + + /* + * Look up the opclass + */ + DeconstructQualifiedName(name, &schemaname, &opcname); + + if (schemaname) + { + namespaceOid = LookupExplicitNamespace(schemaname); + + tup = SearchSysCacheCopy(CLAAMNAMENSP, + ObjectIdGetDatum(amOid), + PointerGetDatum(opcname), + ObjectIdGetDatum(namespaceOid), + 0); + if (!HeapTupleIsValid(tup)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("operator class \"%s\" does not exist for access method \"%s\"", + opcname, access_method))); + + } + else + { + opcOid = OpclassnameGetOpcid(amOid, opcname); + if (!OidIsValid(opcOid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("operator class \"%s\" does not exist for access method \"%s\"", + opcname, access_method))); + + tup = SearchSysCacheCopy(CLAOID, + ObjectIdGetDatum(opcOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for opclass %u", opcOid); + namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace; + } + opcForm = (Form_pg_opclass) GETSTRUCT(tup); + + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (opcForm->opcowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner --- okay to scribble on tup because it's a copy */ + opcForm->opcowner = newOwnerSysId; + + simple_heap_update(rel, &tup->t_self, tup); + + CatalogUpdateIndexes(rel, tup); + } + + heap_close(rel, NoLock); + heap_freetuple(tup); +} diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index d2ffae2ce56..8fbe0d1128b 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.16 2004/05/26 04:41:11 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.17 2004/06/25 21:55:53 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -37,6 +37,7 @@ #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/dependency.h" +#include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_operator.h" #include "commands/defrem.h" @@ -263,3 +264,55 @@ RemoveOperatorById(Oid operOid) heap_close(relation, RowExclusiveLock); } + +/* + * change operator owner + */ +void +AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2, + AclId newOwnerSysId) +{ + Oid operOid; + HeapTuple tup; + Relation rel; + Form_pg_operator oprForm; + + rel = heap_openr(OperatorRelationName, RowExclusiveLock); + + operOid = LookupOperNameTypeNames(name, typeName1, typeName2, + false); + + tup = SearchSysCacheCopy(OPEROID, + ObjectIdGetDatum(operOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for operator %u", operOid); + + oprForm = (Form_pg_operator) GETSTRUCT(tup); + + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (oprForm->oprowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner --- okay to scribble on tup because it's a copy */ + oprForm->oprowner = newOwnerSysId; + + simple_heap_update(rel, &tup->t_self, tup); + + CatalogUpdateIndexes(rel, tup); + } + + heap_close(rel, NoLock); + heap_freetuple(tup); + +} + + diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index 8366ea634a0..35e18c9bfbd 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.19 2004/06/18 06:13:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.20 2004/06/25 21:55:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -307,3 +307,48 @@ RenameSchema(const char *oldname, const char *newname) heap_close(rel, NoLock); heap_freetuple(tup); } + +/* + * Change schema owner + */ +void +AlterSchemaOwner(const char *name, AclId newOwnerSysId) +{ + HeapTuple tup; + Relation rel; + Form_pg_namespace nspForm; + + rel = heap_openr(NamespaceRelationName, RowExclusiveLock); + + tup = SearchSysCacheCopy(NAMESPACENAME, + CStringGetDatum(name), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_SCHEMA), + errmsg("schema \"%s\" does not exist", name))); + nspForm = (Form_pg_namespace) GETSTRUCT(tup); + + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (nspForm->nspowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner --- okay to scribble on tup because it's a copy */ + nspForm->nspowner = newOwnerSysId; + + simple_heap_update(rel, &tup->t_self, tup); + + CatalogUpdateIndexes(rel, tup); + } + + heap_close(rel, NoLock); + heap_freetuple(tup); +} diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 8fd07e396ae..cfd8bd80cc0 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.116 2004/06/18 06:13:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.117 2004/06/25 21:55:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1921,11 +1921,6 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, pass = AT_PASS_MISC; break; case AT_ChangeOwner: /* ALTER OWNER */ - /* check that we are the superuser */ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to alter owner"))); /* This command never recurses */ /* No command-specific prep needed */ pass = AT_PASS_MISC; @@ -5097,42 +5092,55 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) NameStr(tuple_class->relname)))); } - /* - * Okay, this is a valid tuple: change its ownership and write to the - * heap. + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. */ - tuple_class->relowner = newOwnerSysId; - simple_heap_update(class_rel, &tuple->t_self, tuple); + if (tuple_class->relowner != newOwnerSysId) + { + /* Otherwise, check that we are the superuser */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); - /* Keep the catalog indexes up to date */ - CatalogUpdateIndexes(class_rel, tuple); + /* + * Okay, this is a valid tuple: change its ownership and write to the + * heap. + */ + tuple_class->relowner = newOwnerSysId; + simple_heap_update(class_rel, &tuple->t_self, tuple); - /* - * If we are operating on a table, also change the ownership of any - * indexes that belong to the table, as well as the table's toast - * table (if it has one) - */ - if (tuple_class->relkind == RELKIND_RELATION || - tuple_class->relkind == RELKIND_TOASTVALUE) - { - List *index_oid_list; - ListCell *i; + /* Keep the catalog indexes up to date */ + CatalogUpdateIndexes(class_rel, tuple); - /* Find all the indexes belonging to this relation */ - index_oid_list = RelationGetIndexList(target_rel); + /* + * If we are operating on a table, also change the ownership of any + * indexes that belong to the table, as well as the table's toast + * table (if it has one) + */ + if (tuple_class->relkind == RELKIND_RELATION || + tuple_class->relkind == RELKIND_TOASTVALUE) + { + List *index_oid_list; + ListCell *i; - /* For each index, recursively change its ownership */ - foreach(i, index_oid_list) - ATExecChangeOwner(lfirst_oid(i), newOwnerSysId); + /* Find all the indexes belonging to this relation */ + index_oid_list = RelationGetIndexList(target_rel); - list_free(index_oid_list); - } + /* For each index, recursively change its ownership */ + foreach(i, index_oid_list) + ATExecChangeOwner(lfirst_oid(i), newOwnerSysId); - if (tuple_class->relkind == RELKIND_RELATION) - { - /* If it has a toast table, recurse to change its ownership */ - if (tuple_class->reltoastrelid != InvalidOid) - ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId); + list_free(index_oid_list); + } + + if (tuple_class->relkind == RELKIND_RELATION) + { + /* If it has a toast table, recurse to change its ownership */ + if (tuple_class->reltoastrelid != InvalidOid) + ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId); + } } heap_freetuple(tuple); diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 61e36d5b5c2..847985456f7 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -45,7 +45,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.3 2004/06/21 04:06:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.4 2004/06/25 21:55:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -669,3 +669,123 @@ get_tablespace_name(Oid spc_oid) return result; } + +/* + * Rename a tablespace + */ +void +RenameTableSpace(const char *oldname, const char *newname) +{ + Relation rel; + ScanKeyData entry[1]; + HeapScanDesc scan; + HeapTuple tup; + HeapTuple newtuple; + Form_pg_tablespace newform; + + /* Search pg_tablespace */ + rel = heap_openr(TableSpaceRelationName, RowExclusiveLock); + + ScanKeyInit(&entry[0], + Anum_pg_tablespace_spcname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(oldname)); + scan = heap_beginscan(rel, SnapshotNow, 1, entry); + tup = heap_getnext(scan, ForwardScanDirection); + if (!HeapTupleIsValid(tup)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("tablespace \"%s\" does not exist", + oldname))); + + newtuple = heap_copytuple(tup); + newform = (Form_pg_tablespace) GETSTRUCT(newtuple); + + heap_endscan(scan); + + /* Must be owner or superuser */ + if (newform->spcowner != GetUserId() && !superuser()) + aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, oldname); + + /* Validate new name */ + if (!allowSystemTableMods && IsReservedName(newname)) + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("unacceptable tablespace name \"%s\"", newname), + errdetail("The prefix \"pg_\" is reserved for system tablespaces."))); + + /* Make sure the new name doesn't exist */ + ScanKeyInit(&entry[0], + Anum_pg_tablespace_spcname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(newname)); + scan = heap_beginscan(rel, SnapshotNow, 1, entry); + tup = heap_getnext(scan, ForwardScanDirection); + if (HeapTupleIsValid(tup)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("tablespace \"%s\" already exists", + newname))); + + heap_endscan(scan); + + /* OK, update the entry */ + namestrcpy(&(newform->spcname), newname); + + simple_heap_update(rel, &newtuple->t_self, newtuple); + CatalogUpdateIndexes(rel, newtuple); + + heap_close(rel, NoLock); +} + +/* + * Change tablespace owner + */ +void +AlterTableSpaceOwner(const char *name, AclId newOwnerSysId) +{ + Relation rel; + ScanKeyData entry[1]; + HeapScanDesc scandesc; + Form_pg_tablespace spcForm; + HeapTuple tup; + HeapTuple newtuple; + + /* Search pg_tablespace */ + rel = heap_openr(TableSpaceRelationName, RowExclusiveLock); + + ScanKeyInit(&entry[0], + Anum_pg_tablespace_spcname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(name)); + scandesc = heap_beginscan(rel, SnapshotNow, 1, entry); + tup = heap_getnext(scandesc, ForwardScanDirection); + if (!HeapTupleIsValid(tup)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("tablespace \"%s\" does not exist", name))); + + newtuple = heap_copytuple(tup); + spcForm = (Form_pg_tablespace) GETSTRUCT(newtuple); + + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (spcForm->spcowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner */ + spcForm->spcowner = newOwnerSysId; + simple_heap_update(rel, &newtuple->t_self, newtuple); + CatalogUpdateIndexes(rel, newtuple); + } + + heap_endscan(scandesc); + heap_close(rel, NoLock); +} diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index d087ad8895c..f9f1caa8630 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.60 2004/06/18 06:13:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.61 2004/06/25 21:55:53 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -2042,14 +2042,7 @@ GetDomainConstraints(Oid typeOid) } /* - * 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. + * Change the owner of a type. */ void AlterTypeOwner(List *names, AclId newOwnerSysId) @@ -2084,19 +2077,36 @@ AlterTypeOwner(List *names, AclId newOwnerSysId) elog(ERROR, "cache lookup failed for type %u", typeOid); typTup = (Form_pg_type) GETSTRUCT(tup); - /* Check that this is actually a domain */ - if (typTup->typtype != 'd') + /* + * If it's a composite type, we need to check that it really is a + * 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') ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a domain", + errmsg("\"%s\" is a table's row type", TypeNameToString(typename)))); - /* Modify the owner --- okay to scribble on typTup because it's a copy */ - typTup->typowner = newOwnerSysId; + /* + * If the new owner is the same as the existing owner, consider the + * command to have succeeded. This is for dump restoration purposes. + */ + if (typTup->typowner != newOwnerSysId) + { + /* Otherwise, must be superuser to change object ownership */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to change owner"))); + + /* Modify the owner --- okay to scribble on typTup because it's a copy */ + typTup->typowner = newOwnerSysId; - simple_heap_update(rel, &tup->t_self, tup); + simple_heap_update(rel, &tup->t_self, tup); - CatalogUpdateIndexes(rel, tup); + CatalogUpdateIndexes(rel, tup); + } /* Clean up */ heap_close(rel, RowExclusiveLock); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 90983e6db0b..17adc9cf5fd 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.286 2004/06/18 06:13:28 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.287 2004/06/25 21:55:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1937,6 +1937,21 @@ _copyRenameStmt(RenameStmt *from) return newnode; } +static AlterOwnerStmt * +_copyAlterOwnerStmt(AlterOwnerStmt *from) +{ + AlterOwnerStmt *newnode = makeNode(AlterOwnerStmt); + + COPY_NODE_FIELD(relation); + COPY_NODE_FIELD(object); + COPY_NODE_FIELD(objarg); + COPY_STRING_FIELD(addname); + COPY_STRING_FIELD(newowner); + COPY_SCALAR_FIELD(objectType); + + return newnode; +} + static RuleStmt * _copyRuleStmt(RuleStmt *from) { @@ -2080,17 +2095,6 @@ _copyCreatedbStmt(CreatedbStmt *from) return newnode; } -static AlterDbOwnerStmt * -_copyAlterDbOwnerStmt(AlterDbOwnerStmt *from) -{ - AlterDbOwnerStmt *newnode = makeNode(AlterDbOwnerStmt); - - COPY_STRING_FIELD(dbname); - COPY_STRING_FIELD(uname); - - return newnode; -} - static AlterDatabaseSetStmt * _copyAlterDatabaseSetStmt(AlterDatabaseSetStmt *from) { @@ -2874,6 +2878,9 @@ copyObject(void *from) case T_RenameStmt: retval = _copyRenameStmt(from); break; + case T_AlterOwnerStmt: + retval = _copyAlterOwnerStmt(from); + break; case T_RuleStmt: retval = _copyRuleStmt(from); break; @@ -2910,9 +2917,6 @@ copyObject(void *from) case T_CreatedbStmt: retval = _copyCreatedbStmt(from); break; - case T_AlterDbOwnerStmt: - retval = _copyAlterDbOwnerStmt(from); - break; case T_AlterDatabaseSetStmt: retval = _copyAlterDatabaseSetStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 47ec3157727..f46c7b44205 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.225 2004/06/18 06:13:28 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.226 2004/06/25 21:55:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -992,6 +992,19 @@ _equalRenameStmt(RenameStmt *a, RenameStmt *b) } static bool +_equalAlterOwnerStmt(AlterOwnerStmt *a, AlterOwnerStmt *b) +{ + COMPARE_NODE_FIELD(relation); + COMPARE_NODE_FIELD(object); + COMPARE_NODE_FIELD(objarg); + COMPARE_STRING_FIELD(addname); + COMPARE_STRING_FIELD(newowner); + COMPARE_SCALAR_FIELD(objectType); + + return true; +} + +static bool _equalRuleStmt(RuleStmt *a, RuleStmt *b) { COMPARE_NODE_FIELD(relation); @@ -1111,15 +1124,6 @@ _equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b) } static bool -_equalAlterDbOwnerStmt(AlterDbOwnerStmt *a, AlterDbOwnerStmt *b) -{ - COMPARE_STRING_FIELD(dbname); - COMPARE_STRING_FIELD(uname); - - return true; -} - -static bool _equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b) { COMPARE_STRING_FIELD(dbname); @@ -2008,6 +2012,9 @@ equal(void *a, void *b) case T_RenameStmt: retval = _equalRenameStmt(a, b); break; + case T_AlterOwnerStmt: + retval = _equalAlterOwnerStmt(a, b); + break; case T_RuleStmt: retval = _equalRuleStmt(a, b); break; @@ -2044,9 +2051,6 @@ equal(void *a, void *b) case T_CreatedbStmt: retval = _equalCreatedbStmt(a, b); break; - case T_AlterDbOwnerStmt: - retval = _equalAlterDbOwnerStmt(a, b); - break; case T_AlterDatabaseSetStmt: retval = _equalAlterDatabaseSetStmt(a, b); break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 9dc53604c61..7da8affbf91 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.462 2004/06/18 06:13:31 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.463 2004/06/25 21:55:55 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -131,7 +131,7 @@ static void doNegateFloat(Value *v); } %type <node> stmt schema_stmt - AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt + AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt AlterUserStmt AlterUserSetStmt AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt @@ -152,7 +152,6 @@ static void doNegateFloat(Value *v); VariableResetStmt VariableSetStmt VariableShowStmt ViewStmt CheckPointStmt CreateConversionStmt DeallocateStmt PrepareStmt ExecuteStmt - AlterDbOwnerStmt %type <node> select_no_parens select_with_parens select_clause simple_select @@ -487,10 +486,10 @@ stmtmulti: stmtmulti ';' stmt ; stmt : - AlterDbOwnerStmt - | AlterDatabaseSetStmt + AlterDatabaseSetStmt | AlterDomainStmt | AlterGroupStmt + | AlterOwnerStmt | AlterSeqStmt | AlterTableStmt | AlterUserSetStmt @@ -3670,6 +3669,14 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name n->newname = $6; $$ = (Node *)n; } + | ALTER TABLESPACE name RENAME TO name + { + RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TABLESPACE; + n->subname = $3; + n->newname = $6; + $$ = (Node *)n; + } ; opt_column: COLUMN { $$ = COLUMN; } @@ -3679,6 +3686,99 @@ opt_column: COLUMN { $$ = COLUMN; } /***************************************************************************** * + * ALTER THING name OWNER TO newname. + * + *****************************************************************************/ + +AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_AGGREGATE; + n->object = $3; + n->objarg = list_make1($5); + n->newowner = $9; + $$ = (Node *)n; + } + | ALTER CONVERSION_P any_name OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_CONVERSION; + n->object = $3; + n->newowner = $6; + $$ = (Node *)n; + } + | ALTER DATABASE database_name OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_DATABASE; + n->object = list_make1($3); + n->newowner = $6; + $$ = (Node *)n; + } + | ALTER DOMAIN_P any_name OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_DOMAIN; + n->object = $3; + n->newowner = $6; + $$ = (Node *)n; + } + | ALTER FUNCTION func_name func_args OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_FUNCTION; + n->object = $3; + n->objarg = extractArgTypes($4); + n->newowner = $7; + $$ = (Node *)n; + } + | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_OPERATOR; + n->object = $3; + n->objarg = $5; + n->newowner = $9; + $$ = (Node *)n; + } + | ALTER OPERATOR CLASS any_name USING access_method OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_OPCLASS; + n->object = $4; + n->addname = $6; + n->newowner = $9; + $$ = (Node *)n; + } + | ALTER SCHEMA name OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_SCHEMA; + n->object = list_make1($3); + n->newowner = $6; + $$ = (Node *)n; + } + | ALTER TYPE_P any_name OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_TYPE; + n->object = $3; + n->newowner = $6; + $$ = (Node *)n; + } + | ALTER TABLESPACE name OWNER TO UserId + { + AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_TABLESPACE; + n->object = list_make1($3); + n->newowner = $6; + $$ = (Node *)n; + } + ; + + +/***************************************************************************** + * * QUERY: Define Rewrite Rule * *****************************************************************************/ @@ -4019,15 +4119,6 @@ opt_equal: '=' {} * *****************************************************************************/ -AlterDbOwnerStmt: ALTER DATABASE database_name OWNER TO UserId - { - AlterDbOwnerStmt *n = makeNode(AlterDbOwnerStmt); - n->dbname = $3; - n->uname = $6; - $$ = (Node *)n; - } - ; - AlterDatabaseSetStmt: ALTER DATABASE database_name SET set_rest { @@ -4126,15 +4217,6 @@ AlterDomainStmt: n->behavior = $7; $$ = (Node *)n; } - /* ALTER DOMAIN <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 {} diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index d12cf0d750f..a3e727472ab 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.219 2004/06/18 06:13:38 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.220 2004/06/25 21:55:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -236,14 +236,14 @@ check_xact_readonly(Node *parsetree) switch (nodeTag(parsetree)) { case T_AlterDatabaseSetStmt: - case T_AlterDbOwnerStmt: case T_AlterDomainStmt: case T_AlterGroupStmt: + case T_AlterOwnerStmt: case T_AlterSeqStmt: case T_AlterTableStmt: - case T_RenameStmt: case T_AlterUserStmt: case T_AlterUserSetStmt: + case T_RenameStmt: case T_CommentStmt: case T_DefineStmt: case T_CreateCastStmt: @@ -527,6 +527,10 @@ ProcessUtility(Node *parsetree, ExecRenameStmt((RenameStmt *) parsetree); break; + case T_AlterOwnerStmt: + ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree); + break; + case T_AlterTableStmt: AlterTable((AlterTableStmt *) parsetree); break; @@ -567,16 +571,6 @@ ProcessUtility(Node *parsetree, stmt->name, stmt->behavior); break; - case 'U': /* OWNER TO */ - /* check that we are the superuser */ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to alter owner"))); - /* get_usesysid raises an error if no such user */ - AlterTypeOwner(stmt->typename, - get_usesysid(stmt->name)); - break; default: /* oops */ elog(ERROR, "unrecognized alter domain type: %d", (int) stmt->subtype); @@ -689,13 +683,6 @@ ProcessUtility(Node *parsetree, createdb((CreatedbStmt *) parsetree); break; - case T_AlterDbOwnerStmt: - { - AlterDbOwnerStmt *stmt = (AlterDbOwnerStmt *) parsetree; - AlterDatabaseOwner(stmt->dbname, stmt->uname); - } - break; - case T_AlterDatabaseSetStmt: AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree); break; @@ -1258,6 +1245,44 @@ CreateCommandTag(Node *parsetree) } break; + case T_AlterOwnerStmt: + switch (((AlterOwnerStmt *) parsetree)->objectType) + { + case OBJECT_AGGREGATE: + tag = "ALTER AGGREGATE"; + break; + case OBJECT_CONVERSION: + tag = "ALTER CONVERSION"; + break; + case OBJECT_DATABASE: + tag = "ALTER DATABASE"; + break; + case OBJECT_DOMAIN: + tag = "ALTER DOMAIN"; + break; + case OBJECT_FUNCTION: + tag = "ALTER FUNCTION"; + break; + case OBJECT_OPERATOR: + tag = "ALTER OPERATOR"; + break; + case OBJECT_OPCLASS: + tag = "ALTER OPERATOR CLASS"; + break; + case OBJECT_SCHEMA: + tag = "ALTER SCHEMA"; + break; + case OBJECT_TABLESPACE: + tag = "ALTER TABLESPACE"; + break; + case OBJECT_TYPE: + tag = "ALTER TYPE"; + break; + default: + tag = "ALTER TABLE"; + } + break; + case T_AlterTableStmt: tag = "ALTER TABLE"; break; @@ -1335,10 +1360,6 @@ CreateCommandTag(Node *parsetree) tag = "CREATE DATABASE"; break; - case T_AlterDbOwnerStmt: - tag = "ALTER DATABASE"; - break; - case T_AlterDatabaseSetStmt: tag = "ALTER DATABASE"; break; diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h index 58717ae03f5..2914fbbd8a6 100644 --- a/src/include/commands/alter.h +++ b/src/include/commands/alter.h @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * alter.h - * prototypes for alter.h + * prototypes for commands/alter.c * * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/alter.h,v 1.3 2003/11/29 22:40:59 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/commands/alter.h,v 1.4 2004/06/25 21:55:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,4 +18,6 @@ extern void ExecRenameStmt(RenameStmt *stmt); +extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt); + #endif /* ALTER_H */ diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h index 8ea65326c7c..a5146981177 100644 --- a/src/include/commands/conversioncmds.h +++ b/src/include/commands/conversioncmds.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/conversioncmds.h,v 1.6 2003/11/29 22:40:59 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/commands/conversioncmds.h,v 1.7 2004/06/25 21:55:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,5 +20,6 @@ extern void CreateConversionCommand(CreateConversionStmt *parsetree); extern void DropConversionCommand(List *conversion_name, DropBehavior behavior); extern void RenameConversion(List *name, const char *newname); +extern void AlterConversionOwner(List *name, AclId newOwnerSysId); #endif /* CONVERSIONCMDS_H */ diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h index 30b73d4daf1..c481e8c9d91 100644 --- a/src/include/commands/dbcommands.h +++ b/src/include/commands/dbcommands.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.31 2004/05/26 13:56:59 momjian Exp $ + * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.32 2004/06/25 21:55:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ extern void createdb(const CreatedbStmt *stmt); extern void dropdb(const char *dbname); extern void RenameDatabase(const char *oldname, const char *newname); extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt); -extern void AlterDatabaseOwner(const char *dbname, const char *uname); +extern void AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId); extern Oid get_database_oid(const char *dbname); extern char *get_database_name(Oid dbid); diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 8670a41a763..afe6cf0ac15 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.58 2004/06/18 06:14:08 tgl Exp $ + * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.59 2004/06/25 21:55:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -48,6 +48,7 @@ extern void RemoveFunctionById(Oid funcOid); extern void SetFunctionReturnType(Oid funcOid, Oid newRetType); extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType); extern void RenameFunction(List *name, List *argtypes, const char *newname); +extern void AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId); extern void CreateCast(CreateCastStmt *stmt); extern void DropCast(DropCastStmt *stmt); extern void DropCastById(Oid castOid); @@ -56,17 +57,21 @@ extern void DropCastById(Oid castOid); extern void DefineOperator(List *names, List *parameters); extern void RemoveOperator(RemoveOperStmt *stmt); extern void RemoveOperatorById(Oid operOid); +extern void AlterOperatorOwner(List *name, TypeName *typeName1, + TypeName *typename2, AclId newOwnerSysId); /* commands/aggregatecmds.c */ extern void DefineAggregate(List *names, List *parameters); extern void RemoveAggregate(RemoveAggrStmt *stmt); extern void RenameAggregate(List *name, TypeName *basetype, const char *newname); +extern void AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId); /* commands/opclasscmds.c */ extern void DefineOpClass(CreateOpClassStmt *stmt); extern void RemoveOpClass(RemoveOpClassStmt *stmt); extern void RemoveOpClassById(Oid opclassOid); extern void RenameOpClass(List *name, const char *access_method, const char *newname); +extern void AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId); /* support routines in commands/define.c */ diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h index 6f772e6b3e8..96e03d80ad8 100644 --- a/src/include/commands/schemacmds.h +++ b/src/include/commands/schemacmds.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/schemacmds.h,v 1.6 2003/11/29 22:40:59 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/commands/schemacmds.h,v 1.7 2004/06/25 21:55:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,5 +23,6 @@ extern void RemoveSchema(List *names, DropBehavior behavior); extern void RemoveSchemaById(Oid schemaOid); extern void RenameSchema(const char *oldname, const char *newname); +extern void AlterSchemaOwner(const char *name, AclId newOwnerSysId); #endif /* SCHEMACMDS_H */ diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index 129413ac14b..17821493f45 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.1 2004/06/18 06:14:08 tgl Exp $ + * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.2 2004/06/25 21:55:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,4 +26,7 @@ extern Oid get_tablespace_oid(const char *tablespacename); extern char *get_tablespace_name(Oid spc_oid); +extern void RenameTableSpace(const char *oldname, const char *newname); +extern void AlterTableSpaceOwner(const char *name, AclId newOwnerSysId); + #endif /* TABLESPACE_H */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 531b7e6c654..258bdc7b61e 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.158 2004/06/18 06:14:11 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.159 2004/06/25 21:55:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -270,7 +270,7 @@ typedef enum NodeTag T_DeclareCursorStmt, T_CreateTableSpaceStmt, T_DropTableSpaceStmt, - T_AlterDbOwnerStmt, + T_AlterOwnerStmt, T_A_Expr = 800, T_ColumnRef, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 4c24fe9e27b..22d18ef4f70 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.259 2004/06/18 06:14:11 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.260 2004/06/25 21:55:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -838,12 +838,10 @@ typedef struct AlterDomainStmt * O = alter column set not null * C = add constraint * X = drop constraint - * U = change owner *------------ */ List *typename; /* domain to work on */ - char *name; /* column or constraint name to act on, or - * new owner */ + char *name; /* column or constraint name to act on */ Node *def; /* definition of default or constraint */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ } AlterDomainStmt; @@ -1446,6 +1444,22 @@ typedef struct RenameStmt } RenameStmt; /* ---------------------- + * Alter Object Owner Statement + * ---------------------- + */ +typedef struct AlterOwnerStmt +{ + NodeTag type; + RangeVar *relation; /* in case it's a table */ + List *object; /* in case it's some other object */ + List *objarg; /* argument types, if applicable */ + char *addname; /* additional name if needed */ + char *newowner; /* the new owner */ + ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */ +} AlterOwnerStmt; + + +/* ---------------------- * Create Rule Statement * ---------------------- */ @@ -1560,13 +1574,6 @@ typedef struct CreatedbStmt * Alter Database * ---------------------- */ -typedef struct AlterDbOwnerStmt -{ - NodeTag type; - char *dbname; - char *uname; -} AlterDbOwnerStmt; - typedef struct AlterDatabaseSetStmt { NodeTag type; |