]> granicus.if.org Git - postgresql/commitdiff
Move TablespaceCreateDbspace() call into smgrcreate(), which is where it
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 11 Jul 2004 19:52:52 +0000 (19:52 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 11 Jul 2004 19:52:52 +0000 (19:52 +0000)
probably should have been to begin with; this is to cover cases like
needing to recreate the per-db directory during WAL replay.
Also, fix heap_create to force pg_class.reltablespace to be zero instead
of the database's default tablespace; this makes the world safe for
CREATE DATABASE to handle all tables in the default tablespace alike,
as per previous discussion.  And force pg_class.reltablespace to zero
when creating a relation without physical storage (eg, a view); this
avoids possibly having dangling references in this column after a
subsequent DROP TABLESPACE.

src/backend/catalog/heap.c
src/backend/commands/tablespace.c
src/backend/storage/smgr/smgr.c
src/include/catalog/heap.h
src/include/commands/tablespace.h

index 68ea6f45f69e295164d061c250edddcb8b77ecb2..1dbe77a8f53bc2fcabebab33ee7dc9b8dc6827ec 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.271 2004/06/18 06:13:19 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.272 2004/07/11 19:52:48 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -43,7 +43,6 @@
 #include "catalog/pg_statistic.h"
 #include "catalog/pg_type.h"
 #include "commands/tablecmds.h"
-#include "commands/tablespace.h"
 #include "commands/trigger.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
@@ -195,10 +194,6 @@ SystemAttributeByName(const char *attname, bool relhasoids)
  *             and is mostly zeroes at return.
  *
  *             Remove the system relation specific code to elsewhere eventually.
- *
- * If storage_create is TRUE then heap_storage_create is called here,
- * else caller must call heap_storage_create later (or not at all,
- * if the relation doesn't need physical storage).
  * ----------------------------------------------------------------
  */
 Relation
@@ -207,7 +202,7 @@ heap_create(const char *relname,
                        Oid reltablespace,
                        TupleDesc tupDesc,
                        bool shared_relation,
-                       bool storage_create,
+                       bool create_storage,
                        bool allow_system_table_mods)
 {
        Oid                     relid;
@@ -268,6 +263,25 @@ heap_create(const char *relname,
        else
                relid = newoid();
 
+       /*
+        * Never allow a pg_class entry to explicitly specify the database's
+        * default tablespace in reltablespace; force it to zero instead.
+        * This ensures that if the database is cloned with a different
+        * default tablespace, the pg_class entry will still match where
+        * CREATE DATABASE will put the physically copied relation.
+        *
+        * Yes, this is a bit of a hack.
+        */
+       if (reltablespace == MyDatabaseTableSpace)
+               reltablespace = InvalidOid;
+
+       /*
+        * Also, force reltablespace to zero if the relation has no physical
+        * storage.  This is mainly just for cleanliness' sake.
+        */
+       if (!create_storage)
+               reltablespace = InvalidOid;
+
        /*
         * build the relcache entry.
         */
@@ -280,33 +294,18 @@ heap_create(const char *relname,
                                                                         nailme);
 
        /*
-        * have the storage manager create the relation's disk file, if
-        * wanted.
+        * have the storage manager create the relation's disk file, if needed.
         */
-       if (storage_create)
-               heap_storage_create(rel);
+       if (create_storage)
+       {
+               Assert(rel->rd_smgr == NULL);
+               rel->rd_smgr = smgropen(rel->rd_node);
+               smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
+       }
 
        return rel;
 }
 
-void
-heap_storage_create(Relation rel)
-{
-       /*
-        * We may be using the target table space for the first time in this
-        * database, so create a per-database subdirectory if needed.
-        *
-        * XXX it might be better to do this right in smgrcreate...
-        */
-       TablespaceCreateDbspace(rel->rd_node.spcNode, rel->rd_node.dbNode);
-       /*
-        * Now we can make the file.
-        */
-       Assert(rel->rd_smgr == NULL);
-       rel->rd_smgr = smgropen(rel->rd_node);
-       smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
-}
-
 /* ----------------------------------------------------------------
  *             heap_create_with_catalog                - Create a cataloged relation
  *
index 875fb1cae8a8a57dc0fcad827cc9f187b9c5ba52..a08c12305a76f5afb692e49af1c1e598e35c06e2 100644 (file)
@@ -45,7 +45,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.5 2004/07/02 18:59:22 joe Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.6 2004/07/11 19:52:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -85,9 +85,13 @@ static bool directory_is_empty(const char *path);
  *
  * If tablespaces are not supported, this is just a no-op; CREATE DATABASE
  * is expected to create the default subdirectory for the database.
+ *
+ * isRedo indicates that we are creating an object during WAL replay;
+ * we can skip doing locking in that case (and should do so to avoid
+ * any possible problems with pg_tablespace not being valid).
  */
 void
-TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
+TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo)
 {
 #ifdef HAVE_SYMLINK
        struct stat st;
@@ -116,7 +120,10 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
                         */
                        Relation rel;
 
-                       rel = heap_openr(TableSpaceRelationName, ExclusiveLock);
+                       if (!isRedo)
+                               rel = heap_openr(TableSpaceRelationName, ExclusiveLock);
+                       else
+                               rel = NULL;
 
                        /*
                         * Recheck to see if someone created the directory while
@@ -137,7 +144,8 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
                        }
 
                        /* OK to drop the exclusive lock */
-                       heap_close(rel, ExclusiveLock);
+                       if (!isRedo)
+                               heap_close(rel, ExclusiveLock);
                }
                else
                {
index 5c53d48f83831057d0d08b07137366438065aa7f..5ad43955e46e4cfd66b3f08bbe9da7f3979e01db 100644 (file)
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.75 2004/07/01 00:51:07 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.76 2004/07/11 19:52:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
+#include "commands/tablespace.h"
 #include "storage/bufmgr.h"
 #include "storage/freespace.h"
 #include "storage/ipc.h"
@@ -309,6 +310,19 @@ smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo)
        PendingRelDelete *pending;
        MemoryContext   old_cxt;
 
+       /*
+        * We may be using the target table space for the first time in this
+        * database, so create a per-database subdirectory if needed.
+        *
+        * XXX this is a fairly ugly violation of module layering, but this seems
+        * to be the best place to put the check.  Maybe TablespaceCreateDbspace
+        * should be here and not in commands/tablespace.c?  But that would imply
+        * importing a lot of stuff that smgr.c oughtn't know, either.
+        */
+       TablespaceCreateDbspace(reln->smgr_rnode.spcNode,
+                                                       reln->smgr_rnode.dbNode,
+                                                       isRedo);
+
        if (! (*(smgrsw[reln->smgr_which].smgr_create)) (reln, isRedo))
                ereport(ERROR,
                                (errcode_for_file_access(),
index 4ead9728df0464b6eab4e0060b9bdd51922b974e..06f0f4da3a4a2ab012bcecc8f61e99163b398df8 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.67 2004/06/18 06:14:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.68 2004/07/11 19:52:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,11 +40,9 @@ extern Relation heap_create(const char *relname,
                        Oid reltablespace,
                        TupleDesc tupDesc,
                        bool shared_relation,
-                       bool storage_create,
+                       bool create_storage,
                        bool allow_system_table_mods);
 
-extern void heap_storage_create(Relation rel);
-
 extern Oid heap_create_with_catalog(const char *relname,
                                                 Oid relnamespace,
                                                 Oid reltablespace,
index 17821493f45994e98a0cd6fa417833de02077b6a..42093c515054e5a6bc79c09b6aff088db13f42c8 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.2 2004/06/25 21:55:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.3 2004/07/11 19:52:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,7 +20,7 @@ extern void CreateTableSpace(CreateTableSpaceStmt *stmt);
 
 extern void DropTableSpace(DropTableSpaceStmt *stmt);
 
-extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode);
+extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
 
 extern Oid     get_tablespace_oid(const char *tablespacename);