|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.134 2004/10/12 21:54:36 petere Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.135 2004/10/16 21:16:36 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -168,6 +168,7 @@ static void StoreCatalogInheritance(Oid relationId, List *supers);
|
168 | 168 | static int findAttrByName(const char *attributeName, List *schema);
|
169 | 169 | static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
|
170 | 170 | static bool needs_toast_table(Relation rel);
|
| 171 | +static void check_tablespace_exists(Oid tablespaceId, Oid namespaceId); |
171 | 172 | static int transformColumnNameList(Oid relId, List *colList,
|
172 | 173 | int16 *attnums, Oid *atttypids);
|
173 | 174 | static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
|
@@ -337,6 +338,9 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
337 | 338 | {
|
338 | 339 | tablespaceId = get_namespace_tablespace(namespaceId);
|
339 | 340 | /* note no permission check on tablespace in this case */
|
| 341 | + /* check to see that schema's tablespace still exists */ |
| 342 | + if (OidIsValid(tablespaceId)) |
| 343 | + check_tablespace_exists(tablespaceId, namespaceId); |
340 | 344 | }
|
341 | 345 |
|
342 | 346 | /*
|
@@ -5865,6 +5869,42 @@ needs_toast_table(Relation rel)
|
5865 | 5869 | return (tuple_length > TOAST_TUPLE_THRESHOLD);
|
5866 | 5870 | }
|
5867 | 5871 |
|
| 5872 | +/* |
| 5873 | + * Verify that a schema's tablespace still exists |
| 5874 | + * |
| 5875 | + * We need this because DROP TABLESPACE cannot check whether the target |
| 5876 | + * tablespace is the default tablespace for any schemas. (It could check |
| 5877 | + * in the current database, but that doesn't seem very helpful.) Subsequent |
| 5878 | + * attempts to create tables in that tablespace will fail. This code just |
| 5879 | + * exists to ensure that we give a helpful error message. |
| 5880 | + */ |
| 5881 | +static void |
| 5882 | +check_tablespace_exists(Oid tablespaceId, Oid namespaceId) |
| 5883 | +{ |
| 5884 | + Relation pg_tablespace; |
| 5885 | + ScanKeyData entry[1]; |
| 5886 | + HeapScanDesc scan; |
| 5887 | + HeapTuple tuple; |
| 5888 | + |
| 5889 | + /* There's no syscache for pg_tablespace, so must look the hard way */ |
| 5890 | + pg_tablespace = heap_openr(TableSpaceRelationName, AccessShareLock); |
| 5891 | + ScanKeyInit(&entry[0], |
| 5892 | + ObjectIdAttributeNumber, |
| 5893 | + BTEqualStrategyNumber, F_OIDEQ, |
| 5894 | + ObjectIdGetDatum(tablespaceId)); |
| 5895 | + scan = heap_beginscan(pg_tablespace, SnapshotNow, 1, entry); |
| 5896 | + tuple = heap_getnext(scan, ForwardScanDirection); |
| 5897 | + if (!HeapTupleIsValid(tuple)) |
| 5898 | + ereport(ERROR, |
| 5899 | + (errcode(ERRCODE_UNDEFINED_OBJECT), |
| 5900 | + errmsg("tablespace with OID %u does not exist", |
| 5901 | + tablespaceId), |
| 5902 | + errdetail("The default tablespace for schema \"%s\" has been dropped.", |
| 5903 | + get_namespace_name(namespaceId)))); |
| 5904 | + heap_endscan(scan); |
| 5905 | + heap_close(pg_tablespace, AccessShareLock); |
| 5906 | +} |
| 5907 | + |
5868 | 5908 |
|
5869 | 5909 | /*
|
5870 | 5910 | * This code supports
|
|
0 commit comments