OSDN Git Service

Disallow VACUUM, ANALYZE, TRUNCATE on temp tables belonging to other
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 23 Sep 2002 20:43:41 +0000 (20:43 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 23 Sep 2002 20:43:41 +0000 (20:43 +0000)
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
src/backend/commands/analyze.c
src/backend/commands/tablecmds.c
src/backend/commands/vacuum.c
src/include/catalog/namespace.h

index 182d901..c5a5c70 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -1218,6 +1218,28 @@ isTempNamespace(Oid namespaceId)
 }
 
 /*
+ * 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.
  *
index 5c20b05..4c06a28 100644 (file)
@@ -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"
@@ -216,6 +217,19 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
        }
 
        /*
+        * 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
         */
        if (IsSystemNamespace(RelationGetNamespace(onerel)) &&
index 7b2bab7..0934a27 100644 (file)
@@ -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));
@@ -375,6 +376,13 @@ TruncateRelation(const RangeVar *relation)
                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
         */
        fkeyRel = heap_openr(ConstraintRelationName, AccessShareLock);
index 42172ac..04c13be 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -776,6 +776,20 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
        }
 
        /*
+        * 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
         * relation's TOAST table (if any) secure in the knowledge that no one
index 3369f67..531afac 100644 (file)
@@ -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);