diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
index f21410e7c1..f02edd4cff 100644
--- a/doc/src/sgml/ref/allfiles.sgml
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -1,5 +1,5 @@
@@ -13,11 +13,14 @@ Complete list of usable sgml source files in this directory.
+
+
+
diff --git a/doc/src/sgml/ref/alter_aggregate.sgml b/doc/src/sgml/ref/alter_aggregate.sgml
index 112242f142..bfdb1761d5 100644
--- a/doc/src/sgml/ref/alter_aggregate.sgml
+++ b/doc/src/sgml/ref/alter_aggregate.sgml
@@ -1,5 +1,5 @@
@@ -21,6 +21,7 @@ PostgreSQL documentation
ALTER AGGREGATE name ( type ) RENAME TO newname
+ALTER AGGREGATE name ( type ) OWNER TO newowner
@@ -29,8 +30,7 @@ ALTER AGGREGATE name ( type
ALTER AGGREGATE changes the definition of an
- aggregate function. The only currently available functionality is to
- rename the aggregate function.
+ aggregate function.
@@ -65,6 +65,16 @@ ALTER AGGREGATE name ( type
+
+
+ newowner
+
+
+ The new owner of the aggregate function.
+ You must be a superuser to change an aggregate's owner.
+
+
+
@@ -76,6 +86,14 @@ ALTER AGGREGATE name ( typeinteger to my_average:
ALTER AGGREGATE myavg(integer) RENAME TO my_average;
+
+
+
+
+ To change the owner of the aggregate function myavg for type
+ integer to joe:
+
+ALTER AGGREGATE myavg(integer) OWNER TO joe;
diff --git a/doc/src/sgml/ref/alter_conversion.sgml b/doc/src/sgml/ref/alter_conversion.sgml
index 08d167eb3c..024d03212c 100644
--- a/doc/src/sgml/ref/alter_conversion.sgml
+++ b/doc/src/sgml/ref/alter_conversion.sgml
@@ -1,5 +1,5 @@
@@ -21,6 +21,7 @@ PostgreSQL documentation
ALTER CONVERSION name RENAME TO newname
+ALTER CONVERSION name OWNER TO newowner
@@ -29,7 +30,6 @@ ALTER CONVERSION name RENAME TO newname<
ALTER CONVERSION changes the definition of a
- conversion. The only currently available functionality is to rename the
conversion.
@@ -55,6 +55,16 @@ ALTER CONVERSION name RENAME TO newname<
+
+
+ newowner
+
+
+ The new owner of the conversion. To change the owner of a conversion,
+ you must be a superuser.
+
+
+
@@ -66,6 +76,14 @@ ALTER CONVERSION name RENAME TO newname<
latin1_to_unicode:
ALTER CONVERSION iso_8859_1_to_utf_8 RENAME TO latin1_to_unicode;
+
+
+
+
+ To change the owner of the conversion iso_8859_1_to_utf_8 to
+ joe:
+
+ALTER CONVERSION iso_8859_1_to_utf_8 OWNER TO joe;
diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml
index 71ae81893b..00dfcac007 100644
--- a/doc/src/sgml/ref/alter_function.sgml
+++ b/doc/src/sgml/ref/alter_function.sgml
@@ -1,5 +1,5 @@
@@ -21,6 +21,7 @@ PostgreSQL documentation
ALTER FUNCTION name ( [ type [, ...] ] ) RENAME TO newname
+ALTER FUNCTION name ( [ type [, ...] ] ) OWNER TO newowner
@@ -29,7 +30,7 @@ ALTER FUNCTION name ( [
+
+
+ newowner
+
+
+ The new owner of the function.
+ To change the owner of a function, you must be a superuser.
+ Note that if the function is marked
+ SECURITY DEFINER,
+ it will subsequently execute as the new owner.
+
+
+
@@ -74,6 +88,14 @@ ALTER FUNCTION name ( [ index_method RENAME TO newname
+ALTER OPERATOR CLASS name USING index_method OWNER TO newowner
@@ -29,8 +30,7 @@ ALTER OPERATOR CLASS name USING
-
+
+
+ newowner
+
+
+ The new owner of the operator class.
+ You must be a superuser to change the owner of an operator class.
+
+
+
+
diff --git a/doc/src/sgml/ref/alter_operator.sgml b/doc/src/sgml/ref/alter_operator.sgml
new file mode 100644
index 0000000000..cfec153f2b
--- /dev/null
+++ b/doc/src/sgml/ref/alter_operator.sgml
@@ -0,0 +1,127 @@
+
+
+
+
+ ALTER OPERATOR
+ SQL - Language Statements
+
+
+
+ ALTER OPERATOR
+ change the definition of an operator
+
+
+
+ ALTER OPERATOR
+
+
+
+
+ALTER OPERATOR name ( { lefttype | NONE } , { righttype | NONE } ) OWNER TO newowner
+
+
+
+
+ Description
+
+
+ ALTER OPERATOR changes the definition of
+ an operator. The only currently available functionality is to change the
+ owner of the operator.
+
+
+
+
+ Parameters
+
+
+
+ name
+
+
+ The name (optionally schema-qualified) of an existing operator.
+
+
+
+
+
+ lefttype
+
+
+ The data type of the operator's left operand; write
+ NONE if the operator has no left operand.
+
+
+
+
+
+ righttype
+
+
+ The data type of the operator's right operand; write
+ NONE if the operator has no right operand.
+
+
+
+
+
+ newowner
+
+
+ The new owner of the operator.
+ You must be a superuser to change the owner of an operator.
+
+
+
+
+
+
+
+ Examples
+
+
+ Change the owner of a custom operator a @@ b for type text:
+
+ALTER OPERATOR @@ (text, text) OWNER TO joe;
+
+
+
+
+
+ Compatibility
+
+
+ There is no ALTER OPERATOR statement in
+ the SQL standard.
+
+
+
+
+ See Also
+
+
+
+
+
+
+
+
+
diff --git a/doc/src/sgml/ref/alter_schema.sgml b/doc/src/sgml/ref/alter_schema.sgml
index 866db72868..702df1da39 100644
--- a/doc/src/sgml/ref/alter_schema.sgml
+++ b/doc/src/sgml/ref/alter_schema.sgml
@@ -1,5 +1,5 @@
@@ -21,6 +21,7 @@ PostgreSQL documentation
ALTER SCHEMA name RENAME TO newname
+ALTER SCHEMA name OWNER TO newowner
@@ -29,9 +30,9 @@ ALTER SCHEMA name RENAME TO newname
ALTER SCHEMA changes the definition of a schema.
- The only functionality is to rename the schema. To rename a schema
- you must own the schema and have the privilege
- CREATE for the database.
+ To rename a schema you must own the schema and have the privilege
+ CREATE for the database. To change the owner
+ of a schema, you must be a superuser.
@@ -43,7 +44,7 @@ ALTER SCHEMA name RENAME TO newnamename
- Name of a schema
+ The name of an existing schema.
@@ -52,7 +53,18 @@ ALTER SCHEMA name RENAME TO newnamenewname
- The new name of the schema
+ The new name of the schema. The new name cannot
+ begin with pg_, as such names
+ are reserved for system schemas.
+
+
+
+
+
+ newowner
+
+
+ The new owner of the schema.
diff --git a/doc/src/sgml/ref/alter_tablespace.sgml b/doc/src/sgml/ref/alter_tablespace.sgml
new file mode 100644
index 0000000000..bdfe4b8155
--- /dev/null
+++ b/doc/src/sgml/ref/alter_tablespace.sgml
@@ -0,0 +1,125 @@
+
+
+
+
+ ALTER TABLESPACE
+ SQL - Language Statements
+
+
+
+ ALTER TABLESPACE
+ change the definition of a tablespace
+
+
+
+ ALTER TABLESPACE
+
+
+
+
+ALTER TABLESPACE name RENAME TO newname
+ALTER TABLESPACE name OWNER TO newowner
+
+
+
+
+ Description
+
+
+ ALTER TABLESPACE changes the definition of
+ a tablespace.
+
+
+
+
+ Parameters
+
+
+
+ name
+
+
+ The name of an existing tablespace.
+
+
+
+
+
+ newname
+
+
+ The new name of the tablespace. The new name cannot
+ begin with pg_, as such names
+ are reserved for system tablespaces.
+
+
+
+
+
+ newowner
+
+
+ The new owner of the tablespace.
+ You must be a superuser to change the owner of a tablespace.
+
+
+
+
+
+
+
+ Examples
+
+
+ Rename tablespace index_space to fast_raid:
+
+ALTER TABLESPACE index_space RENAME TO fast_raid;
+
+
+
+
+ Change the owner of tablespace index_space:
+
+ALTER TABLESPACE index_space OWNER TO mary;
+
+
+
+
+
+ Compatibility
+
+
+ There is no ALTER TABLESPACE statement in
+ the SQL standard.
+
+
+
+
+ See Also
+
+
+
+
+
+
+
+
+
diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml
new file mode 100644
index 0000000000..33830c04c0
--- /dev/null
+++ b/doc/src/sgml/ref/alter_type.sgml
@@ -0,0 +1,106 @@
+
+
+
+
+ ALTER TYPE
+ SQL - Language Statements
+
+
+
+
+ ALTER TYPE
+
+
+ change the definition of a type
+
+
+
+
+ ALTER TYPE
+
+
+
+
+ALTER TYPE name OWNER TO new_owner
+
+
+
+
+ Description
+
+
+ ALTER TYPE changes the definition of an existing type.
+ The only currently available capability is changing the owner of a type.
+
+
+
+
+ Parameters
+
+
+
+
+ name
+
+
+ The name (possibly schema-qualified) of an existing type to
+ alter.
+
+
+
+
+
+ new_owner
+
+
+ The user name of the new owner of the type.
+ You must be a superuser to change a type's owner.
+
+
+
+
+
+
+
+
+
+ Examples
+
+
+ To change the owner of the user-defined type email
+ to joe:
+
+ALTER TYPE email OWNER TO joe;
+
+
+
+
+
+ Compatibility
+
+
+ There is no ALTER TYPE statement in the SQL
+ standard.
+
+
+
+
+
diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml
index 1001b8f33f..029d1af0d9 100644
--- a/doc/src/sgml/ref/create_operator.sgml
+++ b/doc/src/sgml/ref/create_operator.sgml
@@ -1,5 +1,5 @@
@@ -109,13 +109,13 @@ CREATE OPERATOR name (
name
- The name of the operator to be defined. See above for allowable
- characters. The name may be schema-qualified, for example
- CREATE OPERATOR myschema.+ (...)>. If not, then
- the operator is created in the current schema. Two operators
- in the same schema can have the same name if they operate on
- different data types. This is called
- overloading>.
+ The name of the operator to be defined. See above for allowable
+ characters. The name may be schema-qualified, for example
+ CREATE OPERATOR myschema.+ (...)>. If not, then
+ the operator is created in the current schema. Two operators
+ in the same schema can have the same name if they operate on
+ different data types. This is called
+ overloading>.
@@ -124,7 +124,7 @@ CREATE OPERATOR name (
funcname
- The function used to implement this operator.
+ The function used to implement this operator.
@@ -133,8 +133,8 @@ CREATE OPERATOR name (
lefttype
- The data type of the operator's left operand, if any.
- This option would be omitted for a left-unary operator.
+ The data type of the operator's left operand, if any.
+ This option would be omitted for a left-unary operator.
@@ -143,8 +143,8 @@ CREATE OPERATOR name (
righttype
- The data type of the operator's right operand, if any.
- This option would be omitted for a right-unary operator.
+ The data type of the operator's right operand, if any.
+ This option would be omitted for a right-unary operator.
@@ -153,7 +153,7 @@ CREATE OPERATOR name (
com_op
- The commutator of this operator.
+ The commutator of this operator.
@@ -162,7 +162,7 @@ CREATE OPERATOR name (
neg_op
- The negator of this operator.
+ The negator of this operator.
@@ -171,7 +171,7 @@ CREATE OPERATOR name (
res_proc
- The restriction selectivity estimator function for this operator.
+ The restriction selectivity estimator function for this operator.
@@ -180,7 +180,7 @@ CREATE OPERATOR name (
join_proc
- The join selectivity estimator function for this operator.
+ The join selectivity estimator function for this operator.
@@ -207,8 +207,8 @@ CREATE OPERATOR name (
left_sort_op
- If this operator can support a merge join, the less-than
- operator that sorts the left-hand data type of this operator.
+ If this operator can support a merge join, the less-than
+ operator that sorts the left-hand data type of this operator.
@@ -217,8 +217,8 @@ CREATE OPERATOR name (
right_sort_op
- If this operator can support a merge join, the less-than
- operator that sorts the right-hand data type of this operator.
+ If this operator can support a merge join, the less-than
+ operator that sorts the right-hand data type of this operator.
@@ -227,8 +227,8 @@ CREATE OPERATOR name (
less_than_op
- If this operator can support a merge join, the less-than
- operator that compares the input data types of this operator.
+ If this operator can support a merge join, the less-than
+ operator that compares the input data types of this operator.
@@ -237,8 +237,8 @@ CREATE OPERATOR name (
greater_than_op
- If this operator can support a merge join, the greater-than
- operator that compares the input data types of this operator.
+ If this operator can support a merge join, the greater-than
+ operator that compares the input data types of this operator.
@@ -263,7 +263,8 @@ COMMUTATOR = OPERATOR(myschema.===) ,
Use DROP OPERATOR to delete user-defined
- operators from a database.
+ operators from a database. Use ALTER OPERATOR
+ to modify operators in a database.
diff --git a/doc/src/sgml/ref/create_schema.sgml b/doc/src/sgml/ref/create_schema.sgml
index 8668612cc6..4f56341ce3 100644
--- a/doc/src/sgml/ref/create_schema.sgml
+++ b/doc/src/sgml/ref/create_schema.sgml
@@ -1,5 +1,5 @@
@@ -64,7 +64,9 @@ CREATE SCHEMA AUTHORIZATION username
The name of a schema to be created. If this is omitted, the user name
- is used as the schema name.
+ is used as the schema name. The name cannot
+ begin with pg_, as such names
+ are reserved for system schemas.
diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml
index 9f670a817d..08ff4e3254 100644
--- a/doc/src/sgml/ref/create_tablespace.sgml
+++ b/doc/src/sgml/ref/create_tablespace.sgml
@@ -1,5 +1,5 @@
@@ -56,7 +56,9 @@ CREATE TABLESPACE tablespacename [
tablespacename
- The name of a tablespace to be created.
+ The name of a tablespace to be created. The name cannot
+ begin with pg_, as such names
+ are reserved for system tablespaces.
@@ -133,6 +135,7 @@ CREATE TABLESPACE indexspace OWNER genevieve LOCATION '/data/indexes';
+
diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml
index b35a1805ca..b7d1ac64e0 100644
--- a/doc/src/sgml/ref/create_type.sgml
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -1,5 +1,5 @@
@@ -546,6 +546,7 @@ CREATE TABLE big_objs (
+
diff --git a/doc/src/sgml/ref/drop_operator.sgml b/doc/src/sgml/ref/drop_operator.sgml
index 5b17ebec1b..b928e72193 100644
--- a/doc/src/sgml/ref/drop_operator.sgml
+++ b/doc/src/sgml/ref/drop_operator.sgml
@@ -1,5 +1,5 @@
@@ -20,7 +20,7 @@ PostgreSQL documentation
-DROP OPERATOR name ( lefttype | NONE , righttype | NONE ) [ CASCADE | RESTRICT ]
+DROP OPERATOR name ( { lefttype | NONE } , { righttype | NONE } ) [ CASCADE | RESTRICT ]
@@ -128,6 +128,7 @@ DROP OPERATOR ! (bigint, none);
+
diff --git a/doc/src/sgml/ref/drop_tablespace.sgml b/doc/src/sgml/ref/drop_tablespace.sgml
index ba8415208e..bd4fb6dcd5 100644
--- a/doc/src/sgml/ref/drop_tablespace.sgml
+++ b/doc/src/sgml/ref/drop_tablespace.sgml
@@ -1,5 +1,5 @@
@@ -80,6 +80,7 @@ DROP TABLESPACE mystuff;
+
diff --git a/doc/src/sgml/ref/drop_type.sgml b/doc/src/sgml/ref/drop_type.sgml
index 3ac172b5b4..da0f6bc8b6 100644
--- a/doc/src/sgml/ref/drop_type.sgml
+++ b/doc/src/sgml/ref/drop_type.sgml
@@ -1,5 +1,5 @@
@@ -95,6 +95,7 @@ DROP TYPE box;
+
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
index b5d42361ce..5230e07119 100644
--- a/doc/src/sgml/reference.sgml
+++ b/doc/src/sgml/reference.sgml
@@ -1,5 +1,5 @@
@@ -45,11 +45,14 @@ PostgreSQL Reference Manual
&alterFunction;
&alterGroup;
&alterLanguage;
+ &alterOperator;
&alterOperatorClass;
&alterSchema;
&alterSequence;
&alterTable;
+ &alterTableSpace;
&alterTrigger;
+ &alterType;
&alterUser;
&analyze;
&begin;
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index c8865b3dbd..a787f7ad43 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 40a28103c7..50516e1f04 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 1e55398f86..298085f160 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 8fbebecd87..b9e8c83627 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 */
-
- /* 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")));
-
- /* change owner */
newtuple = heap_copytuple(tuple);
- ((Form_pg_database) GETSTRUCT(newtuple))->datdba = newdatdba;
- simple_heap_update(rel, &tuple->t_self, newtuple);
- CatalogUpdateIndexes(rel, newtuple);
+ datForm = (Form_pg_database) GETSTRUCT(newtuple);
+
+ /*
+ * 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 */
+ 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 7747eb1d77..20ee9fa344 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 db5c2ccabc..d9c0c1dead 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 d2ffae2ce5..8fbe0d1128 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 8366ea634a..35e18c9bfb 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 8fd07e396a..cfd8bd80cc 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);
-
- /* Keep the catalog indexes up to date */
- CatalogUpdateIndexes(class_rel, 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)
+ if (tuple_class->relowner != newOwnerSysId)
{
- List *index_oid_list;
- ListCell *i;
+ /* Otherwise, check that we are the superuser */
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to change owner")));
- /* Find all the indexes belonging to this relation */
- index_oid_list = RelationGetIndexList(target_rel);
+ /*
+ * 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);
- /* For each index, recursively change its ownership */
- foreach(i, index_oid_list)
- ATExecChangeOwner(lfirst_oid(i), newOwnerSysId);
+ /* Keep the catalog indexes up to date */
+ CatalogUpdateIndexes(class_rel, tuple);
- list_free(index_oid_list);
- }
+ /*
+ * 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;
- 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);
+ /* Find all the indexes belonging to this relation */
+ index_oid_list = RelationGetIndexList(target_rel);
+
+ /* For each index, recursively change its ownership */
+ foreach(i, index_oid_list)
+ ATExecChangeOwner(lfirst_oid(i), 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 61e36d5b5c..847985456f 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 d087ad8895..f9f1caa863 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")));
- simple_heap_update(rel, &tup->t_self, tup);
+ /* Modify the owner --- okay to scribble on typTup because it's a copy */
+ typTup->typowner = newOwnerSysId;
- CatalogUpdateIndexes(rel, tup);
+ simple_heap_update(rel, &tup->t_self, 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 90983e6db0..17adc9cf5f 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 47ec315772..f46c7b4420 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 $
*
*-------------------------------------------------------------------------
*/
@@ -991,6 +991,19 @@ _equalRenameStmt(RenameStmt *a, RenameStmt *b)
return true;
}
+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)
{
@@ -1110,15 +1123,6 @@ _equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
return true;
}
-static bool
-_equalAlterDbOwnerStmt(AlterDbOwnerStmt *a, AlterDbOwnerStmt *b)
-{
- COMPARE_STRING_FIELD(dbname);
- COMPARE_STRING_FIELD(uname);
-
- return true;
-}
-
static bool
_equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b)
{
@@ -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 9dc53604c6..7da8affbf9 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 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 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; }
@@ -3677,6 +3684,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 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 d12cf0d750..a3e727472a 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 58717ae03f..2914fbbd8a 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 8ea65326c7..a514698117 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 30b73d4daf..c481e8c9d9 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 8670a41a76..afe6cf0ac1 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 6f772e6b3e..96e03d80ad 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 129413ac14..17821493f4 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 531b7e6c65..258bdc7b61 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 4c24fe9e27..22d18ef4f7 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;
@@ -1445,6 +1443,22 @@ typedef struct RenameStmt
ObjectType renameType; /* OBJECT_TABLE, OBJECT_COLUMN, etc */
} 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;