1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
/*-------------------------------------------------------------------------
*
* schemacmds.c
* schema creation command support code
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.4 2002/06/11 13:40:50 wieck Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_namespace.h"
#include "commands/schemacmds.h"
#include "miscadmin.h"
#include "parser/analyze.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/lsyscache.h"
/*
* CREATE SCHEMA
*/
void
CreateSchemaCommand(CreateSchemaStmt *stmt)
{
const char *schemaName = stmt->schemaname;
const char *authId = stmt->authid;
Oid namespaceId;
List *parsetree_list;
List *parsetree_item;
const char *owner_name;
Oid owner_userid;
Oid saved_userid;
AclResult aclresult;
saved_userid = GetUserId();
/*
* Figure out user identities.
*/
if (!authId)
{
owner_userid = saved_userid;
owner_name = GetUserNameFromId(owner_userid);
}
else if (superuser())
{
owner_name = authId;
/* The following will error out if user does not exist */
owner_userid = get_usesysid(owner_name);
/*
* Set the current user to the requested authorization so
* that objects created in the statement have the requested
* owner. (This will revert to session user on error or at
* the end of this routine.)
*/
SetUserId(owner_userid);
}
else /* not superuser */
{
owner_userid = saved_userid;
owner_name = GetUserNameFromId(owner_userid);
if (strcmp(authId, owner_name) != 0)
elog(ERROR, "CREATE SCHEMA: permission denied"
"\n\t\"%s\" is not a superuser, so cannot create a schema for \"%s\"",
owner_name, authId);
}
/*
* Permissions checks.
*/
aclresult = pg_database_aclcheck(MyDatabaseId, saved_userid, ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, DatabaseName);
if (!allowSystemTableMods && IsReservedName(schemaName))
elog(ERROR, "CREATE SCHEMA: Illegal schema name: \"%s\" -- pg_ is reserved for system schemas",
schemaName);
/* Create the schema's namespace */
namespaceId = NamespaceCreate(schemaName, owner_userid);
/* 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.
*/
PushSpecialNamespace(namespaceId);
/*
* 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 in need of parse analysis --- we cannot, in general,
* run analyze.c on one statement until we have actually executed the
* prior ones.
*/
parsetree_list = analyzeCreateSchemaStmt(stmt);
/*
* Analyze and execute each command contained in the CREATE SCHEMA
*/
foreach(parsetree_item, parsetree_list)
{
Node *parsetree = (Node *) lfirst(parsetree_item);
List *querytree_list,
*querytree_item;
querytree_list = parse_analyze(parsetree, NULL);
foreach(querytree_item, querytree_list)
{
Query *querytree = (Query *) lfirst(querytree_item);
/* schemas should contain only utility stmts */
Assert(querytree->commandType == CMD_UTILITY);
/* do this step */
ProcessUtility(querytree->utilityStmt, None, NULL);
/* make sure later steps can see the object created here */
CommandCounterIncrement();
}
}
/* Reset search path to normal state */
PopSpecialNamespace(namespaceId);
/* Reset current user */
SetUserId(saved_userid);
}
|