#include "nodes/parsenodes.h"

Go to the source code of this file.
Functions | |
| Oid | CreateSchemaCommand (CreateSchemaStmt *parsetree, const char *queryString) |
| void | RemoveSchemaById (Oid schemaOid) |
| Oid | RenameSchema (const char *oldname, const char *newname) |
| Oid | AlterSchemaOwner (const char *name, Oid newOwnerId) |
| void | AlterSchemaOwner_oid (Oid schemaOid, Oid newOwnerId) |
Definition at line 276 of file schemacmds.c.
References AlterSchemaOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, NAMESPACENAME, NamespaceRelationId, ReleaseSysCache(), RowExclusiveLock, and SearchSysCache1.
Referenced by ExecAlterOwnerStmt().
{
Oid nspOid;
HeapTuple tup;
Relation rel;
rel = heap_open(NamespaceRelationId, RowExclusiveLock);
tup = SearchSysCache1(NAMESPACENAME, CStringGetDatum(name));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema \"%s\" does not exist", name)));
nspOid = HeapTupleGetOid(tup);
AlterSchemaOwner_internal(tup, rel, newOwnerId);
ReleaseSysCache(tup);
heap_close(rel, RowExclusiveLock);
return nspOid;
}
Definition at line 253 of file schemacmds.c.
References AlterSchemaOwner_internal(), elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, NAMESPACEOID, NamespaceRelationId, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, and SearchSysCache1.
Referenced by shdepReassignOwned().
{
HeapTuple tup;
Relation rel;
rel = heap_open(NamespaceRelationId, RowExclusiveLock);
tup = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(oid));
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for schema %u", oid);
AlterSchemaOwner_internal(tup, rel, newOwnerId);
ReleaseSysCache(tup);
heap_close(rel, RowExclusiveLock);
}
| Oid CreateSchemaCommand | ( | CreateSchemaStmt * | parsetree, | |
| const char * | queryString | |||
| ) |
Definition at line 43 of file schemacmds.c.
References ACL_CREATE, ACL_KIND_DATABASE, aclcheck_error(), ACLCHECK_OK, allowSystemTableMods, CreateSchemaStmt::authid, check_is_member_of_role(), CommandCounterIncrement(), CurrentMemoryContext, ereport, errcode(), errdetail(), errmsg(), ERROR, get_database_name(), get_role_oid(), GetOverrideSearchPath(), GetUserIdAndSecContext(), CreateSchemaStmt::if_not_exists, IsReservedName(), lcons_oid(), lfirst, MyDatabaseId, NamespaceCreate(), NAMESPACENAME, None_Receiver, NOTICE, NULL, pg_database_aclcheck(), PointerGetDatum, PopOverrideSearchPath(), PROCESS_UTILITY_SUBCOMMAND, ProcessUtility(), PushOverrideSearchPath(), CreateSchemaStmt::schemaname, OverrideSearchPath::schemas, SearchSysCacheExists1, SECURITY_LOCAL_USERID_CHANGE, SetUserIdAndSecContext(), and transformCreateSchemaStmt().
Referenced by CreateExtension(), and ProcessUtilitySlow().
{
const char *schemaName = stmt->schemaname;
const char *authId = stmt->authid;
Oid namespaceId;
OverrideSearchPath *overridePath;
List *parsetree_list;
ListCell *parsetree_item;
Oid owner_uid;
Oid saved_uid;
int save_sec_context;
AclResult aclresult;
GetUserIdAndSecContext(&saved_uid, &save_sec_context);
/*
* Who is supposed to own the new schema?
*/
if (authId)
owner_uid = get_role_oid(authId, false);
else
owner_uid = saved_uid;
/*
* To create a schema, must have schema-create privilege on the current
* database and must be able to become the target role (this does not
* imply that the target role itself must have create-schema privilege).
* The latter provision guards against "giveaway" attacks. Note that a
* superuser will always have both of these privileges a fortiori.
*/
aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_DATABASE,
get_database_name(MyDatabaseId));
check_is_member_of_role(saved_uid, owner_uid);
/* Additional check to protect reserved schema names */
if (!allowSystemTableMods && IsReservedName(schemaName))
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("unacceptable schema name \"%s\"", schemaName),
errdetail("The prefix \"pg_\" is reserved for system schemas.")));
/*
* If if_not_exists was given and the schema already exists, bail out.
* (Note: we needn't check this when not if_not_exists, because
* NamespaceCreate will complain anyway.) We could do this before making
* the permissions checks, but since CREATE TABLE IF NOT EXISTS makes its
* creation-permission check first, we do likewise.
*/
if (stmt->if_not_exists &&
SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(schemaName)))
{
ereport(NOTICE,
(errcode(ERRCODE_DUPLICATE_SCHEMA),
errmsg("schema \"%s\" already exists, skipping",
schemaName)));
return InvalidOid;
}
/*
* If the requested authorization is different from the current user,
* temporarily set the current user so that the object(s) will be created
* with the correct ownership.
*
* (The setting will be restored at the end of this routine, or in case of
* error, transaction abort will clean things up.)
*/
if (saved_uid != owner_uid)
SetUserIdAndSecContext(owner_uid,
save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
/* Create the schema's namespace */
namespaceId = NamespaceCreate(schemaName, owner_uid, false);
/* Advance cmd counter to make the namespace visible */
CommandCounterIncrement();
/*
* Temporarily make the new namespace be the front of the search path, as
* well as the default creation target namespace. This will be undone at
* the end of this routine, or upon error.
*/
overridePath = GetOverrideSearchPath(CurrentMemoryContext);
overridePath->schemas = lcons_oid(namespaceId, overridePath->schemas);
/* XXX should we clear overridePath->useTemp? */
PushOverrideSearchPath(overridePath);
/*
* Examine the list of commands embedded in the CREATE SCHEMA command, and
* reorganize them into a sequentially executable order with no forward
* references. Note that the result is still a list of raw parsetrees ---
* we cannot, in general, run parse analysis on one statement until we
* have actually executed the prior ones.
*/
parsetree_list = transformCreateSchemaStmt(stmt);
/*
* Execute each command contained in the CREATE SCHEMA. Since the grammar
* allows only utility commands in CREATE SCHEMA, there is no need to pass
* them through parse_analyze() or the rewriter; we can just hand them
* straight to ProcessUtility.
*/
foreach(parsetree_item, parsetree_list)
{
Node *stmt = (Node *) lfirst(parsetree_item);
/* do this step */
ProcessUtility(stmt,
queryString,
PROCESS_UTILITY_SUBCOMMAND,
NULL,
None_Receiver,
NULL);
/* make sure later steps can see the object created here */
CommandCounterIncrement();
}
/* Reset search path to normal state */
PopOverrideSearchPath();
/* Reset current user and security context */
SetUserIdAndSecContext(saved_uid, save_sec_context);
return namespaceId;
}
| void RemoveSchemaById | ( | Oid | schemaOid | ) |
Definition at line 175 of file schemacmds.c.
References elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, NAMESPACEOID, NamespaceRelationId, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, simple_heap_delete(), and HeapTupleData::t_self.
Referenced by doDeletion().
{
Relation relation;
HeapTuple tup;
relation = heap_open(NamespaceRelationId, RowExclusiveLock);
tup = SearchSysCache1(NAMESPACEOID,
ObjectIdGetDatum(schemaOid));
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "cache lookup failed for namespace %u", schemaOid);
simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock);
}
| Oid RenameSchema | ( | const char * | oldname, | |
| const char * | newname | |||
| ) |
Definition at line 199 of file schemacmds.c.
References ACL_CREATE, ACL_KIND_DATABASE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, allowSystemTableMods, CatalogUpdateIndexes(), 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, OidIsValid, pg_database_aclcheck(), pg_namespace_ownercheck(), RowExclusiveLock, SearchSysCacheCopy1, simple_heap_update(), and HeapTupleData::t_self.
Referenced by ExecRenameStmt().
{
Oid nspOid;
HeapTuple tup;
Relation rel;
AclResult aclresult;
rel = heap_open(NamespaceRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(NAMESPACENAME, CStringGetDatum(oldname));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema \"%s\" does not exist", oldname)));
nspOid = HeapTupleGetOid(tup);
/* make sure the new name doesn't exist */
if (OidIsValid(get_namespace_oid(newname, true)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_SCHEMA),
errmsg("schema \"%s\" already exists", newname)));
/* must be owner */
if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE,
oldname);
/* must have CREATE privilege on database */
aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_DATABASE,
get_database_name(MyDatabaseId));
if (!allowSystemTableMods && IsReservedName(newname))
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("unacceptable schema name \"%s\"", newname),
errdetail("The prefix \"pg_\" is reserved for system schemas.")));
/* rename */
namestrcpy(&(((Form_pg_namespace) GETSTRUCT(tup))->nspname), newname);
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
InvokeObjectPostAlterHook(NamespaceRelationId, HeapTupleGetOid(tup), 0);
heap_close(rel, NoLock);
heap_freetuple(tup);
return nspOid;
}
1.7.1