PostgreSQL Source Code git master
Functions
schemacmds.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "commands/event_trigger.h"
#include "commands/schemacmds.h"
#include "miscadmin.h"
#include "parser/parse_utilcmd.h"
#include "parser/scansup.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for schemacmds.c:

Go to the source code of this file.

Functions

static void  AlterSchemaOwner_internal (HeapTuple tup, Relation rel, Oid newOwnerId)
 
Oid  CreateSchemaCommand (CreateSchemaStmt *stmt, const char *queryString, int stmt_location, int stmt_len)
 
ObjectAddress  RenameSchema (const char *oldname, const char *newname)
 
void  AlterSchemaOwner_oid (Oid schemaoid, Oid newOwnerId)
 
ObjectAddress  AlterSchemaOwner (const char *name, Oid newOwnerId)
 

Function Documentation

AlterSchemaOwner()

ObjectAddress AlterSchemaOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 331 of file schemacmds.c.

332{
333 Oid nspOid;
334 HeapTuple tup;
335 Relation rel;
336 ObjectAddress address;
337 Form_pg_namespace nspform;
338
339 rel = table_open(NamespaceRelationId, RowExclusiveLock);
340
341 tup = SearchSysCache1(NAMESPACENAME, CStringGetDatum(name));
342 if (!HeapTupleIsValid(tup))
344 (errcode(ERRCODE_UNDEFINED_SCHEMA),
345 errmsg("schema \"%s\" does not exist", name)));
346
347 nspform = (Form_pg_namespace) GETSTRUCT(tup);
348 nspOid = nspform->oid;
349
350 AlterSchemaOwner_internal(tup, rel, newOwnerId);
351
352 ObjectAddressSet(address, NamespaceRelationId, nspOid);
353
354 ReleaseSysCache(tup);
355
357
358 return address;
359}
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:52
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:360
unsigned int Oid
Definition: postgres_ext.h:32
static void AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
Definition: schemacmds.c:362
Definition: rel.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
const char * name

References AlterSchemaOwner_internal(), CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, GETSTRUCT(), HeapTupleIsValid, name, ObjectAddressSet, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), table_close(), and table_open().

Referenced by ExecAlterOwnerStmt().

AlterSchemaOwner_internal()

static void AlterSchemaOwner_internal ( HeapTuple  tup,
Relation  rel,
Oid  newOwnerId 
)
static

Definition at line 362 of file schemacmds.c.

363{
364 Form_pg_namespace nspForm;
365
366 Assert(tup->t_tableOid == NamespaceRelationId);
367 Assert(RelationGetRelid(rel) == NamespaceRelationId);
368
369 nspForm = (Form_pg_namespace) GETSTRUCT(tup);
370
371 /*
372 * If the new owner is the same as the existing owner, consider the
373 * command to have succeeded. This is for dump restoration purposes.
374 */
375 if (nspForm->nspowner != newOwnerId)
376 {
377 Datum repl_val[Natts_pg_namespace];
378 bool repl_null[Natts_pg_namespace];
379 bool repl_repl[Natts_pg_namespace];
380 Acl *newAcl;
381 Datum aclDatum;
382 bool isNull;
383 HeapTuple newtuple;
384 AclResult aclresult;
385
386 /* Otherwise, must be owner of the existing object */
387 if (!object_ownercheck(NamespaceRelationId, nspForm->oid, GetUserId()))
389 NameStr(nspForm->nspname));
390
391 /* Must be able to become new owner */
392 check_can_set_role(GetUserId(), newOwnerId);
393
394 /*
395 * must have create-schema rights
396 *
397 * NOTE: This is different from other alter-owner checks in that the
398 * current user is checked for create privileges instead of the
399 * destination owner. This is consistent with the CREATE case for
400 * schemas. Because superusers will always have this right, we need
401 * no special case for them.
402 */
403 aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
404 ACL_CREATE);
405 if (aclresult != ACLCHECK_OK)
408
409 memset(repl_null, false, sizeof(repl_null));
410 memset(repl_repl, false, sizeof(repl_repl));
411
412 repl_repl[Anum_pg_namespace_nspowner - 1] = true;
413 repl_val[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(newOwnerId);
414
415 /*
416 * Determine the modified ACL for the new owner. This is only
417 * necessary when the ACL is non-null.
418 */
419 aclDatum = SysCacheGetAttr(NAMESPACENAME, tup,
420 Anum_pg_namespace_nspacl,
421 &isNull);
422 if (!isNull)
423 {
424 newAcl = aclnewowner(DatumGetAclP(aclDatum),
425 nspForm->nspowner, newOwnerId);
426 repl_repl[Anum_pg_namespace_nspacl - 1] = true;
427 repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl);
428 }
429
430 newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
431
432 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
433
434 heap_freetuple(newtuple);
435
436 /* Update owner dependency reference */
437 changeDependencyOnOwner(NamespaceRelationId, nspForm->oid,
438 newOwnerId);
439 }
440
441 InvokeObjectPostAlterHook(NamespaceRelationId,
442 nspForm->oid, 0);
443}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1119
void check_can_set_role(Oid member, Oid role)
Definition: acl.c:5341
AclResult
Definition: acl.h:182
@ ACLCHECK_OK
Definition: acl.h:183
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
#define DatumGetAclP(X)
Definition: acl.h:120
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2652
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3834
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4088
#define NameStr(name)
Definition: c.h:751
Oid MyDatabaseId
Definition: globals.c:94
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1210
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
char * get_database_name(Oid dbid)
Definition: lsyscache.c:1259
Oid GetUserId(void)
Definition: miscinit.c:469
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
@ OBJECT_SCHEMA
Definition: parsenodes.h:2361
@ OBJECT_DATABASE
Definition: parsenodes.h:2334
#define ACL_CREATE
Definition: parsenodes.h:85
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:316
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
uint64_t Datum
Definition: postgres.h:70
#define RelationGetRelid(relation)
Definition: rel.h:514
#define RelationGetDescr(relation)
Definition: rel.h:540
Definition: array.h:93
ItemPointerData t_self
Definition: htup.h:65
Oid t_tableOid
Definition: htup.h:66
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:595

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, aclnewowner(), Assert(), CatalogTupleUpdate(), changeDependencyOnOwner(), check_can_set_role(), DatumGetAclP, get_database_name(), GETSTRUCT(), GetUserId(), heap_freetuple(), heap_modify_tuple(), InvokeObjectPostAlterHook, MyDatabaseId, NameStr, object_aclcheck(), OBJECT_DATABASE, object_ownercheck(), OBJECT_SCHEMA, ObjectIdGetDatum(), PointerGetDatum(), RelationGetDescr, RelationGetRelid, SysCacheGetAttr(), HeapTupleData::t_self, and HeapTupleData::t_tableOid.

Referenced by AlterSchemaOwner(), and AlterSchemaOwner_oid().

AlterSchemaOwner_oid()

void AlterSchemaOwner_oid ( Oid  schemaoid,
Oid  newOwnerId 
)

Definition at line 308 of file schemacmds.c.

309{
310 HeapTuple tup;
311 Relation rel;
312
313 rel = table_open(NamespaceRelationId, RowExclusiveLock);
314
315 tup = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(schemaoid));
316 if (!HeapTupleIsValid(tup))
317 elog(ERROR, "cache lookup failed for schema %u", schemaoid);
318
319 AlterSchemaOwner_internal(tup, rel, newOwnerId);
320
321 ReleaseSysCache(tup);
322
324}
#define elog(elevel,...)
Definition: elog.h:226

References AlterSchemaOwner_internal(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), table_close(), and table_open().

Referenced by shdepReassignOwned_Owner().

CreateSchemaCommand()

Oid CreateSchemaCommand ( CreateSchemaStmtstmt,
const char *  queryString,
int  stmt_location,
int  stmt_len 
)

Definition at line 52 of file schemacmds.c.

54{
55 const char *schemaName = stmt->schemaname;
56 Oid namespaceId;
57 List *parsetree_list;
58 ListCell *parsetree_item;
59 Oid owner_uid;
60 Oid saved_uid;
61 int save_sec_context;
62 int save_nestlevel;
63 char *nsp = namespace_search_path;
64 AclResult aclresult;
65 ObjectAddress address;
66 StringInfoData pathbuf;
67
68 GetUserIdAndSecContext(&saved_uid, &save_sec_context);
69
70 /*
71 * Who is supposed to own the new schema?
72 */
73 if (stmt->authrole)
74 owner_uid = get_rolespec_oid(stmt->authrole, false);
75 else
76 owner_uid = saved_uid;
77
78 /* fill schema name with the user name if not specified */
79 if (!schemaName)
80 {
81 HeapTuple tuple;
82
83 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(owner_uid));
84 if (!HeapTupleIsValid(tuple))
85 elog(ERROR, "cache lookup failed for role %u", owner_uid);
86 schemaName =
88 ReleaseSysCache(tuple);
89 }
90
91 /*
92 * To create a schema, must have schema-create privilege on the current
93 * database and must be able to become the target role (this does not
94 * imply that the target role itself must have create-schema privilege).
95 * The latter provision guards against "giveaway" attacks. Note that a
96 * superuser will always have both of these privileges a fortiori.
97 */
98 aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, saved_uid, ACL_CREATE);
99 if (aclresult != ACLCHECK_OK)
102
103 check_can_set_role(saved_uid, owner_uid);
104
105 /* Additional check to protect reserved schema names */
106 if (!allowSystemTableMods && IsReservedName(schemaName))
108 (errcode(ERRCODE_RESERVED_NAME),
109 errmsg("unacceptable schema name \"%s\"", schemaName),
110 errdetail("The prefix \"pg_\" is reserved for system schemas.")));
111
112 /*
113 * If if_not_exists was given and the schema already exists, bail out.
114 * (Note: we needn't check this when not if_not_exists, because
115 * NamespaceCreate will complain anyway.) We could do this before making
116 * the permissions checks, but since CREATE TABLE IF NOT EXISTS makes its
117 * creation-permission check first, we do likewise.
118 */
119 if (stmt->if_not_exists)
120 {
121 namespaceId = get_namespace_oid(schemaName, true);
122 if (OidIsValid(namespaceId))
123 {
124 /*
125 * If we are in an extension script, insist that the pre-existing
126 * object be a member of the extension, to avoid security risks.
127 */
128 ObjectAddressSet(address, NamespaceRelationId, namespaceId);
130
131 /* OK to skip */
133 (errcode(ERRCODE_DUPLICATE_SCHEMA),
134 errmsg("schema \"%s\" already exists, skipping",
135 schemaName)));
136 return InvalidOid;
137 }
138 }
139
140 /*
141 * If the requested authorization is different from the current user,
142 * temporarily set the current user so that the object(s) will be created
143 * with the correct ownership.
144 *
145 * (The setting will be restored at the end of this routine, or in case of
146 * error, transaction abort will clean things up.)
147 */
148 if (saved_uid != owner_uid)
149 SetUserIdAndSecContext(owner_uid,
150 save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
151
152 /* Create the schema's namespace */
153 namespaceId = NamespaceCreate(schemaName, owner_uid, false);
154
155 /* Advance cmd counter to make the namespace visible */
157
158 /*
159 * Prepend the new schema to the current search path.
160 *
161 * We use the equivalent of a function SET option to allow the setting to
162 * persist for exactly the duration of the schema creation. guc.c also
163 * takes care of undoing the setting on error.
164 */
165 save_nestlevel = NewGUCNestLevel();
166
167 initStringInfo(&pathbuf);
168 appendStringInfoString(&pathbuf, quote_identifier(schemaName));
169
170 while (scanner_isspace(*nsp))
171 nsp++;
172
173 if (*nsp != '0円')
174 appendStringInfo(&pathbuf, ", %s", nsp);
175
176 (void) set_config_option("search_path", pathbuf.data,
178 GUC_ACTION_SAVE, true, 0, false);
179
180 /*
181 * Report the new schema to possibly interested event triggers. Note we
182 * must do this here and not in ProcessUtilitySlow because otherwise the
183 * objects created below are reported before the schema, which would be
184 * wrong.
185 */
186 ObjectAddressSet(address, NamespaceRelationId, namespaceId);
188 (Node *) stmt);
189
190 /*
191 * Examine the list of commands embedded in the CREATE SCHEMA command, and
192 * reorganize them into a sequentially executable order with no forward
193 * references. Note that the result is still a list of raw parsetrees ---
194 * we cannot, in general, run parse analysis on one statement until we
195 * have actually executed the prior ones.
196 */
197 parsetree_list = transformCreateSchemaStmtElements(stmt->schemaElts,
198 schemaName);
199
200 /*
201 * Execute each command contained in the CREATE SCHEMA. Since the grammar
202 * allows only utility commands in CREATE SCHEMA, there is no need to pass
203 * them through parse_analyze_*() or the rewriter; we can just hand them
204 * straight to ProcessUtility.
205 */
206 foreach(parsetree_item, parsetree_list)
207 {
208 Node *stmt = (Node *) lfirst(parsetree_item);
209 PlannedStmt *wrapper;
210
211 /* need to make a wrapper PlannedStmt */
212 wrapper = makeNode(PlannedStmt);
213 wrapper->commandType = CMD_UTILITY;
214 wrapper->canSetTag = false;
215 wrapper->utilityStmt = stmt;
216 wrapper->stmt_location = stmt_location;
217 wrapper->stmt_len = stmt_len;
219
220 /* do this step */
221 ProcessUtility(wrapper,
222 queryString,
223 false,
225 NULL,
226 NULL,
228 NULL);
229
230 /* make sure later steps can see the object created here */
232 }
233
234 /*
235 * Restore the GUC variable search_path we set above.
236 */
237 AtEOXact_GUC(true, save_nestlevel);
238
239 /* Reset current user and security context */
240 SetUserIdAndSecContext(saved_uid, save_sec_context);
241
242 return namespaceId;
243}
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5586
#define OidIsValid(objectId)
Definition: c.h:774
bool IsReservedName(const char *name)
Definition: catalog.c:278
DestReceiver * None_Receiver
Definition: dest.c:96
int errdetail(const char *fmt,...)
Definition: elog.c:1207
#define NOTICE
Definition: elog.h:35
void EventTriggerCollectSimpleCommand(ObjectAddress address, ObjectAddress secondaryObject, Node *parsetree)
bool allowSystemTableMods
Definition: globals.c:130
int NewGUCNestLevel(void)
Definition: guc.c:2240
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2267
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
Definition: guc.c:3347
@ GUC_ACTION_SAVE
Definition: guc.h:205
@ PGC_S_SESSION
Definition: guc.h:126
@ PGC_USERSET
Definition: guc.h:79
#define stmt
Definition: indent_codes.h:59
char * pstrdup(const char *in)
Definition: mcxt.c:1759
#define SECURITY_LOCAL_USERID_CHANGE
Definition: miscadmin.h:317
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:612
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:619
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3605
char * namespace_search_path
Definition: namespace.c:210
@ CMD_UTILITY
Definition: nodes.h:280
#define makeNode(_type_)
Definition: nodes.h:161
const ObjectAddress InvalidObjectAddress
Definition: objectaddress.c:836
List * transformCreateSchemaStmtElements(List *schemaElts, const char *schemaName)
NameData rolname
Definition: pg_authid.h:34
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void checkMembershipInCurrentExtension(const ObjectAddress *object)
Definition: pg_depend.c:258
#define lfirst(lc)
Definition: pg_list.h:172
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:43
@ PLAN_STMT_INTERNAL
Definition: plannodes.h:40
#define InvalidOid
Definition: postgres_ext.h:37
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:13035
bool scanner_isspace(char ch)
Definition: scansup.c:117
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
Definition: pg_list.h:54
Definition: nodes.h:135
bool canSetTag
Definition: plannodes.h:86
ParseLoc stmt_len
Definition: plannodes.h:156
PlannedStmtOrigin planOrigin
Definition: plannodes.h:77
ParseLoc stmt_location
Definition: plannodes.h:154
CmdType commandType
Definition: plannodes.h:68
Node * utilityStmt
Definition: plannodes.h:150
char * data
Definition: stringinfo.h:48
Definition: pg_list.h:46
void ProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
Definition: utility.c:499
@ PROCESS_UTILITY_SUBCOMMAND
Definition: utility.h:26
void CommandCounterIncrement(void)
Definition: xact.c:1100

References ACL_CREATE, aclcheck_error(), ACLCHECK_OK, allowSystemTableMods, appendStringInfo(), appendStringInfoString(), AtEOXact_GUC(), PlannedStmt::canSetTag, check_can_set_role(), checkMembershipInCurrentExtension(), CMD_UTILITY, CommandCounterIncrement(), PlannedStmt::commandType, StringInfoData::data, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, EventTriggerCollectSimpleCommand(), get_database_name(), get_namespace_oid(), get_rolespec_oid(), GETSTRUCT(), GetUserIdAndSecContext(), GUC_ACTION_SAVE, HeapTupleIsValid, initStringInfo(), InvalidObjectAddress, InvalidOid, IsReservedName(), lfirst, makeNode, MyDatabaseId, namespace_search_path, NamespaceCreate(), NameStr, NewGUCNestLevel(), None_Receiver, NOTICE, object_aclcheck(), OBJECT_DATABASE, ObjectAddressSet, ObjectIdGetDatum(), OidIsValid, PGC_S_SESSION, PGC_USERSET, PLAN_STMT_INTERNAL, PlannedStmt::planOrigin, PROCESS_UTILITY_SUBCOMMAND, ProcessUtility(), pstrdup(), quote_identifier(), ReleaseSysCache(), rolname, scanner_isspace(), SearchSysCache1(), SECURITY_LOCAL_USERID_CHANGE, set_config_option(), SetUserIdAndSecContext(), stmt, PlannedStmt::stmt_len, PlannedStmt::stmt_location, transformCreateSchemaStmtElements(), and PlannedStmt::utilityStmt.

Referenced by CreateExtensionInternal(), and ProcessUtilitySlow().

RenameSchema()

ObjectAddress RenameSchema ( const char *  oldname,
const char *  newname 
)

Definition at line 250 of file schemacmds.c.

251{
252 Oid nspOid;
253 HeapTuple tup;
254 Relation rel;
255 AclResult aclresult;
256 ObjectAddress address;
257 Form_pg_namespace nspform;
258
259 rel = table_open(NamespaceRelationId, RowExclusiveLock);
260
261 tup = SearchSysCacheCopy1(NAMESPACENAME, CStringGetDatum(oldname));
262 if (!HeapTupleIsValid(tup))
264 (errcode(ERRCODE_UNDEFINED_SCHEMA),
265 errmsg("schema \"%s\" does not exist", oldname)));
266
267 nspform = (Form_pg_namespace) GETSTRUCT(tup);
268 nspOid = nspform->oid;
269
270 /* make sure the new name doesn't exist */
271 if (OidIsValid(get_namespace_oid(newname, true)))
273 (errcode(ERRCODE_DUPLICATE_SCHEMA),
274 errmsg("schema \"%s\" already exists", newname)));
275
276 /* must be owner */
277 if (!object_ownercheck(NamespaceRelationId, nspOid, GetUserId()))
279 oldname);
280
281 /* must have CREATE privilege on database */
282 aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE);
283 if (aclresult != ACLCHECK_OK)
286
287 if (!allowSystemTableMods && IsReservedName(newname))
289 (errcode(ERRCODE_RESERVED_NAME),
290 errmsg("unacceptable schema name \"%s\"", newname),
291 errdetail("The prefix \"pg_\" is reserved for system schemas.")));
292
293 /* rename */
294 namestrcpy(&nspform->nspname, newname);
295 CatalogTupleUpdate(rel, &tup->t_self, tup);
296
297 InvokeObjectPostAlterHook(NamespaceRelationId, nspOid, 0);
298
299 ObjectAddressSet(address, NamespaceRelationId, nspOid);
300
301 table_close(rel, NoLock);
302 heap_freetuple(tup);
303
304 return address;
305}
#define NoLock
Definition: lockdefs.h:34
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:91

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, allowSystemTableMods, CatalogTupleUpdate(), CStringGetDatum(), ereport, errcode(), errdetail(), errmsg(), ERROR, get_database_name(), get_namespace_oid(), GETSTRUCT(), GetUserId(), heap_freetuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, IsReservedName(), MyDatabaseId, namestrcpy(), NoLock, object_aclcheck(), OBJECT_DATABASE, object_ownercheck(), OBJECT_SCHEMA, ObjectAddressSet, OidIsValid, RowExclusiveLock, SearchSysCacheCopy1, HeapTupleData::t_self, table_close(), and table_open().

Referenced by ExecRenameStmt().

AltStyle によって変換されたページ (->オリジナル) /