alter.c 5.9 KB
Newer Older
1 2 3 4 5
/*-------------------------------------------------------------------------
 *
 * alter.c
 *	  Drivers for generic alter commands
 *
6
 * Portions Copyright (c) 1996-2007, 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.23 2007/03/26 16:58:38 tgl Exp $
12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 *-------------------------------------------------------------------------
 */
#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"
25
#include "commands/tablespace.h"
26
#include "commands/trigger.h"
27
#include "commands/typecmds.h"
28 29 30
#include "commands/user.h"
#include "miscadmin.h"
#include "parser/parse_clause.h"
31
#include "tcop/utility.h"
32 33 34 35
#include "utils/acl.h"
#include "utils/lsyscache.h"


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

69 70 71 72
		case OBJECT_OPFAMILY:
			RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
			break;

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

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

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

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

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

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

B
Bruce Momjian 已提交
96
				switch (stmt->renameType)
97
				{
B
Bruce Momjian 已提交
98
					case OBJECT_TABLE:
T
Tom Lane 已提交
99
					case OBJECT_INDEX:
B
Bruce Momjian 已提交
100 101 102
						{
							/*
							 * RENAME TABLE requires that we (still) hold
B
Bruce Momjian 已提交
103 104
							 * CREATE rights on the containing namespace, as
							 * well as ownership of the table.
B
Bruce Momjian 已提交
105 106 107 108 109
							 */
							Oid			namespaceId = get_rel_namespace(relid);
							AclResult	aclresult;

							aclresult = pg_namespace_aclcheck(namespaceId,
110 111
															  GetUserId(),
															  ACL_CREATE);
B
Bruce Momjian 已提交
112 113
							if (aclresult != ACLCHECK_OK)
								aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
B
Bruce Momjian 已提交
114
											get_namespace_name(namespaceId));
B
Bruce Momjian 已提交
115 116 117 118 119 120 121 122

							renamerel(relid, stmt->newname);
							break;
						}
					case OBJECT_COLUMN:
						renameatt(relid,
								  stmt->subname,		/* old att name */
								  stmt->newname,		/* new att name */
B
Bruce Momjian 已提交
123
								  interpretInhOption(stmt->relation->inhOpt),	/* recursive? */
B
Bruce Momjian 已提交
124 125 126 127 128 129 130 131 132 133 134
								  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;
135 136 137
			}

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

143 144 145 146 147 148 149 150 151 152
/*
 * 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:
T
Tom Lane 已提交
153 154 155 156
			AlterFunctionNamespace(stmt->object, stmt->objarg, true,
								   stmt->newschema);
			break;

157
		case OBJECT_FUNCTION:
T
Tom Lane 已提交
158
			AlterFunctionNamespace(stmt->object, stmt->objarg, false,
159 160
								   stmt->newschema);
			break;
B
Bruce Momjian 已提交
161

162 163 164 165 166
		case OBJECT_SEQUENCE:
		case OBJECT_TABLE:
			CheckRelationOwnership(stmt->relation, true);
			AlterTableNamespace(stmt->relation, stmt->newschema);
			break;
B
Bruce Momjian 已提交
167

168 169 170 171
		case OBJECT_TYPE:
		case OBJECT_DOMAIN:
			AlterTypeNamespace(stmt->object, stmt->newschema);
			break;
B
Bruce Momjian 已提交
172

173 174 175 176 177 178
		default:
			elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
				 (int) stmt->objectType);
	}
}

179 180 181 182 183 184 185
/*
 * Executes an ALTER OBJECT / OWNER TO statement.  Based on the object
 * type, the function appropriate to that type is executed.
 */
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
B
Bruce Momjian 已提交
186
	Oid			newowner = get_roleid_checked(stmt->newowner);
187 188 189 190

	switch (stmt->objectType)
	{
		case OBJECT_AGGREGATE:
T
Tom Lane 已提交
191
			AlterAggregateOwner(stmt->object, stmt->objarg, newowner);
192 193 194 195 196 197 198 199 200 201 202 203 204 205
			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;

206 207 208 209
		case OBJECT_LANGUAGE:
			AlterLanguageOwner((char *) linitial(stmt->object), newowner);
			break;

210
		case OBJECT_OPERATOR:
T
Tom Lane 已提交
211
			Assert(list_length(stmt->objarg) == 2);
212 213 214 215 216 217 218 219 220 221
			AlterOperatorOwner(stmt->object,
							   (TypeName *) linitial(stmt->objarg),
							   (TypeName *) lsecond(stmt->objarg),
							   newowner);
			break;

		case OBJECT_OPCLASS:
			AlterOpClassOwner(stmt->object, stmt->addname, newowner);
			break;

222 223 224 225
		case OBJECT_OPFAMILY:
			AlterOpFamilyOwner(stmt->object, stmt->addname, newowner);
			break;

226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
		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);
	}
}