From 5fa3418304b06967fa54052b183bf96e1193d85e Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 23 Sep 2002 20:43:41 +0000
Subject: [PATCH] Disallow VACUUM, ANALYZE, TRUNCATE on temp tables belonging
 to other backends.  Given that temp tables now store data locally in the
 local buffer manager, these things are not going to work safely.

---
 src/backend/catalog/namespace.c  | 24 +++++++++++++++++++++++-
 src/backend/commands/analyze.c   | 16 +++++++++++++++-
 src/backend/commands/tablecmds.c | 10 +++++++++-
 src/backend/commands/vacuum.c    | 16 +++++++++++++++-
 src/include/catalog/namespace.h  |  3 ++-
 5 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 182d9016e97..c5a5c70ebc7 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.35 2002/09/04 20:31:14 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.36 2002/09/23 20:43:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1217,6 +1217,28 @@ isTempNamespace(Oid namespaceId)
 	return false;
 }
 
+/*
+ * isOtherTempNamespace - is the given namespace some other backend's
+ * temporary-table namespace?
+ */
+bool
+isOtherTempNamespace(Oid namespaceId)
+{
+	bool		result;
+	char	   *nspname;
+
+	/* If it's my own temp namespace, say "false" */
+	if (isTempNamespace(namespaceId))
+		return false;
+	/* Else, if the namespace name starts with "pg_temp_", say "true" */
+	nspname = get_namespace_name(namespaceId);
+	if (!nspname)
+		return false;			/* no such namespace? */
+	result = (strncmp(nspname, "pg_temp_", 8) == 0);
+	pfree(nspname);
+	return result;
+}
+
 /*
  * PushSpecialNamespace - push a "special" namespace onto the front of the
  * search path.
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 5c20b05447e..4c06a28621a 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.46 2002/09/04 20:31:14 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.47 2002/09/23 20:43:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,6 +21,7 @@
 #include "catalog/catalog.h"
 #include "catalog/catname.h"
 #include "catalog/indexing.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_statistic.h"
 #include "catalog/pg_type.h"
@@ -215,6 +216,19 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
 		return;
 	}
 
+	/*
+	 * Silently ignore tables that are temp tables of other backends ---
+	 * trying to analyze these is rather pointless, since their
+	 * contents are probably not up-to-date on disk.  (We don't throw a
+	 * warning here; it would just lead to chatter during a database-wide
+	 * ANALYZE.)
+	 */
+	if (isOtherTempNamespace(RelationGetNamespace(onerel)))
+	{
+		relation_close(onerel, AccessShareLock);
+		return;
+	}
+
 	/*
 	 * We can ANALYZE any table except pg_statistic. See update_attstats
 	 */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 7b2bab71c34..0934a274c7a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.43 2002/09/22 19:42:50 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.44 2002/09/23 20:43:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -367,6 +367,7 @@ TruncateRelation(const RangeVar *relation)
 			 RelationGetRelationName(rel));
 	}
 
+	/* Permissions checks */
 	if (!allowSystemTableMods && IsSystemRelation(rel))
 		elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
 			 RelationGetRelationName(rel));
@@ -374,6 +375,13 @@ TruncateRelation(const RangeVar *relation)
 	if (!pg_class_ownercheck(relid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
 
+	/*
+	 * Don't allow truncate on temp tables of other backends ... their
+	 * local buffer manager is not going to cope.
+	 */
+	if (isOtherTempNamespace(RelationGetNamespace(rel)))
+		elog(ERROR, "TRUNCATE cannot be used on temp tables of other processes");
+
 	/*
 	 * Don't allow truncate on tables which are referenced by foreign keys
 	 */
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 42172ac07b4..04c13be4e07 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.239 2002/09/23 00:42:48 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.240 2002/09/23 20:43:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -775,6 +775,20 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
 		return;
 	}
 
+	/*
+	 * Silently ignore tables that are temp tables of other backends ---
+	 * trying to vacuum these will lead to great unhappiness, since their
+	 * contents are probably not up-to-date on disk.  (We don't throw a
+	 * warning here; it would just lead to chatter during a database-wide
+	 * VACUUM.)
+	 */
+	if (isOtherTempNamespace(RelationGetNamespace(onerel)))
+	{
+		relation_close(onerel, lmode);
+		CommitTransactionCommand(true);
+		return;
+	}
+
 	/*
 	 * Get a session-level lock too. This will protect our access to the
 	 * relation across multiple transactions, so that we can vacuum the
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 3369f678095..531afac1453 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: namespace.h,v 1.20 2002/09/04 20:31:37 momjian Exp $
+ * $Id: namespace.h,v 1.21 2002/09/23 20:43:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -76,6 +76,7 @@ extern RangeVar *makeRangeVarFromNameList(List *names);
 extern char *NameListToString(List *names);
 
 extern bool isTempNamespace(Oid namespaceId);
+extern bool isOtherTempNamespace(Oid namespaceId);
 
 extern void PushSpecialNamespace(Oid namespaceId);
 extern void PopSpecialNamespace(Oid namespaceId);
-- 
GitLab