On 5/3/07, Bruce Momjian <[EMAIL PROTECTED]> wrote:

Your patch has been added to the PostgreSQL unapplied patches list at:


This is an updated version of the patch.

Tom objections:
- fd.c is too low level for calling code from commands/tablespace.c.
 This was fixed adding a second parameter to BufFileCreateTemp() to send
 the tblspcOid (this function is called from executor/nodeHashJoin.c,
 utils/sort/logtape.c and utils/sort/tuplestore.c). Are these places ok?

- RemovePgTempFilesInDir() has no support for removing temp files from
 strange locations.
 Per Tom suggestion temp files are now created in: base/pgsql_tmp and
 pg_tblspc/$oid_tblspc/pgsql_tmp. So i just refactor RemovePgTempFiles()
 to call RemovePgTempFilesInDir() with base and pg_tblspc/$oid_tblspc's
 pgsql_tmp

Other changes in code:
fd.c:
functions make_database_relative() and FileNameOpenFile() were marked
as NOT_USED. objections to simply delete them?
also added OpenTempFileInTblspc() to create the tempfilepath and call
to PathNameOpenFile()
buffile.c:
also added a new tblspcOid field to BufFile struct to use it in extendBufFile()


Problems:
While the patch passes all the regression tests i still have a problem
when doin this:

sgerp=# set temp_tablespaces = '';
ERROR:  tablespace "" does not exist

note that setting temp_tablespaces = '' from postgresql.conf works well.

maybe this is silly but it's too late for me... i will keep trying
tomorrow unless someone else has fixed it.

comments?

--
regards,
Jaime Casanova

"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs and the universe trying
to produce bigger and better idiots.
So far, the universe is winning."
                                      Richard Cook
? postgresql-8.3devel
Index: doc/src/sgml/config.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/config.sgml,v
retrieving revision 1.122
diff -c -r1.122 config.sgml
*** doc/src/sgml/config.sgml    20 Apr 2007 02:37:37 -0000      1.122
--- doc/src/sgml/config.sgml    5 May 2007 05:27:03 -0000
***************
*** 3479,3484 ****
--- 3479,3513 ----
        </listitem>
       </varlistentry>
  
+      <varlistentry id="guc-temp-tablespaces" xreflabel="temp_tablespaces">
+       <term><varname>temp_tablespaces</varname> (<type>string</type>)</term>
+       <indexterm>
+        <primary><varname>temp_tablespaces</> configuration parameter</primary>
+       </indexterm>
+       <indexterm><primary>tablespace</><secondary>temp</></>
+       <listitem>
+        <para>
+         This variable specifies tablespaces in which to create temp
+         objects (temp tables and indexes on temp tables) when a 
+               <command>CREATE</> command does not explicitly specify a 
tablespace 
+               and temp files when necessary (eg. for sorting operations).
+        </para>
+ 
+        <para>
+         The value is either a list of names of tablespaces, or an empty 
+               string to specify using the default tablespace of the current 
database.
+         If the value does not match the name of any existing tablespace,
+         <productname>PostgreSQL</> will automatically use the default
+         tablespace of the current database.
+        </para>
+ 
+        <para>
+         For more information on tablespaces,
+         see <xref linkend="manage-ag-tablespaces">.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
       <varlistentry id="guc-check-function-bodies" 
xreflabel="check_function_bodies">
        <term><varname>check_function_bodies</varname> 
(<type>boolean</type>)</term>
        <indexterm>
Index: src/backend/commands/indexcmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/indexcmds.c,v
retrieving revision 1.158
diff -c -r1.158 indexcmds.c
*** src/backend/commands/indexcmds.c    2 May 2007 21:08:45 -0000       1.158
--- src/backend/commands/indexcmds.c    5 May 2007 05:27:06 -0000
***************
*** 208,214 ****
        }
        else
        {
!               tablespaceId = GetDefaultTablespace();
                /* note InvalidOid is OK in this case */
        }
  
--- 208,220 ----
        }
        else
        {
!               /*
!                * if the target table is temporary then use a temp_tablespace
!                */
!               if (!rel->rd_istemp)
!                       tablespaceId = GetDefaultTablespace();
!               else
!                       tablespaceId = GetTempTablespace();
                /* note InvalidOid is OK in this case */
        }
  
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.219
diff -c -r1.219 tablecmds.c
*** src/backend/commands/tablecmds.c    8 Apr 2007 01:26:32 -0000       1.219
--- src/backend/commands/tablecmds.c    5 May 2007 05:27:17 -0000
***************
*** 333,338 ****
--- 333,342 ----
                                         errmsg("tablespace \"%s\" does not 
exist",
                                                        stmt->tablespacename)));
        }
+       else if (stmt->relation->istemp)
+       {
+               tablespaceId = GetTempTablespace();
+       }
        else
        {
                tablespaceId = GetDefaultTablespace();
Index: src/backend/commands/tablespace.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablespace.c,v
retrieving revision 1.45
diff -c -r1.45 tablespace.c
*** src/backend/commands/tablespace.c   22 Mar 2007 19:51:44 -0000      1.45
--- src/backend/commands/tablespace.c   5 May 2007 05:27:19 -0000
***************
*** 65,73 ****
  #include "utils/lsyscache.h"
  
  
! /* GUC variable */
  char     *default_tablespace = NULL;
  
  
  static bool remove_tablespace_directories(Oid tablespaceoid, bool redo);
  static void set_short_version(const char *path);
--- 65,76 ----
  #include "utils/lsyscache.h"
  
  
! /* GUC variables */
  char     *default_tablespace = NULL;
+ char       *temp_tablespaces = NULL;
  
+ int      next_temp_tablespace;
+ int      num_temp_tablespaces;
  
  static bool remove_tablespace_directories(Oid tablespaceoid, bool redo);
  static void set_short_version(const char *path);
***************
*** 935,940 ****
--- 938,1083 ----
        return result;
  }
  
+ /*
+  * Routines for handling the GUC variable 'temp_tablespaces'.
+  */
+ 
+ /* assign_hook: validate new temp_tablespaces, do extra actions as needed */
+ const char *
+ assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
+ {
+       char       *rawname;
+       List       *namelist;
+       ListCell   *l;
+ 
+       /* Need a modifiable copy of string */
+       rawname = pstrdup(newval);
+ 
+       /* Parse string into list of identifiers */
+       if (!SplitIdentifierString(rawname, ',', &namelist))
+       {
+               /* syntax error in name list */
+               pfree(rawname);
+               list_free(namelist);
+               return NULL;
+       }
+ 
+       num_temp_tablespaces = 0;
+       foreach(l, namelist)
+       {
+               char       *curname = (char *) lfirst(l);
+ 
+               /*
+                * If we aren't inside a transaction, we cannot do database 
access so
+                * cannot verify the individual names.  Must accept the list on 
faith.
+                */
+               if (source >= PGC_S_INTERACTIVE && IsTransactionState())
+               {
+                       /*
+                        * Verify that all the names are valid tablspace names 
+                        * We do not check for USAGE rights should we?
+                        */
+                       if (get_tablespace_oid(curname) == InvalidOid)
+                               ereport((source == PGC_S_TEST) ? NOTICE : ERROR,
+                                               
(errcode(ERRCODE_UNDEFINED_OBJECT),
+                                               errmsg("tablespace \"%s\" does 
not exist", curname)));
+               }
+               num_temp_tablespaces++;
+       }
+ 
+       /*
+        * Select the first tablespace to use
+        */
+       Assert(num_temp_tablespaces >= 0);
+       if (num_temp_tablespaces != 0)
+               next_temp_tablespace = MyProcPid % num_temp_tablespaces;
+ 
+       pfree(rawname);
+       list_free(namelist);
+       return newval;
+ }
+ 
+ /*
+  * GetTempTablespace -- get the OID of the tablespace for temporary objects
+  *
+  * May return InvalidOid to indicate "use the database's default tablespace"
+  *
+  * This exists to hide the temp_tablespace GUC variable.
+  */
+ Oid
+ GetTempTablespace(void)
+ {
+       Oid                     result;
+       char *curname = NULL;
+       char *rawname;
+       List *namelist;
+       ListCell *l;
+       int i = 0;
+       
+       if ( temp_tablespaces == NULL )
+               return InvalidOid;
+       
+       elog(NOTICE, "prueba");
+ 
+       /* Need a modifiable version of temp_tablespaces */
+       rawname = pstrdup(temp_tablespaces);
+ 
+       /* Parse string into list of identifiers */
+       if (!SplitIdentifierString(rawname, ',', &namelist))
+       {
+               /* syntax error in name list */
+               pfree(rawname);
+               list_free(namelist);
+               return InvalidOid;
+       }
+ 
+       /* 
+        * Iterate through the list of namespaces until the one we need 
+        * (next_temp_tablespace) 
+        */
+       foreach(l, namelist)
+       {
+               curname = (char *) lfirst(l);
+               if ( i == next_temp_tablespace )
+                       break;
+               i++;
+       }
+ 
+ 
+       /* Prepare for the next time the function is called */
+       next_temp_tablespace++;
+       if (next_temp_tablespace == num_temp_tablespaces)
+               next_temp_tablespace = 0;
+ 
+       /* Fast path for temp_tablespaces == "" */
+       if ( curname == NULL || curname[0] == '\0') {
+               list_free(namelist);
+               pfree(rawname);
+               return InvalidOid;
+       }
+ 
+       /*
+        * It is tempting to cache this lookup for more speed, but then we would
+        * fail to detect the case where the tablespace was dropped since the 
GUC
+        * variable was set.  Note also that we don't complain if the value 
fails
+        * to refer to an existing tablespace; we just silently return 
InvalidOid,
+        * causing the new object to be created in the database's tablespace.
+        */
+       result = get_tablespace_oid(curname);
+ 
+       /* We don't free rawname before because curname points to a part of it 
*/
+       pfree(rawname);
+ 
+       /*
+        * Allow explicit specification of database's default tablespace in
+        * default_tablespace without triggering permissions checks.
+        */
+       if (result == MyDatabaseTableSpace)
+               result = InvalidOid;
+       
+       list_free(namelist);
+       return result;
+ }
  
  /*
   * get_tablespace_oid - given a tablespace name, look up the OID
Index: src/backend/executor/execMain.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/execMain.c,v
retrieving revision 1.293
diff -c -r1.293 execMain.c
*** src/backend/executor/execMain.c     27 Apr 2007 22:05:47 -0000      1.293
--- src/backend/executor/execMain.c     5 May 2007 05:27:23 -0000
***************
*** 2442,2447 ****
--- 2442,2451 ----
                                         errmsg("tablespace \"%s\" does not 
exist",
                                                        into->tableSpaceName)));
        }
+       else if (into->rel->istemp)
+       {
+               tablespaceId = GetTempTablespace();
+       }
        else
        {
                tablespaceId = GetDefaultTablespace();
Index: src/backend/executor/nodeHashjoin.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v
retrieving revision 1.89
diff -c -r1.89 nodeHashjoin.c
*** src/backend/executor/nodeHashjoin.c 2 Feb 2007 00:07:03 -0000       1.89
--- src/backend/executor/nodeHashjoin.c 5 May 2007 05:27:25 -0000
***************
*** 15,27 ****
  
  #include "postgres.h"
  
  #include "executor/executor.h"
  #include "executor/hashjoin.h"
  #include "executor/nodeHash.h"
  #include "executor/nodeHashjoin.h"
  #include "utils/memutils.h"
  
- 
  static TupleTableSlot *ExecHashJoinOuterGetTuple(PlanState *outerNode,
                                                  HashJoinState *hjstate,
                                                  uint32 *hashvalue);
--- 15,27 ----
  
  #include "postgres.h"
  
+ #include "commands/tablespace.h"
  #include "executor/executor.h"
  #include "executor/hashjoin.h"
  #include "executor/nodeHash.h"
  #include "executor/nodeHashjoin.h"
  #include "utils/memutils.h"
  
  static TupleTableSlot *ExecHashJoinOuterGetTuple(PlanState *outerNode,
                                                  HashJoinState *hjstate,
                                                  uint32 *hashvalue);
***************
*** 763,769 ****
        if (file == NULL)
        {
                /* First write to this batch file, so open it. */
!               file = BufFileCreateTemp(false);
                *fileptr = file;
        }
  
--- 763,769 ----
        if (file == NULL)
        {
                /* First write to this batch file, so open it. */
!               file = BufFileCreateTemp(false, GetTempTablespace());
                *fileptr = file;
        }
  
Index: src/backend/storage/file/buffile.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/file/buffile.c,v
retrieving revision 1.25
diff -c -r1.25 buffile.c
*** src/backend/storage/file/buffile.c  5 Jan 2007 22:19:37 -0000       1.25
--- src/backend/storage/file/buffile.c  5 May 2007 05:27:26 -0000
***************
*** 63,68 ****
--- 63,69 ----
  
        bool            isTemp;                 /* can only add files if this 
is TRUE */
        bool            isInterXact;    /* keep open over transactions? */
+       Oid                     tblspcOid;              /* Tablespace Oid or 
InvalidOid */
        bool            dirty;                  /* does buffer need to be 
written? */
  
        /*
***************
*** 98,103 ****
--- 99,105 ----
        file->offsets = (long *) palloc(sizeof(long));
        file->offsets[0] = 0L;
        file->isTemp = false;
+       file->tblspcOid = InvalidOid;
        file->dirty = false;
        file->curFile = 0;
        file->curOffset = 0L;
***************
*** 116,122 ****
        File            pfile;
  
        Assert(file->isTemp);
!       pfile = OpenTemporaryFile(file->isInterXact);
        Assert(pfile >= 0);
  
        file->files = (File *) repalloc(file->files,
--- 118,124 ----
        File            pfile;
  
        Assert(file->isTemp);
!       pfile = OpenTemporaryFile(file->isInterXact, file->tblspcOid);
        Assert(pfile >= 0);
  
        file->files = (File *) repalloc(file->files,
***************
*** 137,153 ****
   * memory context that will survive across transaction boundaries.
   */
  BufFile *
! BufFileCreateTemp(bool interXact)
  {
        BufFile    *file;
        File            pfile;
  
!       pfile = OpenTemporaryFile(interXact);
        Assert(pfile >= 0);
  
        file = makeBufFile(pfile);
        file->isTemp = true;
        file->isInterXact = interXact;
  
        return file;
  }
--- 139,156 ----
   * memory context that will survive across transaction boundaries.
   */
  BufFile *
! BufFileCreateTemp(bool interXact, Oid tblspcOid)
  {
        BufFile    *file;
        File            pfile;
  
!       pfile = OpenTemporaryFile(interXact, tblspcOid);
        Assert(pfile >= 0);
  
        file = makeBufFile(pfile);
        file->isTemp = true;
        file->isInterXact = interXact;
+       file->tblspcOid = tblspcOid;
  
        return file;
  }
Index: src/backend/storage/file/fd.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/file/fd.c,v
retrieving revision 1.137
diff -c -r1.137 fd.c
*** src/backend/storage/file/fd.c       6 Mar 2007 02:06:14 -0000       1.137
--- src/backend/storage/file/fd.c       5 May 2007 05:27:29 -0000
***************
*** 76,81 ****
--- 76,82 ----
   */
  #define FD_MINFREE                            10
  
+ #define OIDCHARS        10                      /* max chars printed by %u */
  
  /*
   * A number of platforms allow individual processes to open many more files
***************
*** 225,231 ****
--- 226,234 ----
  static void FreeVfd(File file);
  
  static int    FileAccess(File file);
+ #ifdef NOT_USED
  static char *make_database_relative(const char *filename);
+ #endif
  static void AtProcExit_Files(int code, Datum arg);
  static void CleanupTempFiles(bool isProcExit);
  static void RemovePgTempFilesInDir(const char *tmpdirname);
***************
*** 721,726 ****
--- 724,730 ----
        VfdCache[0].nextFree = file;
  }
  
+ #ifdef NOT_USED
  /*
   * make_database_relative()
   *            Prepend DatabasePath to the given file name.
***************
*** 737,742 ****
--- 741,747 ----
        sprintf(buf, "%s/%s", DatabasePath, filename);
        return buf;
  }
+ #endif
  
  /* returns 0 on success, -1 on re-open failure (with errno set) */
  static int
***************
*** 844,849 ****
--- 849,855 ----
        return file;
  }
  
+ #ifdef NOT_USED
  /*
   * open a file in the database directory ($PGDATA/base/DIROID/)
   *
***************
*** 861,938 ****
        pfree(fname);
        return fd;
  }
  
  /*
   * Open a temporary file that will disappear when we close it.
   *
-  * This routine takes care of generating an appropriate tempfile name.
-  * There's no need to pass in fileFlags or fileMode either, since only
-  * one setting makes any sense for a temp file.
-  *
   * interXact: if true, don't close the file at end-of-transaction. In
   * most cases, you don't want temporary files to outlive the transaction
   * that created them, so this should be false -- but if you need
   * "somewhat" temporary storage, this might be useful. In either case,
   * the file is removed when the File is explicitly closed.
   */
  File
! OpenTemporaryFile(bool interXact)
  {
-       char            tempfilepath[MAXPGPATH];
        File            file;
  
        /*
         * Generate a tempfile name that should be unique within the current
         * database instance.
         */
        snprintf(tempfilepath, sizeof(tempfilepath),
!                        "%s/%s%d.%ld", PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX,
                         MyProcPid, tempFileCounter++);
  
        /*
!        * Open the file.  Note: we don't use O_EXCL, in case there is an 
orphaned
!        * temp file that can be reused.
         */
-       file = FileNameOpenFile(tempfilepath,
-                                                       O_RDWR | O_CREAT | 
O_TRUNC | PG_BINARY,
-                                                       0600);
        if (file <= 0)
        {
!               char       *dirpath;
  
                /*
!                * We might need to create the pg_tempfiles subdirectory, if no 
one
!                * has yet done so.
!                *
!                * Don't check for error from mkdir; it could fail if someone 
else
!                * just did the same thing.  If it doesn't work then we'll bomb 
out on
!                * the second create attempt, instead.
                 */
!               dirpath = make_database_relative(PG_TEMP_FILES_DIR);
!               mkdir(dirpath, S_IRWXU);
!               pfree(dirpath);
! 
!               file = FileNameOpenFile(tempfilepath,
!                                                               O_RDWR | 
O_CREAT | O_TRUNC | PG_BINARY,
!                                                               0600);
!               if (file <= 0)
                        elog(ERROR, "could not create temporary file \"%s\": 
%m",
                                 tempfilepath);
        }
! 
!       /* Mark it for deletion at close */
!       VfdCache[file].fdstate |= FD_TEMPORARY;
! 
!       /* Mark it for deletion at EOXact */
!       if (!interXact)
!       {
!               VfdCache[file].fdstate |= FD_XACT_TEMPORARY;
!               VfdCache[file].create_subid = GetCurrentSubTransactionId();
!       }
  
        return file;
  }
  
  /*
   * close a file when done with it
   */
--- 867,996 ----
        pfree(fname);
        return fd;
  }
+ #endif
  
  /*
   * Open a temporary file that will disappear when we close it.
   *
   * interXact: if true, don't close the file at end-of-transaction. In
   * most cases, you don't want temporary files to outlive the transaction
   * that created them, so this should be false -- but if you need
   * "somewhat" temporary storage, this might be useful. In either case,
   * the file is removed when the File is explicitly closed.
+  *
+  * tblspcOid: the oid of the tablespace where the temp file will be created.
+  * if InvalidOid we fall into $PGDATA/base
   */
  File
! OpenTemporaryFile(bool interXact, Oid tblspcOid)
  {
        File            file;
  
+       if (tblspcOid != InvalidOid)
+       {
+               /*
+                * As we got a valid tablespace, try to create the
+                * file there
+                */
+               file = OpenTempFileInTblspc(tblspcOid);
+       }
+ 
+       /*
+        * Create a normal temporary file if no tablespace was passed or
+        * couldn't create the file in the tablespace "tblspcOid"
+        */
+       if (tblspcOid == InvalidOid || file <= 0) 
+       {
+               file = OpenTempFileInTblspc(InvalidOid);
+       }
+ 
+       /* Mark it for deletion at close */
+       VfdCache[file].fdstate |= FD_TEMPORARY;
+ 
+       /* Mark it for deletion at EOXact */
+       if (!interXact)
+       {
+               VfdCache[file].fdstate |= FD_XACT_TEMPORARY;
+               VfdCache[file].create_subid = GetCurrentSubTransactionId();
+       }
+ 
+       return file;
+ }
+ 
+ 
+ /*
+  * Actually call PathNameOpenFile() to create the file.
+  *  
+  * This routine takes care of generating an appropriate tempfile name.
+  * There's no need to pass in fileFlags or fileMode either, since only
+  * one setting makes any sense for a temp file.
+  *
+  * tblspcOid: the oid of the tabespace where the file will be created or 
+  * InvalidOid if $PGDATA/base should be used.
+  */
+ File
+ OpenTempFileInTblspc(Oid tblspcOid)
+ {             
+       char    tempfilepath[MAXPGPATH];
+       int             pathlen;
+       File    file;
+       char    *path;
+ 
+       pathlen = 20 + OIDCHARS + 1;
+       path = (char *) palloc(pathlen);
+ 
+       if (tblspcOid == InvalidOid)
+               snprintf(path, pathlen, "base/%s", PG_TEMP_FILES_DIR);
+       else
+               snprintf(path, pathlen, "pg_tblspc/%u/%s", tblspcOid, 
+                                                               
PG_TEMP_FILES_DIR);
        /*
         * Generate a tempfile name that should be unique within the current
         * database instance.
         */
        snprintf(tempfilepath, sizeof(tempfilepath),
!                        "%s/%s%d.%ld", path, PG_TEMP_FILE_PREFIX,
                         MyProcPid, tempFileCounter++);
  
        /*
!        * Open the file.  Note: we don't use O_EXCL, in case there is an 
!        * orphaned temp file that can be reused.
!        */
!       file = PathNameOpenFile(tempfilepath,
!                                               O_RDWR | O_CREAT | O_TRUNC | 
PG_BINARY,
!                                               0600);
!       /*
!        * We might need to create the pg_tempfiles subdirectory, if no one
!        * has yet done so.
!        *
!        * Don't check for error from mkdir; it could fail if someone else
!        * just did the same thing.  If it doesn't work then we'll bomb 
!        * out on the second create attempt, instead.
         */
        if (file <= 0)
        {
!               mkdir(path, S_IRWXU);
!               file = PathNameOpenFile(tempfilepath,
!                                                       O_RDWR | O_CREAT | 
O_TRUNC | PG_BINARY,
!                                                       0600);
  
                /*
!                * If can't open the file in base/pgsql_tmp directory then we 
throw 
!                * an error
                 */
!               if (file <= 0 && tblspcOid == InvalidOid)
!               {
!                       pfree(path);
                        elog(ERROR, "could not create temporary file \"%s\": 
%m",
                                 tempfilepath);
+               }
        }
!       pfree(path);
  
        return file;
  }
  
+ 
  /*
   * close a file when done with it
   */
***************
*** 1292,1297 ****
--- 1350,1369 ----
                errno = save_errno;
        }
  
+       /*
+        * TEMPORARY hack to log the Windows error code on fopen failures, in
+        * hopes of diagnosing some hard-to-reproduce problems.
+        */
+ #ifdef WIN32
+       {
+               int                     save_errno = errno;
+ 
+               elog(LOG, "Windows fopen(\"%s\",\"%s\") failed: code %lu, errno 
%d",
+                        name, mode, GetLastError(), save_errno);
+               errno = save_errno;
+       }
+ #endif
+ 
        return NULL;
  }
  
***************
*** 1647,1664 ****
        struct dirent *db_de;
  
        /*
!        * Cycle through pgsql_tmp directories for all databases and remove old
         * temp files.
         */
!       db_dir = AllocateDir("base");
  
!       while ((db_de = ReadDir(db_dir, "base")) != NULL)
        {
                if (strcmp(db_de->d_name, ".") == 0 ||
                        strcmp(db_de->d_name, "..") == 0)
                        continue;
  
!               snprintf(temp_path, sizeof(temp_path), "base/%s/%s",
                                 db_de->d_name, PG_TEMP_FILES_DIR);
                RemovePgTempFilesInDir(temp_path);
        }
--- 1719,1742 ----
        struct dirent *db_de;
  
        /*
!        * First process pgsql_tmp in base directory
!        */
!       snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
!       RemovePgTempFilesInDir(temp_path);
! 
!       /*
!        * Cycle through pgsql_tmp directories for all tablespaces and remove 
old
         * temp files.
         */
!       db_dir = AllocateDir("pg_tblspc");
  
!       while ((db_de = ReadDir(db_dir, "pg_tblspc")) != NULL)
        {
                if (strcmp(db_de->d_name, ".") == 0 ||
                        strcmp(db_de->d_name, "..") == 0)
                        continue;
  
!               snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
                                 db_de->d_name, PG_TEMP_FILES_DIR);
                RemovePgTempFilesInDir(temp_path);
        }
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.390
diff -c -r1.390 guc.c
*** src/backend/utils/misc/guc.c        4 May 2007 01:13:44 -0000       1.390
--- src/backend/utils/misc/guc.c        5 May 2007 05:27:40 -0000
***************
*** 103,108 ****
--- 103,109 ----
  extern int    CommitDelay;
  extern int    CommitSiblings;
  extern char *default_tablespace;
+ extern char *temp_tablespaces;
  extern bool fullPageWrites;
  
  #ifdef TRACE_SORT
***************
*** 2387,2392 ****
--- 2388,2403 ----
        },
  #endif /* USE_SSL */
  
+       {
+               {"temp_tablespaces", PGC_USERSET, PGC_S_FILE,
+                       gettext_noop("Sets the tablespaces suitable for 
creating new objects and sort files."),
+                       NULL,
+                       GUC_LIST_INPUT | GUC_LIST_QUOTE 
+               },
+               &temp_tablespaces,
+               NULL, assign_temp_tablespaces, NULL
+       },
+ 
        /* End-of-list marker */
        {
                {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: 
/projects/cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.215
diff -c -r1.215 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample       18 Apr 2007 16:44:18 
-0000      1.215
--- src/backend/utils/misc/postgresql.conf.sample       5 May 2007 05:27:41 
-0000
***************
*** 408,413 ****
--- 408,415 ----
  #search_path = '"$user",public'               # schema names
  #default_tablespace = ''              # a tablespace name, '' uses
                                        # the default
+ #temp_tablespaces = ''                # a list of tablespace names, 
+                                                       # '' uses 
default_tablespace
  #check_function_bodies = on
  #default_transaction_isolation = 'read committed'
  #default_transaction_read_only = off
Index: src/backend/utils/sort/logtape.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/sort/logtape.c,v
retrieving revision 1.23
diff -c -r1.23 logtape.c
*** src/backend/utils/sort/logtape.c    5 Jan 2007 22:19:47 -0000       1.23
--- src/backend/utils/sort/logtape.c    5 May 2007 05:27:42 -0000
***************
*** 77,82 ****
--- 77,83 ----
  
  #include "postgres.h"
  
+ #include "commands/tablespace.h"
  #include "storage/buffile.h"
  #include "utils/logtape.h"
  
***************
*** 528,534 ****
        Assert(ntapes > 0);
        lts = (LogicalTapeSet *) palloc(sizeof(LogicalTapeSet) +
                                                                        (ntapes 
- 1) *sizeof(LogicalTape));
!       lts->pfile = BufFileCreateTemp(false);
        lts->nFileBlocks = 0L;
        lts->forgetFreeSpace = false;
        lts->blocksSorted = true;       /* a zero-length array is sorted ... */
--- 529,535 ----
        Assert(ntapes > 0);
        lts = (LogicalTapeSet *) palloc(sizeof(LogicalTapeSet) +
                                                                        (ntapes 
- 1) *sizeof(LogicalTape));
!       lts->pfile = BufFileCreateTemp(false, GetTempTablespace());
        lts->nFileBlocks = 0L;
        lts->forgetFreeSpace = false;
        lts->blocksSorted = true;       /* a zero-length array is sorted ... */
Index: src/backend/utils/sort/tuplestore.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/sort/tuplestore.c,v
retrieving revision 1.30
diff -c -r1.30 tuplestore.c
*** src/backend/utils/sort/tuplestore.c 5 Jan 2007 22:19:47 -0000       1.30
--- src/backend/utils/sort/tuplestore.c 5 May 2007 05:27:44 -0000
***************
*** 44,49 ****
--- 44,50 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "commands/tablespace.h"
  #include "storage/buffile.h"
  #include "utils/memutils.h"
  #include "utils/tuplestore.h"
***************
*** 388,394 ****
                        /*
                         * Nope; time to switch to tape-based operation.
                         */
!                       state->myfile = BufFileCreateTemp(state->interXact);
                        state->status = TSS_WRITEFILE;
                        dumptuples(state);
                        break;
--- 389,396 ----
                        /*
                         * Nope; time to switch to tape-based operation.
                         */
!                       state->myfile = BufFileCreateTemp(state->interXact, 
!                                                                               
          GetTempTablespace());
                        state->status = TSS_WRITEFILE;
                        dumptuples(state);
                        break;
Index: src/include/commands/tablespace.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/tablespace.h,v
retrieving revision 1.16
diff -c -r1.16 tablespace.h
*** src/include/commands/tablespace.h   6 Mar 2007 02:06:15 -0000       1.16
--- src/include/commands/tablespace.h   5 May 2007 05:27:45 -0000
***************
*** 41,46 ****
--- 41,47 ----
  extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
  
  extern Oid    GetDefaultTablespace(void);
+ extern Oid    GetTempTablespace(void);
  
  extern Oid    get_tablespace_oid(const char *tablespacename);
  extern char *get_tablespace_name(Oid spc_oid);
Index: src/include/storage/buffile.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/storage/buffile.h,v
retrieving revision 1.20
diff -c -r1.20 buffile.h
*** src/include/storage/buffile.h       5 Jan 2007 22:19:57 -0000       1.20
--- src/include/storage/buffile.h       5 May 2007 05:27:45 -0000
***************
*** 34,40 ****
   * prototypes for functions in buffile.c
   */
  
! extern BufFile *BufFileCreateTemp(bool interXact);
  extern void BufFileClose(BufFile *file);
  extern size_t BufFileRead(BufFile *file, void *ptr, size_t size);
  extern size_t BufFileWrite(BufFile *file, void *ptr, size_t size);
--- 34,40 ----
   * prototypes for functions in buffile.c
   */
  
! extern BufFile *BufFileCreateTemp(bool interXact, Oid tblspcOid);
  extern void BufFileClose(BufFile *file);
  extern size_t BufFileRead(BufFile *file, void *ptr, size_t size);
  extern size_t BufFileWrite(BufFile *file, void *ptr, size_t size);
Index: src/include/storage/fd.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/storage/fd.h,v
retrieving revision 1.57
diff -c -r1.57 fd.h
*** src/include/storage/fd.h    5 Jan 2007 22:19:57 -0000       1.57
--- src/include/storage/fd.h    5 May 2007 05:27:46 -0000
***************
*** 59,67 ****
   */
  
  /* Operations on virtual Files --- equivalent to Unix kernel file ops */
  extern File FileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
  extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
! extern File OpenTemporaryFile(bool interXact);
  extern void FileClose(File file);
  extern void FileUnlink(File file);
  extern int    FileRead(File file, char *buffer, int amount);
--- 59,70 ----
   */
  
  /* Operations on virtual Files --- equivalent to Unix kernel file ops */
+ #ifdef NOT_USED
  extern File FileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
+ #endif
  extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
! extern File OpenTemporaryFile(bool interXact, Oid tblspcOid);
! extern File OpenTempFileInTblspc(Oid tblspcOid);
  extern void FileClose(File file);
  extern void FileUnlink(File file);
  extern int    FileRead(File file, char *buffer, int amount);
Index: src/include/utils/guc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.81
diff -c -r1.81 guc.h
*** src/include/utils/guc.h     12 Apr 2007 06:53:48 -0000      1.81
--- src/include/utils/guc.h     5 May 2007 05:27:46 -0000
***************
*** 238,241 ****
--- 238,245 ----
  extern const char *assign_xlog_sync_method(const char *method,
                                                bool doit, GucSource source);
  
+ /* in commands/tablespace.c */
+ extern const char *assign_temp_tablespaces(const char *newval,
+                                                 bool doit, GucSource source);
+ 
  #endif   /* GUC_H */
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

               http://archives.postgresql.org

Reply via email to