Sorry about the wrong diff format. Attached is the good one. A Dimecres 25 Octubre 2006 09:07, Neil Conway va escriure: > On Wed, 2006-10-25 at 00:45 +0200, Albert Cervera Areny wrote: > > Hope the diff and idents are ok. > > Patches should be submitted in context diff (diff -c) format. > > -Neil
Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.206 diff -c -r1.206 tablecmds.c *** src/backend/commands/tablecmds.c 13 Oct 2006 21:43:18 -0000 1.206 --- src/backend/commands/tablecmds.c 25 Oct 2006 20:06:18 -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.39 diff -c -r1.39 tablespace.c *** src/backend/commands/tablespace.c 4 Oct 2006 00:29:51 -0000 1.39 --- src/backend/commands/tablespace.c 25 Oct 2006 20:06: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); *************** *** 930,935 **** --- 933,1059 ---- 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 = 0; + 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; + + 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; + } + + foreach(l, namelist) + { + curname = (char *) lfirst(l); + if ( i == next_temp_tablespace ) + break; + i++; + } + + pfree(rawname); + + /* 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); + 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); + + /* + * 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,1007 **** --- 1126,1170 ---- return result; } + /* + * get_tablespace_path - given a tablespace OID, look up the path + * + * Returns a palloc'd string, or NULL if no such tablespace. + */ + char * + get_tablespace_path(Oid spc_oid) + { + char *result; + Relation rel; + HeapScanDesc scandesc; + HeapTuple tuple; + ScanKeyData entry[1]; + bool isNull; + Datum pathDatum; + + /* Search pg_tablespace */ + rel = heap_open(TableSpaceRelationId, AccessShareLock); + + ScanKeyInit(&entry[0], + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(spc_oid)); + scandesc = heap_beginscan(rel, SnapshotNow, 1, entry); + tuple = heap_getnext(scandesc, ForwardScanDirection); + + /* We assume that there can be at most one matching tuple */ + if (HeapTupleIsValid(tuple)) { + pathDatum = heap_getattr( tuple, Anum_pg_tablespace_spclocation, + RelationGetDescr(rel), &isNull ); + result = pstrdup( DatumGetCString( pathDatum ) ); + } else + result = NULL; + + heap_endscan(scandesc); + heap_close(rel, AccessShareLock); + + return result; + } /* * TABLESPACE resource manager's routines Index: src/backend/storage/file/fd.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/storage/file/fd.c,v retrieving revision 1.130 diff -c -r1.130 fd.c *** src/backend/storage/file/fd.c 4 Oct 2006 00:29:57 -0000 1.130 --- src/backend/storage/file/fd.c 25 Oct 2006 20:06:21 -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" *************** *** 879,893 **** { 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. --- 881,914 ---- { char tempfilepath[MAXPGPATH]; File file; + Oid oid; + char *path; + + /* + * Take a look what should be the path of the temporary file + */ + oid = GetTempTablespace(); + if ( oid == InvalidOid ) + { + path = PG_TEMP_FILES_DIR; + } + else + { + path = get_tablespace_path(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++); + /* path should be pfreed in case it was obtained from get_tablespace_path */ + if ( oid != InvalidOid ) + pfree(path); + /* * Open the file. Note: we don't use O_EXCL, in case there is an orphaned * temp file that can be reused. Index: src/backend/utils/misc/guc.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v retrieving revision 1.357 diff -c -r1.357 guc.c *** src/backend/utils/misc/guc.c 19 Oct 2006 18:32:47 -0000 1.357 --- src/backend/utils/misc/guc.c 25 Oct 2006 20:06:26 -0000 *************** *** 96,101 **** --- 96,102 ---- extern int CommitDelay; extern int CommitSiblings; extern char *default_tablespace; + extern char *temp_tablespaces; extern bool fullPageWrites; #ifdef TRACE_SORT *************** *** 2248,2253 **** --- 2249,2264 ---- 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/include/commands/tablespace.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/commands/tablespace.h,v retrieving revision 1.13 diff -c -r1.13 tablespace.h *** src/include/commands/tablespace.h 24 Mar 2006 04:32:13 -0000 1.13 --- src/include/commands/tablespace.h 25 Oct 2006 20:06:27 -0000 *************** *** 41,49 **** --- 41,51 ---- 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); + extern char *get_tablespace_path(Oid spc_oid); extern bool directory_is_empty(const char *path); Index: src/include/utils/guc.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v retrieving revision 1.76 diff -c -r1.76 guc.h *** src/include/utils/guc.h 19 Oct 2006 18:32:47 -0000 1.76 --- src/include/utils/guc.h 25 Oct 2006 20:06:33 -0000 *************** *** 237,240 **** --- 237,244 ---- 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 3: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faq