Sorry, patch attached this time...

On 1/12/07, Jaime Casanova <[EMAIL PROTECTED]> wrote:
On 1/11/07, Joshua D. Drake <[EMAIL PROTECTED]> wrote:
> On Thu, 2007-01-11 at 21:05 -0500, Jaime Casanova wrote:
> > On 1/11/07, Albert Cervera Areny <[EMAIL PROTECTED]> wrote:
> > > Please, go on with that, I hadn't seen that problem. Indeed, I read Andrew
> > > answer to your question and I think it's a nice solution.
> > >
> >
> > yes... i'm always trying to kill flies with tanks... ;)
>
> Isn't that a little expensive on gas?
>

maybe... but... what a beatiful explosion we can get... ;)

seriously, attached's a new version of the patch...
the patch use temp tablespaces for:
 - temp tables
 - temp files (generated by sorts and such)
 - indexes on temp tables

the temp_tablespaces GUC still cannot be set from postgresql.conf, i
will keep working on that but i have to understand the code...

any comments on this patch? although it's not ready for apply it yet,
i think Albert made a good work on it...

--
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



--
Atentamente,
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
Index: src/backend/commands/indexcmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/indexcmds.c,v
retrieving revision 1.152
diff -c -r1.152 indexcmds.c
*** src/backend/commands/indexcmds.c    9 Jan 2007 02:14:11 -0000       1.152
--- src/backend/commands/indexcmds.c    12 Jan 2007 05:08:35 -0000
***************
*** 209,215 ****
        }
        else
        {
!               tablespaceId = GetDefaultTablespace();
                /* note InvalidOid is OK in this case */
        }
  
--- 209,221 ----
        }
        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.210
diff -c -r1.210 tablecmds.c
*** src/backend/commands/tablecmds.c    5 Jan 2007 22:19:26 -0000       1.210
--- src/backend/commands/tablecmds.c    12 Jan 2007 05:08:47 -0000
***************
*** 334,339 ****
--- 334,343 ----
                                         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.40
diff -c -r1.40 tablespace.c
*** src/backend/commands/tablespace.c   5 Jan 2007 22:19:26 -0000       1.40
--- src/backend/commands/tablespace.c   12 Jan 2007 05:08:49 -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);
***************
*** 930,935 ****
--- 933,1069 ----
        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;
+       /*
+        * 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?
+                */
+               foreach(l, namelist)
+               {
+                       char       *curname = (char *) lfirst(l);
+ 
+                       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++;
+               }
+       }
+ 
+       pfree(rawname);
+       list_free(namelist);
+       next_temp_tablespace = MyProcPid % num_temp_tablespaces;
+       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;
+ 
+       /* 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;
+       }
+ 
+       elog(NOTICE, "Proximo temp tablespace: %d", next_temp_tablespace);
+       /* 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
***************
*** 1002,1008 ****
        return result;
  }
  
- 
  /*
   * TABLESPACE resource manager's routines
   */
--- 1136,1141 ----
Index: src/backend/executor/execMain.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/execMain.c,v
retrieving revision 1.283
diff -c -r1.283 execMain.c
*** src/backend/executor/execMain.c     5 Jan 2007 22:19:27 -0000       1.283
--- src/backend/executor/execMain.c     12 Jan 2007 05:08:53 -0000
***************
*** 2409,2414 ****
--- 2409,2418 ----
                                         errmsg("tablespace \"%s\" does not 
exist",
                                                        
parseTree->intoTableSpaceName)));
        }
+       else if (parseTree->into->istemp)
+       {
+               tablespaceId = GetTempTablespace();
+       }
        else
        {
                tablespaceId = GetDefaultTablespace();
Index: src/backend/storage/file/fd.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/file/fd.c,v
retrieving revision 1.134
diff -c -r1.134 fd.c
*** src/backend/storage/file/fd.c       9 Jan 2007 22:03:51 -0000       1.134
--- src/backend/storage/file/fd.c       12 Jan 2007 05:08:56 -0000
***************
*** 46,51 ****
--- 46,53 ----
  #include <unistd.h>
  #include <fcntl.h>
  
+ #include "commands/tablespace.h"
+ 
  #include "miscadmin.h"
  #include "access/xact.h"
  #include "storage/fd.h"
***************
*** 76,81 ****
--- 78,84 ----
   */
  #define FD_MINFREE                            10
  
+ #define OIDCHARS        10                      /* max chars printed by %u */
  
  /*
   * A number of platforms allow individual processes to open many more files
***************
*** 880,925 ****
  {
        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;
  
--- 883,968 ----
  {
        char            tempfilepath[MAXPGPATH];
        File            file;
+       Oid             oid;
+       char            *path;
+       int             pathlen;
  
        /*
!        * Take a look what should be the path of the temporary file
         */
!       oid = GetTempTablespace();
!       if ( oid != InvalidOid )
!       {
!               /*
!                * As we got a valid tablespace, try to create the
!                * file there
!                */
  
!               pathlen = 10 + OIDCHARS + 1;
!               path = (char *) palloc(pathlen);
!               snprintf(path, pathlen, "pg_tblspc/%u", oid );
! 
!               /*
!                * 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++);
!               pfree(path);
!               file = PathNameOpenFile(tempfilepath,
                                                        O_RDWR | O_CREAT | 
O_TRUNC | PG_BINARY,
                                                        0600);
!       }
  
+       /*
+        * Create a normal temporary file if no tablespace returned or
+        * couldn't create the file in the tablespace "oid"
+        */
+       if (oid == InvalidOid || file <= 0) 
+       {
+               path = 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 = 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;
  
***************
*** 1292,1297 ****
--- 1335,1354 ----
                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;
  }
  
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.367
diff -c -r1.367 guc.c
*** src/backend/utils/misc/guc.c        9 Jan 2007 22:16:46 -0000       1.367
--- src/backend/utils/misc/guc.c        12 Jan 2007 05:09:06 -0000
***************
*** 98,103 ****
--- 98,104 ----
  extern int    CommitDelay;
  extern int    CommitSiblings;
  extern char *default_tablespace;
+ extern char *temp_tablespaces;
  extern bool fullPageWrites;
  
  #ifdef TRACE_SORT
***************
*** 2279,2284 ****
--- 2280,2295 ----
                NULL, assign_canonical_path, NULL
        },
  
+       {
+               {"temp_tablespaces", PGC_SUSET, 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.201
diff -c -r1.201 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample       9 Jan 2007 22:16:46 
-0000       1.201
--- src/backend/utils/misc/postgresql.conf.sample       12 Jan 2007 05:09:07 
-0000
***************
*** 395,401 ****
  
  #search_path = '"$user",public'               # schema names
  #default_tablespace = ''              # a tablespace name, '' uses
!                                       # the default
  #check_function_bodies = on
  #default_transaction_isolation = 'read committed'
  #default_transaction_read_only = off
--- 395,402 ----
  
  #search_path = '"$user",public'               # schema names
  #default_tablespace = ''              # a tablespace name, '' uses
!                                                               # the default
!                                       
  #check_function_bodies = on
  #default_transaction_isolation = 'read committed'
  #default_transaction_read_only = off
Index: src/include/commands/tablespace.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/tablespace.h,v
retrieving revision 1.14
diff -c -r1.14 tablespace.h
*** src/include/commands/tablespace.h   5 Jan 2007 22:19:54 -0000       1.14
--- src/include/commands/tablespace.h   12 Jan 2007 05:09:08 -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/utils/guc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.78
diff -c -r1.78 guc.h
*** src/include/utils/guc.h     9 Jan 2007 21:31:17 -0000       1.78
--- src/include/utils/guc.h     12 Jan 2007 05:09:10 -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