summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael P2011-02-21 04:29:22 +0000
committerPavan Deolasee2011-05-19 17:49:37 +0000
commitc379c0e422bc20f720565a22205700c5380099cd (patch)
tree6a54c9fa2d474cc9061e6573abc43b4703538385
parentc3f696597fba503f3f9ea18f0881603b82df62c4 (diff)
Fix for bug 3170713: DROP DATABASE wihout cleaning connections
This adds a call to clean pooler connections for the given database before dropping the given DB on each backend. I added also an owner check to avoid a user to clean connections if he has no rights on the given db.
-rw-r--r--src/backend/pgxc/pool/poolutils.c27
-rw-r--r--src/backend/tcop/utility.c6
-rw-r--r--src/include/pgxc/poolutils.h1
3 files changed, 34 insertions, 0 deletions
diff --git a/src/backend/pgxc/pool/poolutils.c b/src/backend/pgxc/pool/poolutils.c
index cccc9de7cb..eeeba8aa23 100644
--- a/src/backend/pgxc/pool/poolutils.c
+++ b/src/backend/pgxc/pool/poolutils.c
@@ -23,6 +23,7 @@
#include "pgxc/poolutils.h"
#include "access/gtm.h"
#include "commands/dbcommands.h"
+#include "utils/acl.h"
#include "nodes/parsenodes.h"
@@ -185,3 +186,29 @@ CleanConnection(CleanConnStmt *stmt)
if (dn_list)
list_free(dn_list);
}
+
+/*
+ * DropDBCleanConnection
+ *
+ * Clean Connection for given database before dropping it
+ * FORCE is not used here
+ */
+void
+DropDBCleanConnection(char *dbname)
+{
+ List *co_list = GetAllCoordNodes();
+ List *dn_list = GetAllDataNodes();
+
+ /* Check permissions for this database */
+ if (!pg_database_ownercheck(get_database_oid(dbname), GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
+ dbname);
+
+ PoolManagerCleanConnection(dn_list, co_list, dbname);
+
+ /* Clean up memory */
+ if (co_list)
+ list_free(co_list);
+ if (dn_list)
+ list_free(dn_list);
+}
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 35bc6ca3cb..c2f45d4665 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1044,6 +1044,12 @@ ProcessUtility(Node *parsetree,
{
DropdbStmt *stmt = (DropdbStmt *) parsetree;
+#ifdef PGXC
+ /* Clean connections before dropping a database */
+ if (IS_PGXC_COORDINATOR && !IsConnFromCoord())
+ DropDBCleanConnection(stmt->dbname);
+#endif
+
PreventTransactionChain(isTopLevel, "DROP DATABASE");
dropdb(stmt->dbname, stmt->missing_ok);
}
diff --git a/src/include/pgxc/poolutils.h b/src/include/pgxc/poolutils.h
index 5b8749451b..fff8b9ed1f 100644
--- a/src/include/pgxc/poolutils.h
+++ b/src/include/pgxc/poolutils.h
@@ -27,4 +27,5 @@
#define CLEAN_CONNECTION_EOF -1
void CleanConnection(CleanConnStmt *stmt);
+void DropDBCleanConnection(char *dbname);
#endif