diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 9e7f1c812e..c69bf29d83 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.134 2004/10/12 21:54:36 petere Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.135 2004/10/16 21:16:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -168,6 +168,7 @@ static void StoreCatalogInheritance(Oid relationId, List *supers); static int findAttrByName(const char *attributeName, List *schema); static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass); static bool needs_toast_table(Relation rel); +static void check_tablespace_exists(Oid tablespaceId, Oid namespaceId); static int transformColumnNameList(Oid relId, List *colList, int16 *attnums, Oid *atttypids); static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, @@ -337,6 +338,9 @@ DefineRelation(CreateStmt *stmt, char relkind) { tablespaceId = get_namespace_tablespace(namespaceId); /* note no permission check on tablespace in this case */ + /* check to see that schema's tablespace still exists */ + if (OidIsValid(tablespaceId)) + check_tablespace_exists(tablespaceId, namespaceId); } /* @@ -5865,6 +5869,42 @@ needs_toast_table(Relation rel) return (tuple_length > TOAST_TUPLE_THRESHOLD); } +/* + * Verify that a schema's tablespace still exists + * + * We need this because DROP TABLESPACE cannot check whether the target + * tablespace is the default tablespace for any schemas. (It could check + * in the current database, but that doesn't seem very helpful.) Subsequent + * attempts to create tables in that tablespace will fail. This code just + * exists to ensure that we give a helpful error message. + */ +static void +check_tablespace_exists(Oid tablespaceId, Oid namespaceId) +{ + Relation pg_tablespace; + ScanKeyData entry[1]; + HeapScanDesc scan; + HeapTuple tuple; + + /* There's no syscache for pg_tablespace, so must look the hard way */ + pg_tablespace = heap_openr(TableSpaceRelationName, AccessShareLock); + ScanKeyInit(&entry[0], + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(tablespaceId)); + scan = heap_beginscan(pg_tablespace, SnapshotNow, 1, entry); + tuple = heap_getnext(scan, ForwardScanDirection); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("tablespace with OID %u does not exist", + tablespaceId), + errdetail("The default tablespace for schema \"%s\" has been dropped.", + get_namespace_name(namespaceId)))); + heap_endscan(scan); + heap_close(pg_tablespace, AccessShareLock); +} + /* * This code supports