alter.c 5.6 KB
Newer Older
1 2 3 4 5
/*-------------------------------------------------------------------------
 *
 * alter.c
 *	  Drivers for generic alter commands
 *
P
 
PostgreSQL Daemon 已提交
6
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7 8 9 10
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
11
 *	  $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.14 2005/08/01 04:03:55 tgl Exp $
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/htup.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_class.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"
28
#include "commands/tablespace.h"
29
#include "commands/trigger.h"
30
#include "commands/typecmds.h"
31 32 33
#include "commands/user.h"
#include "miscadmin.h"
#include "parser/parse_clause.h"
34
#include "tcop/utility.h"
35 36 37 38 39
#include "utils/acl.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"


40
/*
B
Bruce Momjian 已提交
41
 * Executes an ALTER OBJECT / RENAME TO statement.	Based on the object
42 43
 * type, the function appropriate to that type is executed.
 */
44 45 46 47 48 49
void
ExecRenameStmt(RenameStmt *stmt)
{
	switch (stmt->renameType)
	{
		case OBJECT_AGGREGATE:
50 51 52
			RenameAggregate(stmt->object,
							(TypeName *) linitial(stmt->objarg),
							stmt->newname);
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
			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;

75 76 77 78
		case OBJECT_ROLE:
			RenameRole(stmt->subname, stmt->newname);
			break;

79 80 81 82
		case OBJECT_SCHEMA:
			RenameSchema(stmt->subname, stmt->newname);
			break;

83 84 85 86
		case OBJECT_TABLESPACE:
			RenameTableSpace(stmt->subname, stmt->newname);
			break;

87
		case OBJECT_TABLE:
T
Tom Lane 已提交
88
		case OBJECT_INDEX:
89 90
		case OBJECT_COLUMN:
		case OBJECT_TRIGGER:
B
Bruce Momjian 已提交
91 92
			{
				Oid			relid;
93

B
Bruce Momjian 已提交
94
				CheckRelationOwnership(stmt->relation, true);
95

B
Bruce Momjian 已提交
96
				relid = RangeVarGetRelid(stmt->relation, false);
97

B
Bruce Momjian 已提交
98
				switch (stmt->renameType)
99
				{
B
Bruce Momjian 已提交
100
					case OBJECT_TABLE:
T
Tom Lane 已提交
101
					case OBJECT_INDEX:
B
Bruce Momjian 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
						{
							/*
							 * 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);
							break;
						}
					case OBJECT_COLUMN:
						renameatt(relid,
								  stmt->subname,		/* old att name */
								  stmt->newname,		/* new att name */
125
							  interpretInhOption(stmt->relation->inhOpt),		/* recursive? */
B
Bruce Momjian 已提交
126 127 128 129 130 131 132 133 134 135 136
								  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;
137 138 139
			}

		default:
140 141
			elog(ERROR, "unrecognized rename stmt type: %d",
				 (int) stmt->renameType);
142 143
	}
}
144

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
/*
 * 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:
		case OBJECT_FUNCTION:
			AlterFunctionNamespace(stmt->object, stmt->objarg,
								   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);
	}
}

177 178 179 180 181 182 183
/*
 * Executes an ALTER OBJECT / OWNER TO statement.  Based on the object
 * type, the function appropriate to that type is executed.
 */
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
184
	Oid		newowner = get_roleid_checked(stmt->newowner);
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

	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);
	}
}