PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
schemacmds.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/heapam.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace.h"
#include "commands/dbcommands.h"
#include "commands/event_trigger.h"
#include "commands/schemacmds.h"
#include "miscadmin.h"
#include "parser/parse_utilcmd.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/builtins.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)
 
void RemoveSchemaById (Oid schemaOid)
 
ObjectAddress RenameSchema (const char *oldname, const char *newname)
 
void AlterSchemaOwner_oid (Oid oid, Oid newOwnerId)
 
ObjectAddress AlterSchemaOwner (const char *name, Oid newOwnerId)
 

Function Documentation

ObjectAddress AlterSchemaOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 320 of file schemacmds.c.

References AlterSchemaOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, NAMESPACENAME, NamespaceRelationId, ObjectAddressSet, ReleaseSysCache(), RowExclusiveLock, and SearchSysCache1.

Referenced by ExecAlterOwnerStmt().

321 {
322  Oid nspOid;
323  HeapTuple tup;
324  Relation rel;
325  ObjectAddress address;
326 
328 
330  if (!HeapTupleIsValid(tup))
331  ereport(ERROR,
332  (errcode(ERRCODE_UNDEFINED_SCHEMA),
333  errmsg("schema \"%s\" does not exist", name)));
334 
335  nspOid = HeapTupleGetOid(tup);
336 
337  AlterSchemaOwner_internal(tup, rel, newOwnerId);
338 
339  ObjectAddressSet(address, NamespaceRelationId, nspOid);
340 
341  ReleaseSysCache(tup);
342 
344 
345  return address;
346 }
static void AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
Definition: schemacmds.c:349
#define NamespaceRelationId
Definition: pg_namespace.h:34
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
const char * name
Definition: encode.c:521
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void AlterSchemaOwner_internal ( HeapTuple  tup,
Relation  rel,
Oid  newOwnerId 
)
static

Definition at line 349 of file schemacmds.c.

References ACL_CREATE, ACL_KIND_DATABASE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, aclnewowner(), Anum_pg_namespace_nspacl, Anum_pg_namespace_nspowner, Assert, CatalogTupleUpdate(), changeDependencyOnOwner(), check_is_member_of_role(), DatumGetAclP, get_database_name(), GETSTRUCT, GetUserId(), heap_freetuple(), heap_modify_tuple(), HeapTupleGetOid, InvokeObjectPostAlterHook, MyDatabaseId, NAMESPACENAME, NamespaceRelationId, NameStr, Natts_pg_namespace, ObjectIdGetDatum, pg_database_aclcheck(), pg_namespace_ownercheck(), PointerGetDatum, RelationGetDescr, RelationGetRelid, SysCacheGetAttr(), HeapTupleData::t_self, and HeapTupleData::t_tableOid.

Referenced by AlterSchemaOwner(), and AlterSchemaOwner_oid().

350 {
351  Form_pg_namespace nspForm;
352 
355 
356  nspForm = (Form_pg_namespace) GETSTRUCT(tup);
357 
358  /*
359  * If the new owner is the same as the existing owner, consider the
360  * command to have succeeded. This is for dump restoration purposes.
361  */
362  if (nspForm->nspowner != newOwnerId)
363  {
364  Datum repl_val[Natts_pg_namespace];
365  bool repl_null[Natts_pg_namespace];
366  bool repl_repl[Natts_pg_namespace];
367  Acl *newAcl;
368  Datum aclDatum;
369  bool isNull;
370  HeapTuple newtuple;
371  AclResult aclresult;
372 
373  /* Otherwise, must be owner of the existing object */
376  NameStr(nspForm->nspname));
377 
378  /* Must be able to become new owner */
379  check_is_member_of_role(GetUserId(), newOwnerId);
380 
381  /*
382  * must have create-schema rights
383  *
384  * NOTE: This is different from other alter-owner checks in that the
385  * current user is checked for create privileges instead of the
386  * destination owner. This is consistent with the CREATE case for
387  * schemas. Because superusers will always have this right, we need
388  * no special case for them.
389  */
391  ACL_CREATE);
392  if (aclresult != ACLCHECK_OK)
395 
396  memset(repl_null, false, sizeof(repl_null));
397  memset(repl_repl, false, sizeof(repl_repl));
398 
399  repl_repl[Anum_pg_namespace_nspowner - 1] = true;
400  repl_val[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(newOwnerId);
401 
402  /*
403  * Determine the modified ACL for the new owner. This is only
404  * necessary when the ACL is non-null.
405  */
406  aclDatum = SysCacheGetAttr(NAMESPACENAME, tup,
408  &isNull);
409  if (!isNull)
410  {
411  newAcl = aclnewowner(DatumGetAclP(aclDatum),
412  nspForm->nspowner, newOwnerId);
413  repl_repl[Anum_pg_namespace_nspacl - 1] = true;
414  repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl);
415  }
416 
417  newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
418 
419  CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
420 
421  heap_freetuple(newtuple);
422 
423  /* Update owner dependency reference */
425  newOwnerId);
426  }
427 
429  HeapTupleGetOid(tup), 0);
430 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:51
#define RelationGetDescr(relation)
Definition: rel.h:425
Oid GetUserId(void)
Definition: miscinit.c:283
#define DatumGetAclP(X)
Definition: acl.h:113
#define PointerGetDatum(X)
Definition: postgres.h:564
bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
Definition: aclchk.c:4697
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:303
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ACL_CREATE
Definition: parsenodes.h:75
ItemPointerData t_self
Definition: htup.h:65
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2049
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
Oid t_tableOid
Definition: htup.h:66
void check_is_member_of_role(Oid member, Oid role)
Definition: acl.c:4877
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:374
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Oid MyDatabaseId
Definition: globals.c:76
#define Natts_pg_namespace
Definition: pg_namespace.h:58
#define Anum_pg_namespace_nspacl
Definition: pg_namespace.h:61
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4409
#define Assert(condition)
Definition: c.h:670
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define Anum_pg_namespace_nspowner
Definition: pg_namespace.h:60
#define NameStr(name)
Definition: c.h:494
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1036
#define RelationGetRelid(relation)
Definition: rel.h:413
void AlterSchemaOwner_oid ( Oid  oid,
Oid  newOwnerId 
)

Definition at line 297 of file schemacmds.c.

References AlterSchemaOwner_internal(), elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, NAMESPACEOID, NamespaceRelationId, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, and SearchSysCache1.

Referenced by shdepReassignOwned().

298 {
299  HeapTuple tup;
300  Relation rel;
301 
303 
305  if (!HeapTupleIsValid(tup))
306  elog(ERROR, "cache lookup failed for schema %u", oid);
307 
308  AlterSchemaOwner_internal(tup, rel, newOwnerId);
309 
310  ReleaseSysCache(tup);
311 
313 }
static void AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
Definition: schemacmds.c:349
#define NamespaceRelationId
Definition: pg_namespace.h:34
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
Oid CreateSchemaCommand ( CreateSchemaStmt stmt,
const char *  queryString,
int  stmt_location,
int  stmt_len 
)

Definition at line 51 of file schemacmds.c.

References ACL_CREATE, ACL_KIND_DATABASE, aclcheck_error(), ACLCHECK_OK, allowSystemTableMods, AUTHOID, CreateSchemaStmt::authrole, PlannedStmt::canSetTag, check_is_member_of_role(), CMD_UTILITY, CommandCounterIncrement(), PlannedStmt::commandType, CurrentMemoryContext, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, EventTriggerCollectSimpleCommand(), get_database_name(), get_rolespec_oid(), GetOverrideSearchPath(), GETSTRUCT, GetUserIdAndSecContext(), HeapTupleIsValid, CreateSchemaStmt::if_not_exists, InvalidObjectAddress, InvalidOid, IsReservedName(), lcons_oid(), lfirst, makeNode, MyDatabaseId, NamespaceCreate(), NAMESPACENAME, NamespaceRelationId, NameStr, None_Receiver, NOTICE, NULL, ObjectAddressSet, ObjectIdGetDatum, pg_database_aclcheck(), PointerGetDatum, PopOverrideSearchPath(), PROCESS_UTILITY_SUBCOMMAND, ProcessUtility(), pstrdup(), PushOverrideSearchPath(), ReleaseSysCache(), CreateSchemaStmt::schemaname, OverrideSearchPath::schemas, SearchSysCache1, SearchSysCacheExists1, SECURITY_LOCAL_USERID_CHANGE, SetUserIdAndSecContext(), prepared_statement::stmt, PlannedStmt::stmt_len, PlannedStmt::stmt_location, transformCreateSchemaStmt(), and PlannedStmt::utilityStmt.

Referenced by CreateExtensionInternal(), and ProcessUtilitySlow().

53 {
54  const char *schemaName = stmt->schemaname;
55  Oid namespaceId;
56  OverrideSearchPath *overridePath;
57  List *parsetree_list;
58  ListCell *parsetree_item;
59  Oid owner_uid;
60  Oid saved_uid;
61  int save_sec_context;
62  AclResult aclresult;
63  ObjectAddress address;
64 
65  GetUserIdAndSecContext(&saved_uid, &save_sec_context);
66 
67  /*
68  * Who is supposed to own the new schema?
69  */
70  if (stmt->authrole)
71  owner_uid = get_rolespec_oid(stmt->authrole, false);
72  else
73  owner_uid = saved_uid;
74 
75  /* fill schema name with the user name if not specified */
76  if (!schemaName)
77  {
78  HeapTuple tuple;
79 
80  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(owner_uid));
81  if (!HeapTupleIsValid(tuple))
82  elog(ERROR, "cache lookup failed for role %u", owner_uid);
83  schemaName =
84  pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
85  ReleaseSysCache(tuple);
86  }
87 
88  /*
89  * To create a schema, must have schema-create privilege on the current
90  * database and must be able to become the target role (this does not
91  * imply that the target role itself must have create-schema privilege).
92  * The latter provision guards against "giveaway" attacks. Note that a
93  * superuser will always have both of these privileges a fortiori.
94  */
95  aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE);
96  if (aclresult != ACLCHECK_OK)
99 
100  check_is_member_of_role(saved_uid, owner_uid);
101 
102  /* Additional check to protect reserved schema names */
103  if (!allowSystemTableMods && IsReservedName(schemaName))
104  ereport(ERROR,
105  (errcode(ERRCODE_RESERVED_NAME),
106  errmsg("unacceptable schema name \"%s\"", schemaName),
107  errdetail("The prefix \"pg_\" is reserved for system schemas.")));
108 
109  /*
110  * If if_not_exists was given and the schema already exists, bail out.
111  * (Note: we needn't check this when not if_not_exists, because
112  * NamespaceCreate will complain anyway.) We could do this before making
113  * the permissions checks, but since CREATE TABLE IF NOT EXISTS makes its
114  * creation-permission check first, we do likewise.
115  */
116  if (stmt->if_not_exists &&
118  {
119  ereport(NOTICE,
120  (errcode(ERRCODE_DUPLICATE_SCHEMA),
121  errmsg("schema \"%s\" already exists, skipping",
122  schemaName)));
123  return InvalidOid;
124  }
125 
126  /*
127  * If the requested authorization is different from the current user,
128  * temporarily set the current user so that the object(s) will be created
129  * with the correct ownership.
130  *
131  * (The setting will be restored at the end of this routine, or in case of
132  * error, transaction abort will clean things up.)
133  */
134  if (saved_uid != owner_uid)
135  SetUserIdAndSecContext(owner_uid,
136  save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
137 
138  /* Create the schema's namespace */
139  namespaceId = NamespaceCreate(schemaName, owner_uid, false);
140 
141  /* Advance cmd counter to make the namespace visible */
143 
144  /*
145  * Temporarily make the new namespace be the front of the search path, as
146  * well as the default creation target namespace. This will be undone at
147  * the end of this routine, or upon error.
148  */
150  overridePath->schemas = lcons_oid(namespaceId, overridePath->schemas);
151  /* XXX should we clear overridePath->useTemp? */
152  PushOverrideSearchPath(overridePath);
153 
154  /*
155  * Report the new schema to possibly interested event triggers. Note we
156  * must do this here and not in ProcessUtilitySlow because otherwise the
157  * objects created below are reported before the schema, which would be
158  * wrong.
159  */
160  ObjectAddressSet(address, NamespaceRelationId, namespaceId);
162  (Node *) stmt);
163 
164  /*
165  * Examine the list of commands embedded in the CREATE SCHEMA command, and
166  * reorganize them into a sequentially executable order with no forward
167  * references. Note that the result is still a list of raw parsetrees ---
168  * we cannot, in general, run parse analysis on one statement until we
169  * have actually executed the prior ones.
170  */
171  parsetree_list = transformCreateSchemaStmt(stmt);
172 
173  /*
174  * Execute each command contained in the CREATE SCHEMA. Since the grammar
175  * allows only utility commands in CREATE SCHEMA, there is no need to pass
176  * them through parse_analyze() or the rewriter; we can just hand them
177  * straight to ProcessUtility.
178  */
179  foreach(parsetree_item, parsetree_list)
180  {
181  Node *stmt = (Node *) lfirst(parsetree_item);
182  PlannedStmt *wrapper;
183 
184  /* need to make a wrapper PlannedStmt */
185  wrapper = makeNode(PlannedStmt);
186  wrapper->commandType = CMD_UTILITY;
187  wrapper->canSetTag = false;
188  wrapper->utilityStmt = stmt;
189  wrapper->stmt_location = stmt_location;
190  wrapper->stmt_len = stmt_len;
191 
192  /* do this step */
193  ProcessUtility(wrapper,
194  queryString,
196  NULL,
198  NULL);
199 
200  /* make sure later steps can see the object created here */
202  }
203 
204  /* Reset search path to normal state */
206 
207  /* Reset current user and security context */
208  SetUserIdAndSecContext(saved_uid, save_sec_context);
209 
210  return namespaceId;
211 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:395
#define PointerGetDatum(X)
Definition: postgres.h:564
char * pstrdup(const char *in)
Definition: mcxt.c:1165
void PushOverrideSearchPath(OverrideSearchPath *newpath)
Definition: namespace.c:3227
Definition: nodes.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
List * lcons_oid(Oid datum, List *list)
Definition: list.c:295
unsigned int Oid
Definition: postgres_ext.h:31
bool IsReservedName(const char *name)
Definition: catalog.c:193
DestReceiver * None_Receiver
Definition: dest.c:91
int stmt_len
Definition: plannodes.h:84
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
RoleSpec * authrole
Definition: parsenodes.h:1583
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:75
OverrideSearchPath * GetOverrideSearchPath(MemoryContext context)
Definition: namespace.c:3115
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2049
int stmt_location
Definition: plannodes.h:83
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:388
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
int errdetail(const char *fmt,...)
Definition: elog.c:873
Node * utilityStmt
Definition: plannodes.h:80
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
void check_is_member_of_role(Oid member, Oid role)
Definition: acl.c:4877
#define ereport(elevel, rest)
Definition: elog.h:122
void ProcessUtility(PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, DestReceiver *dest, char *completionTag)
Definition: utility.c:332
void PopOverrideSearchPath(void)
Definition: namespace.c:3286
bool canSetTag
Definition: plannodes.h:53
AclResult
Definition: acl.h:170
CmdType commandType
Definition: plannodes.h:45
void CommandCounterIncrement(void)
Definition: xact.c:921
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Oid MyDatabaseId
Definition: globals.c:76
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5147
#define SECURITY_LOCAL_USERID_CHANGE
Definition: miscadmin.h:291
bool allowSystemTableMods
Definition: globals.c:111
#define InvalidOid
Definition: postgres_ext.h:36
#define NOTICE
Definition: elog.h:37
#define makeNode(_type_)
Definition: nodes.h:556
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4409
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
List * transformCreateSchemaStmt(CreateSchemaStmt *stmt)
const ObjectAddress InvalidObjectAddress
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:494
#define elog
Definition: elog.h:219
void EventTriggerCollectSimpleCommand(ObjectAddress address, ObjectAddress secondaryObject, Node *parsetree)
Definition: pg_list.h:45
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:41
void RemoveSchemaById ( Oid  schemaOid)

Definition at line 217 of file schemacmds.c.

References CatalogTupleDelete(), elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, NAMESPACEOID, NamespaceRelationId, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, and HeapTupleData::t_self.

Referenced by doDeletion().

218 {
219  Relation relation;
220  HeapTuple tup;
221 
223 
225  ObjectIdGetDatum(schemaOid));
226  if (!HeapTupleIsValid(tup)) /* should not happen */
227  elog(ERROR, "cache lookup failed for namespace %u", schemaOid);
228 
229  CatalogTupleDelete(relation, &tup->t_self);
230 
231  ReleaseSysCache(tup);
232 
233  heap_close(relation, RowExclusiveLock);
234 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
ObjectAddress RenameSchema ( const char *  oldname,
const char *  newname 
)

Definition at line 241 of file schemacmds.c.

References ACL_CREATE, ACL_KIND_DATABASE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, allowSystemTableMods, CatalogTupleUpdate(), CStringGetDatum, ereport, errcode(), errdetail(), errmsg(), ERROR, get_database_name(), get_namespace_oid(), GETSTRUCT, GetUserId(), heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, IsReservedName(), MyDatabaseId, NAMESPACENAME, NamespaceRelationId, namestrcpy(), NoLock, ObjectAddressSet, OidIsValid, pg_database_aclcheck(), pg_namespace_ownercheck(), RowExclusiveLock, SearchSysCacheCopy1, and HeapTupleData::t_self.

Referenced by ExecRenameStmt().

242 {
243  Oid nspOid;
244  HeapTuple tup;
245  Relation rel;
246  AclResult aclresult;
247  ObjectAddress address;
248 
250 
252  if (!HeapTupleIsValid(tup))
253  ereport(ERROR,
254  (errcode(ERRCODE_UNDEFINED_SCHEMA),
255  errmsg("schema \"%s\" does not exist", oldname)));
256 
257  nspOid = HeapTupleGetOid(tup);
258 
259  /* make sure the new name doesn't exist */
260  if (OidIsValid(get_namespace_oid(newname, true)))
261  ereport(ERROR,
262  (errcode(ERRCODE_DUPLICATE_SCHEMA),
263  errmsg("schema \"%s\" already exists", newname)));
264 
265  /* must be owner */
268  oldname);
269 
270  /* must have CREATE privilege on database */
272  if (aclresult != ACLCHECK_OK)
275 
276  if (!allowSystemTableMods && IsReservedName(newname))
277  ereport(ERROR,
278  (errcode(ERRCODE_RESERVED_NAME),
279  errmsg("unacceptable schema name \"%s\"", newname),
280  errdetail("The prefix \"pg_\" is reserved for system schemas.")));
281 
282  /* rename */
283  namestrcpy(&(((Form_pg_namespace) GETSTRUCT(tup))->nspname), newname);
284  CatalogTupleUpdate(rel, &tup->t_self, tup);
285 
287 
288  ObjectAddressSet(address, NamespaceRelationId, nspOid);
289 
290  heap_close(rel, NoLock);
291  heap_freetuple(tup);
292 
293  return address;
294 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:51
Oid GetUserId(void)
Definition: miscinit.c:283
int errcode(int sqlerrcode)
Definition: elog.c:575
bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
Definition: aclchk.c:4697
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
bool IsReservedName(const char *name)
Definition: catalog.c:193
int namestrcpy(Name name, const char *str)
Definition: name.c:217
#define OidIsValid(objectId)
Definition: c.h:533
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:75
ItemPointerData t_self
Definition: htup.h:65
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2049
#define NoLock
Definition: lockdefs.h:34
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
AclResult
Definition: acl.h:170
Oid MyDatabaseId
Definition: globals.c:76
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
bool allowSystemTableMods
Definition: globals.c:111
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4409
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695