mirror of
https://github.com/postgres/postgres.git
synced 2025-07-17 06:41:09 +03:00
Oleg Bartunov and Teodor Sigaev, but I did a lot of editorializing, so anything that's broken is probably my fault. Documentation is nonexistent as yet, but let's land the patch so we can get some portability testing done.
272 lines
6.5 KiB
C
272 lines
6.5 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* alter.c
|
|
* Drivers for generic alter commands
|
|
*
|
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.25 2007/08/21 01:11:14 tgl Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#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"
|
|
#include "commands/tablespace.h"
|
|
#include "commands/trigger.h"
|
|
#include "commands/typecmds.h"
|
|
#include "commands/user.h"
|
|
#include "miscadmin.h"
|
|
#include "parser/parse_clause.h"
|
|
#include "tcop/utility.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/lsyscache.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)
|
|
{
|
|
switch (stmt->renameType)
|
|
{
|
|
case OBJECT_AGGREGATE:
|
|
RenameAggregate(stmt->object, stmt->objarg, stmt->newname);
|
|
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;
|
|
|
|
case OBJECT_OPFAMILY:
|
|
RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
|
|
break;
|
|
|
|
case OBJECT_ROLE:
|
|
RenameRole(stmt->subname, stmt->newname);
|
|
break;
|
|
|
|
case OBJECT_SCHEMA:
|
|
RenameSchema(stmt->subname, stmt->newname);
|
|
break;
|
|
|
|
case OBJECT_TABLESPACE:
|
|
RenameTableSpace(stmt->subname, stmt->newname);
|
|
break;
|
|
|
|
case OBJECT_TABLE:
|
|
case OBJECT_SEQUENCE:
|
|
case OBJECT_VIEW:
|
|
case OBJECT_INDEX:
|
|
case OBJECT_COLUMN:
|
|
case OBJECT_TRIGGER:
|
|
{
|
|
Oid relid;
|
|
|
|
CheckRelationOwnership(stmt->relation, true);
|
|
|
|
relid = RangeVarGetRelid(stmt->relation, false);
|
|
|
|
switch (stmt->renameType)
|
|
{
|
|
case OBJECT_TABLE:
|
|
case OBJECT_SEQUENCE:
|
|
case OBJECT_VIEW:
|
|
case OBJECT_INDEX:
|
|
{
|
|
/*
|
|
* RENAME TABLE requires that we (still) hold
|
|
* CREATE rights on the containing namespace, as
|
|
* well as ownership of the table.
|
|
*/
|
|
Oid namespaceId = get_rel_namespace(relid);
|
|
AclResult aclresult;
|
|
|
|
aclresult = pg_namespace_aclcheck(namespaceId,
|
|
GetUserId(),
|
|
ACL_CREATE);
|
|
if (aclresult != ACLCHECK_OK)
|
|
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
|
get_namespace_name(namespaceId));
|
|
|
|
renamerel(relid, stmt->newname, stmt->renameType);
|
|
break;
|
|
}
|
|
case OBJECT_COLUMN:
|
|
renameatt(relid,
|
|
stmt->subname, /* old att name */
|
|
stmt->newname, /* new att name */
|
|
interpretInhOption(stmt->relation->inhOpt), /* recursive? */
|
|
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;
|
|
}
|
|
|
|
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;
|
|
|
|
default:
|
|
elog(ERROR, "unrecognized rename stmt type: %d",
|
|
(int) stmt->renameType);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 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:
|
|
AlterFunctionNamespace(stmt->object, stmt->objarg, true,
|
|
stmt->newschema);
|
|
break;
|
|
|
|
case OBJECT_FUNCTION:
|
|
AlterFunctionNamespace(stmt->object, stmt->objarg, false,
|
|
stmt->newschema);
|
|
break;
|
|
|
|
case OBJECT_SEQUENCE:
|
|
case OBJECT_TABLE:
|
|
CheckRelationOwnership(stmt->relation, true);
|
|
AlterTableNamespace(stmt->relation, stmt->newschema);
|
|
break;
|
|
|
|
case OBJECT_TYPE:
|
|
case OBJECT_DOMAIN:
|
|
AlterTypeNamespace(stmt->object, stmt->newschema);
|
|
break;
|
|
|
|
default:
|
|
elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
|
|
(int) stmt->objectType);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Executes an ALTER OBJECT / OWNER TO statement. Based on the object
|
|
* type, the function appropriate to that type is executed.
|
|
*/
|
|
void
|
|
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|
{
|
|
Oid newowner = get_roleid_checked(stmt->newowner);
|
|
|
|
switch (stmt->objectType)
|
|
{
|
|
case OBJECT_AGGREGATE:
|
|
AlterAggregateOwner(stmt->object, 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_LANGUAGE:
|
|
AlterLanguageOwner((char *) linitial(stmt->object), newowner);
|
|
break;
|
|
|
|
case OBJECT_OPERATOR:
|
|
Assert(list_length(stmt->objarg) == 2);
|
|
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_OPFAMILY:
|
|
AlterOpFamilyOwner(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;
|
|
|
|
case OBJECT_TSDICTIONARY:
|
|
AlterTSDictionaryOwner(stmt->object, newowner);
|
|
break;
|
|
|
|
case OBJECT_TSCONFIGURATION:
|
|
AlterTSConfigurationOwner(stmt->object, newowner);
|
|
break;
|
|
|
|
default:
|
|
elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
|
|
(int) stmt->objectType);
|
|
}
|
|
}
|