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