HAWQ-322. Fixed DROP TABLESPACE doesnot check sub-object(database/relation) in some cases
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/ba500a5c Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/ba500a5c Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/ba500a5c Branch: refs/heads/master Commit: ba500a5c05a8518c3c5abc401583a90f8d28f0b7 Parents: 5d2f515 Author: Ming LI <[email protected]> Authored: Wed Jan 6 15:42:27 2016 +0800 Committer: Ming LI <[email protected]> Committed: Thu Jan 14 11:48:27 2016 +0800 ---------------------------------------------------------------------- src/backend/commands/tablespace.c | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/ba500a5c/src/backend/commands/tablespace.c ---------------------------------------------------------------------- diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 3b4c6f7..54a9f97 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -60,6 +60,7 @@ #include "catalog/indexing.h" #include "catalog/pg_filespace.h" #include "catalog/pg_tablespace.h" +#include "catalog/pg_database.h" #include "catalog/pg_type.h" #include "cdb/cdbmirroredflatfile.h" #include "commands/comment.h" @@ -275,7 +276,7 @@ void RemoveTableSpace(List *names, DropBehavior behavior, bool missing_ok) { char *tablespacename; - Relation rel; + Relation rel, rel1; HeapTuple tuple; cqContext cqc; cqContext *pcqCtx; @@ -361,9 +362,55 @@ RemoveTableSpace(List *names, DropBehavior behavior, bool missing_ok) * Check for any databases or relations defined in this tablespace, this * is logically the same as checkSharedDependencies, however we don't * actually track these in pg_shdepend, instead we lookup this information - * in the gp_persistent_database/relation_node tables. + * in the related catalog. The reason why we don't based on the persistent + * table (gp_persistent_database/relation_node) is: + * it will has concurrency problem because there is no 2-phrase-lock + * for persistent table. */ - /* ... */ + + /* + * Check for any databases defined in this tablespace + */ + rel1 = heap_open(DatabaseRelationId, AccessShareLock); + + pcqCtx = caql_addrel(cqclr(&cqc), rel1); + + tuple = caql_getfirst( + pcqCtx, + cql("SELECT * FROM pg_database " + " WHERE dat2tablespace = :1 ", + ObjectIdGetDatum(tablespaceoid))); + + if (HeapTupleIsValid(tuple)) + { + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("tablespace \"%s\" is not empty: existing database.", tablespacename))); + + } + heap_close(rel1, AccessShareLock); + + /* + * Check for any databases defined in this tablespace + */ + rel1 = heap_open(RelationRelationId, AccessShareLock); + + pcqCtx = caql_addrel(cqclr(&cqc), rel1); + + tuple = caql_getfirst( + pcqCtx, + cql("SELECT * FROM pg_class " + " WHERE reltablespace = :1 ", + ObjectIdGetDatum(tablespaceoid))); + + if (HeapTupleIsValid(tuple)) + { + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("tablespace \"%s\" is not empty: existing table.", tablespacename))); + + } + heap_close(rel1, AccessShareLock); /* * Remove the pg_tablespace tuple (this will roll back if we fail below)
