2003-06-27 16:45:32 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* alter.c
|
|
|
|
* Drivers for generic alter commands
|
|
|
|
*
|
2008-01-01 20:46:01 +01:00
|
|
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
2003-06-27 16:45:32 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2008-01-01 20:46:01 +01:00
|
|
|
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.26 2008/01/01 19:45:48 momjian Exp $
|
2003-06-27 16:45:32 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
|
|
|
#include "catalog/namespace.h"
|
|
|
|
#include "commands/alter.h"
|
|
|
|
#include "commands/conversioncmds.h"
|
|
|
|
#include "commands/dbcommands.h"
|
|
|
|
#include "commands/defrem.h"
|
|
|
|
#include "commands/proclang.h"
|
|
|
|
#include "commands/schemacmds.h"
|
|
|
|
#include "commands/tablecmds.h"
|
2004-06-25 23:55:59 +02:00
|
|
|
#include "commands/tablespace.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/trigger.h"
|
2004-06-25 23:55:59 +02:00
|
|
|
#include "commands/typecmds.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/user.h"
|
|
|
|
#include "miscadmin.h"
|
|
|
|
#include "parser/parse_clause.h"
|
2003-07-22 21:00:12 +02:00
|
|
|
#include "tcop/utility.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "utils/acl.h"
|
|
|
|
#include "utils/lsyscache.h"
|
|
|
|
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
/*
|
2004-08-29 07:07:03 +02:00
|
|
|
* Executes an ALTER OBJECT / RENAME TO statement. Based on the object
|
2004-06-25 23:55:59 +02:00
|
|
|
* type, the function appropriate to that type is executed.
|
|
|
|
*/
|
2003-06-27 16:45:32 +02:00
|
|
|
void
|
|
|
|
ExecRenameStmt(RenameStmt *stmt)
|
|
|
|
{
|
|
|
|
switch (stmt->renameType)
|
|
|
|
{
|
|
|
|
case OBJECT_AGGREGATE:
|
2006-04-15 19:45:46 +02:00
|
|
|
RenameAggregate(stmt->object, stmt->objarg, stmt->newname);
|
2003-06-27 16:45:32 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_CONVERSION:
|
|
|
|
RenameConversion(stmt->object, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_DATABASE:
|
|
|
|
RenameDatabase(stmt->subname, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_FUNCTION:
|
|
|
|
RenameFunction(stmt->object, stmt->objarg, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_LANGUAGE:
|
|
|
|
RenameLanguage(stmt->subname, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_OPCLASS:
|
|
|
|
RenameOpClass(stmt->object, stmt->subname, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
case OBJECT_OPFAMILY:
|
|
|
|
RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
2005-06-28 07:09:14 +02:00
|
|
|
case OBJECT_ROLE:
|
|
|
|
RenameRole(stmt->subname, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
case OBJECT_SCHEMA:
|
|
|
|
RenameSchema(stmt->subname, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
case OBJECT_TABLESPACE:
|
|
|
|
RenameTableSpace(stmt->subname, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
case OBJECT_TABLE:
|
2007-07-03 03:30:37 +02:00
|
|
|
case OBJECT_SEQUENCE:
|
|
|
|
case OBJECT_VIEW:
|
2004-08-22 02:08:28 +02:00
|
|
|
case OBJECT_INDEX:
|
2003-06-27 16:45:32 +02:00
|
|
|
case OBJECT_COLUMN:
|
|
|
|
case OBJECT_TRIGGER:
|
2003-08-04 02:43:34 +02:00
|
|
|
{
|
|
|
|
Oid relid;
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2003-08-04 02:43:34 +02:00
|
|
|
CheckRelationOwnership(stmt->relation, true);
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2003-08-04 02:43:34 +02:00
|
|
|
relid = RangeVarGetRelid(stmt->relation, false);
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2003-08-04 02:43:34 +02:00
|
|
|
switch (stmt->renameType)
|
2003-06-27 16:45:32 +02:00
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
case OBJECT_TABLE:
|
2007-07-03 03:30:37 +02:00
|
|
|
case OBJECT_SEQUENCE:
|
|
|
|
case OBJECT_VIEW:
|
2004-08-22 02:08:28 +02:00
|
|
|
case OBJECT_INDEX:
|
2003-08-04 02:43:34 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* RENAME TABLE requires that we (still) hold
|
2005-10-15 04:49:52 +02:00
|
|
|
* CREATE rights on the containing namespace, as
|
|
|
|
* well as ownership of the table.
|
2003-08-04 02:43:34 +02:00
|
|
|
*/
|
|
|
|
Oid namespaceId = get_rel_namespace(relid);
|
|
|
|
AclResult aclresult;
|
|
|
|
|
|
|
|
aclresult = pg_namespace_aclcheck(namespaceId,
|
2006-02-12 20:11:01 +01:00
|
|
|
GetUserId(),
|
|
|
|
ACL_CREATE);
|
2003-08-04 02:43:34 +02:00
|
|
|
if (aclresult != ACLCHECK_OK)
|
|
|
|
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
2005-10-15 04:49:52 +02:00
|
|
|
get_namespace_name(namespaceId));
|
2003-08-04 02:43:34 +02:00
|
|
|
|
2007-07-03 03:30:37 +02:00
|
|
|
renamerel(relid, stmt->newname, stmt->renameType);
|
2003-08-04 02:43:34 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case OBJECT_COLUMN:
|
|
|
|
renameatt(relid,
|
|
|
|
stmt->subname, /* old att name */
|
|
|
|
stmt->newname, /* new att name */
|
2005-10-15 04:49:52 +02:00
|
|
|
interpretInhOption(stmt->relation->inhOpt), /* recursive? */
|
2003-08-04 02:43:34 +02:00
|
|
|
false); /* recursing already? */
|
|
|
|
break;
|
|
|
|
case OBJECT_TRIGGER:
|
|
|
|
renametrig(relid,
|
|
|
|
stmt->subname, /* old att name */
|
|
|
|
stmt->newname); /* new att name */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* can't happen */ ;
|
|
|
|
}
|
|
|
|
break;
|
2003-06-27 16:45:32 +02:00
|
|
|
}
|
|
|
|
|
2007-08-21 03:11:32 +02:00
|
|
|
case OBJECT_TSPARSER:
|
|
|
|
RenameTSParser(stmt->object, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_TSDICTIONARY:
|
|
|
|
RenameTSDictionary(stmt->object, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_TSTEMPLATE:
|
|
|
|
RenameTSTemplate(stmt->object, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_TSCONFIGURATION:
|
|
|
|
RenameTSConfiguration(stmt->object, stmt->newname);
|
|
|
|
break;
|
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
default:
|
2003-07-20 23:56:35 +02:00
|
|
|
elog(ERROR, "unrecognized rename stmt type: %d",
|
|
|
|
(int) stmt->renameType);
|
2003-06-27 16:45:32 +02:00
|
|
|
}
|
|
|
|
}
|
2004-06-25 23:55:59 +02:00
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
/*
|
|
|
|
* Executes an ALTER OBJECT / SET SCHEMA statement. Based on the object
|
|
|
|
* type, the function appropriate to that type is executed.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
|
|
|
|
{
|
|
|
|
switch (stmt->objectType)
|
|
|
|
{
|
|
|
|
case OBJECT_AGGREGATE:
|
2006-04-15 19:45:46 +02:00
|
|
|
AlterFunctionNamespace(stmt->object, stmt->objarg, true,
|
|
|
|
stmt->newschema);
|
|
|
|
break;
|
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
case OBJECT_FUNCTION:
|
2006-04-15 19:45:46 +02:00
|
|
|
AlterFunctionNamespace(stmt->object, stmt->objarg, false,
|
2005-08-01 06:03:59 +02:00
|
|
|
stmt->newschema);
|
|
|
|
break;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
case OBJECT_SEQUENCE:
|
|
|
|
case OBJECT_TABLE:
|
|
|
|
CheckRelationOwnership(stmt->relation, true);
|
|
|
|
AlterTableNamespace(stmt->relation, stmt->newschema);
|
|
|
|
break;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
case OBJECT_TYPE:
|
|
|
|
case OBJECT_DOMAIN:
|
|
|
|
AlterTypeNamespace(stmt->object, stmt->newschema);
|
|
|
|
break;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
|
|
|
|
(int) stmt->objectType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
/*
|
|
|
|
* Executes an ALTER OBJECT / OWNER TO statement. Based on the object
|
|
|
|
* type, the function appropriate to that type is executed.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|
|
|
{
|
2005-10-15 04:49:52 +02:00
|
|
|
Oid newowner = get_roleid_checked(stmt->newowner);
|
2004-06-25 23:55:59 +02:00
|
|
|
|
|
|
|
switch (stmt->objectType)
|
|
|
|
{
|
|
|
|
case OBJECT_AGGREGATE:
|
2006-04-15 19:45:46 +02:00
|
|
|
AlterAggregateOwner(stmt->object, stmt->objarg, newowner);
|
2004-06-25 23:55:59 +02:00
|
|
|
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;
|
|
|
|
|
2007-03-26 18:58:41 +02:00
|
|
|
case OBJECT_LANGUAGE:
|
|
|
|
AlterLanguageOwner((char *) linitial(stmt->object), newowner);
|
|
|
|
break;
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
case OBJECT_OPERATOR:
|
2006-04-15 19:45:46 +02:00
|
|
|
Assert(list_length(stmt->objarg) == 2);
|
2004-06-25 23:55:59 +02:00
|
|
|
AlterOperatorOwner(stmt->object,
|
|
|
|
(TypeName *) linitial(stmt->objarg),
|
|
|
|
(TypeName *) lsecond(stmt->objarg),
|
|
|
|
newowner);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_OPCLASS:
|
|
|
|
AlterOpClassOwner(stmt->object, stmt->addname, newowner);
|
|
|
|
break;
|
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
case OBJECT_OPFAMILY:
|
|
|
|
AlterOpFamilyOwner(stmt->object, stmt->addname, newowner);
|
|
|
|
break;
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
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;
|
|
|
|
|
2007-08-21 03:11:32 +02:00
|
|
|
case OBJECT_TSDICTIONARY:
|
|
|
|
AlterTSDictionaryOwner(stmt->object, newowner);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBJECT_TSCONFIGURATION:
|
|
|
|
AlterTSConfigurationOwner(stmt->object, newowner);
|
|
|
|
break;
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
|
|
|
|
(int) stmt->objectType);
|
|
|
|
}
|
|
|
|
}
|