|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.49 2008/01/03 21:23:15 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.50 2008/06/14 18:04:33 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -148,57 +148,76 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
|
148 | 148 |
|
149 | 149 |
|
150 | 150 | /*
|
151 |
| - * RemoveSchema |
152 |
| - * Removes a schema. |
| 151 | + * RemoveSchemas |
| 152 | + * Implements DROP SCHEMA. |
153 | 153 | */
|
154 | 154 | void
|
155 |
| -RemoveSchema(List *names, DropBehavior behavior, bool missing_ok) |
| 155 | +RemoveSchemas(DropStmt *drop) |
156 | 156 | {
|
157 |
| - char *namespaceName; |
158 |
| - Oid namespaceId; |
159 |
| - ObjectAddress object; |
| 157 | + ObjectAddresses *objects; |
| 158 | + ListCell *cell; |
160 | 159 |
|
161 |
| - if (list_length(names) != 1) |
162 |
| - ereport(ERROR, |
163 |
| - (errcode(ERRCODE_SYNTAX_ERROR), |
164 |
| - errmsg("schema name cannot be qualified"))); |
165 |
| - namespaceName = strVal(linitial(names)); |
166 |
| - |
167 |
| - namespaceId = GetSysCacheOid(NAMESPACENAME, |
168 |
| - CStringGetDatum(namespaceName), |
169 |
| - 0, 0, 0); |
170 |
| - if (!OidIsValid(namespaceId)) |
| 160 | + /* |
| 161 | + * First we identify all the schemas, then we delete them in a single |
| 162 | + * performMultipleDeletions() call. This is to avoid unwanted |
| 163 | + * DROP RESTRICT errors if one of the schemas depends on another. |
| 164 | + */ |
| 165 | + objects = new_object_addresses(); |
| 166 | + |
| 167 | + foreach(cell, drop->objects) |
171 | 168 | {
|
172 |
| - if (!missing_ok) |
173 |
| - { |
| 169 | + List *names = (List *) lfirst(cell); |
| 170 | + char *namespaceName; |
| 171 | + Oid namespaceId; |
| 172 | + ObjectAddress object; |
| 173 | + |
| 174 | + if (list_length(names) != 1) |
174 | 175 | ereport(ERROR,
|
175 |
| - (errcode(ERRCODE_UNDEFINED_SCHEMA), |
176 |
| - errmsg("schema \"%s\" does not exist", namespaceName))); |
177 |
| - } |
178 |
| - else |
| 176 | + (errcode(ERRCODE_SYNTAX_ERROR), |
| 177 | + errmsg("schema name cannot be qualified"))); |
| 178 | + namespaceName = strVal(linitial(names)); |
| 179 | + |
| 180 | + namespaceId = GetSysCacheOid(NAMESPACENAME, |
| 181 | + CStringGetDatum(namespaceName), |
| 182 | + 0, 0, 0); |
| 183 | + |
| 184 | + if (!OidIsValid(namespaceId)) |
179 | 185 | {
|
180 |
| - ereport(NOTICE, |
181 |
| - (errmsg("schema \"%s\" does not exist, skipping", |
182 |
| - namespaceName))); |
| 186 | + if (!drop->missing_ok) |
| 187 | + { |
| 188 | + ereport(ERROR, |
| 189 | + (errcode(ERRCODE_UNDEFINED_SCHEMA), |
| 190 | + errmsg("schema \"%s\" does not exist", |
| 191 | + namespaceName))); |
| 192 | + } |
| 193 | + else |
| 194 | + { |
| 195 | + ereport(NOTICE, |
| 196 | + (errmsg("schema \"%s\" does not exist, skipping", |
| 197 | + namespaceName))); |
| 198 | + } |
| 199 | + continue; |
183 | 200 | }
|
184 | 201 |
|
185 |
| - return; |
186 |
| - } |
| 202 | + /* Permission check */ |
| 203 | + if (!pg_namespace_ownercheck(namespaceId, GetUserId())) |
| 204 | + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, |
| 205 | + namespaceName); |
187 | 206 |
|
188 |
| - /* Permission check */ |
189 |
| - if (!pg_namespace_ownercheck(namespaceId, GetUserId())) |
190 |
| - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE, |
191 |
| - namespaceName); |
| 207 | + object.classId = NamespaceRelationId; |
| 208 | + object.objectId = namespaceId; |
| 209 | + object.objectSubId = 0; |
| 210 | + |
| 211 | + add_exact_object_address(&object, objects); |
| 212 | + } |
192 | 213 |
|
193 | 214 | /*
|
194 |
| - * Do the deletion. Objects contained in the schema are removed by means |
195 |
| - * of their dependency links to the schema. |
| 215 | + * Do the deletions. Objects contained in the schema(s) are removed by |
| 216 | + * means of their dependency links to the schema. |
196 | 217 | */
|
197 |
| - object.classId = NamespaceRelationId; |
198 |
| - object.objectId = namespaceId; |
199 |
| - object.objectSubId = 0; |
| 218 | + performMultipleDeletions(objects, drop->behavior); |
200 | 219 |
|
201 |
| - performDeletion(&object, behavior); |
| 220 | + free_object_addresses(objects); |
202 | 221 | }
|
203 | 222 |
|
204 | 223 |
|
|
0 commit comments