<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/alter_database.sgml,v 1.11 2003/11/29 19:51:38 pgsql Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/alter_database.sgml,v 1.12 2004/05/26 13:56:42 momjian Exp $
PostgreSQL documentation
-->
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>parameter</replaceable>
+ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
+
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>newname</replaceable>
</synopsis>
</refsynopsisdiv>
be renamed. (Connect to a different database if you need to do
that.)
</para>
+
+ <para>
+ The fourth form changes the owner of the database. Only a superuser
+ can change the database's owner.
+ </para>
</refsect1>
<refsect1>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.133 2004/05/26 04:41:10 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.134 2004/05/26 13:56:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
}
+/*
+ * ALTER DATABASE name OWNER TO newowner
+ */
+void
+AlterDatabaseOwner(const char *dbname, const char *newowner)
+{
+ AclId newdatdba;
+ HeapTuple tuple,
+ newtuple;
+ Relation rel;
+ ScanKeyData scankey;
+ SysScanDesc scan;
+
+ rel = heap_openr(DatabaseRelationName, RowExclusiveLock);
+ ScanKeyInit(&scankey,
+ Anum_pg_database_datname,
+ BTEqualStrategyNumber, F_NAMEEQ,
+ NameGetDatum(dbname));
+ scan = systable_beginscan(rel, DatabaseNameIndex, true,
+ SnapshotNow, 1, &scankey);
+ tuple = systable_getnext(scan);
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (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);
+
+ systable_endscan(scan);
+ heap_close(rel, NoLock);
+}
+
/*
* Helper functions
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.282 2004/05/26 04:41:18 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.283 2004/05/26 13:56:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
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)
{
case T_CreatedbStmt:
retval = _copyCreatedbStmt(from);
break;
+ case T_AlterDbOwnerStmt:
+ retval = _copyAlterDbOwnerStmt(from);
+ break;
case T_AlterDatabaseSetStmt:
retval = _copyAlterDatabaseSetStmt(from);
break;
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.221 2004/05/26 04:41:19 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.222 2004/05/26 13:56:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
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)
{
case T_CreatedbStmt:
retval = _equalCreatedbStmt(a, b);
break;
+ case T_AlterDbOwnerStmt:
+ retval = _equalAlterDbOwnerStmt(a, b);
+ break;
case T_AlterDatabaseSetStmt:
retval = _equalAlterDatabaseSetStmt(a, b);
break;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.455 2004/05/26 04:41:29 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.456 2004/05/26 13:56:51 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
VariableResetStmt VariableSetStmt VariableShowStmt
ViewStmt CheckPointStmt CreateConversionStmt
DeallocateStmt PrepareStmt ExecuteStmt
+ AlterDbOwnerStmt
%type <node> select_no_parens select_with_parens select_clause
simple_select
;
stmt :
- AlterDatabaseSetStmt
+ AlterDbOwnerStmt
+ | AlterDatabaseSetStmt
| AlterDomainStmt
| AlterGroupStmt
| AlterSeqStmt
*
*****************************************************************************/
+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
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.216 2004/05/26 04:41:35 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.217 2004/05/26 13:56:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
switch (nodeTag(parsetree))
{
case T_AlterDatabaseSetStmt:
+ case T_AlterDbOwnerStmt:
case T_AlterDomainStmt:
case T_AlterGroupStmt:
case T_AlterSeqStmt:
createdb((CreatedbStmt *) parsetree);
break;
+ case T_AlterDbOwnerStmt:
+ {
+ AlterDbOwnerStmt *stmt = (AlterDbOwnerStmt *) parsetree;
+ AlterDatabaseOwner(stmt->dbname, stmt->uname);
+ }
+ break;
+
case T_AlterDatabaseSetStmt:
AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
break;
tag = "CREATE DATABASE";
break;
+ case T_AlterDbOwnerStmt:
+ tag = "ALTER DATABASE";
+ break;
+
case T_AlterDatabaseSetStmt:
tag = "ALTER DATABASE";
break;
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.106 2004/05/12 13:38:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.107 2004/05/26 13:56:55 momjian Exp $
*/
/*----------------------------------------------------------------------
pg_strcasecmp(prev2_wd, "DATABASE") == 0)
{
static const char *const list_ALTERDATABASE[] =
- {"RESET", "SET", "RENAME TO", NULL};
+ {"RESET", "SET", "OWNER TO", "RENAME TO", NULL};
COMPLETE_WITH_LIST(list_ALTERDATABASE);
}
* 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.30 2003/11/29 22:40:59 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.31 2004/05/26 13:56:59 momjian Exp $
*
*-------------------------------------------------------------------------
*/
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 Oid get_database_oid(const char *dbname);
extern char *get_database_name(Oid dbid);
* 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.155 2004/05/26 04:41:45 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.156 2004/05/26 13:57:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
T_ExecuteStmt,
T_DeallocateStmt,
T_DeclareCursorStmt,
+ T_AlterDbOwnerStmt,
T_A_Expr = 800,
T_ColumnRef,
* 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.255 2004/05/05 04:48:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.256 2004/05/26 13:57:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
* Alter Database
* ----------------------
*/
+typedef struct AlterDbOwnerStmt
+{
+ NodeTag type;
+ char *dbname;
+ char *uname;
+} AlterDbOwnerStmt;
+
typedef struct AlterDatabaseSetStmt
{
NodeTag type;
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.283 2004/05/21 13:50:12 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.284 2004/05/26 13:57:04 momjian Exp $ */
/* Copyright comment */
%{
%type <str> CharacterWithoutLength BitWithLength BitWithoutLength
%type <str> ConstBit GenericType TableFuncElementList opt_analyze
%type <str> opt_sort_clause transaction_access_mode subquery_Op
-
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
%type <str> indicator ECPGExecute ECPGPrepare ecpg_using ecpg_into
%type <str> storage_declaration storage_clause opt_initializer c_anything
%type <str> inf_val_list inf_col_list using_descriptor into_descriptor
%type <str> ecpg_into_using prepared_name struct_union_type_with_symbol
%type <str> ECPGunreserved ECPGunreserved_interval cvariable
+%type <str> AlterDatabaseOwnerStmt
%type <struct_union> s_struct_union_symbol
};
stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
+ | AlterDatabaseOwnerStmt { output_statement($1, 0, connection); }
| AlterDomainStmt { output_statement($1, 0, connection); }
| AlterGroupStmt { output_statement($1, 0, connection); }
| AlterSeqStmt { output_statement($1, 0, connection); }
*
*****************************************************************************/
+AlterDatabaseOwnerStmt: ALTER DATABASE database_name OWNER TO UserId
+ { $$ = cat_str(4, make_str("alter database"), $3, make_str("owner to"), $6); }
AlterDatabaseSetStmt: ALTER DATABASE database_name SET set_rest
{ $$ = cat_str(4, make_str("alter database"), $3, make_str("set"), $5); }
| ALTER DATABASE database_name VariableResetStmt