Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 148ea5c

Browse files
committed
Add GUC temp_tablespaces to provide a default location for temporary
objects. Jaime Casanova
1 parent 5af6b2a commit 148ea5c

File tree

10 files changed

+272
-16
lines changed

10 files changed

+272
-16
lines changed

doc/src/sgml/config.sgml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.104 2007/01/20 21:30:26 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.105 2007/01/25 04:35:10 momjian Exp $ -->
22

33
<chapter Id="runtime-config">
44
<title>Server Configuration</title>
@@ -3398,6 +3398,35 @@ SELECT * FROM parent WHERE key = 2400;
33983398
</listitem>
33993399
</varlistentry>
34003400

3401+
<varlistentry id="guc-temp-tablespaces" xreflabel="temp_tablespaces">
3402+
<term><varname>temp_tablespaces</varname> (<type>string</type>)</term>
3403+
<indexterm>
3404+
<primary><varname>temp_tablespaces</> configuration parameter</primary>
3405+
</indexterm>
3406+
<indexterm><primary>tablespace</><secondary>temp</></>
3407+
<listitem>
3408+
<para>
3409+
This variable specifies tablespaces in which to create temp
3410+
objects (temp tables and indexes on temp tables) when a
3411+
<command>CREATE</> command does not explicitly specify a tablespace
3412+
and temp files when necessary (eg. for sorting operations).
3413+
</para>
3414+
3415+
<para>
3416+
The value is either a list of names of tablespaces, or an empty
3417+
string to specify using the default tablespace of the current database.
3418+
If the value does not match the name of any existing tablespace,
3419+
<productname>PostgreSQL</> will automatically use the default
3420+
tablespace of the current database.
3421+
</para>
3422+
3423+
<para>
3424+
For more information on tablespaces,
3425+
see <xref linkend="manage-ag-tablespaces">.
3426+
</para>
3427+
</listitem>
3428+
</varlistentry>
3429+
34013430
<varlistentry id="guc-check-function-bodies" xreflabel="check_function_bodies">
34023431
<term><varname>check_function_bodies</varname> (<type>boolean</type>)</term>
34033432
<indexterm>

src/backend/commands/indexcmds.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.153 2007/01/20 23:13:01 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.154 2007/01/25 04:35:10 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -209,7 +209,13 @@ DefineIndex(RangeVar *heapRelation,
209209
}
210210
else
211211
{
212-
tablespaceId = GetDefaultTablespace();
212+
/*
213+
* if the target table is temporary then use a temp_tablespace
214+
*/
215+
if (!rel->rd_istemp)
216+
tablespaceId = GetDefaultTablespace();
217+
else
218+
tablespaceId = GetTempTablespace();
213219
/* note InvalidOid is OK in this case */
214220
}
215221

src/backend/commands/tablecmds.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.211 2007/01/25 04:17:45 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.212 2007/01/25 04:35:10 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -334,6 +334,10 @@ DefineRelation(CreateStmt *stmt, char relkind)
334334
errmsg("tablespace \"%s\" does not exist",
335335
stmt->tablespacename)));
336336
}
337+
else if (stmt->relation->istemp)
338+
{
339+
tablespaceId = GetTempTablespace();
340+
}
337341
else
338342
{
339343
tablespaceId = GetDefaultTablespace();

src/backend/commands/tablespace.c

Lines changed: 141 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.40 2007/01/05 22:19:26 momjian Exp $
40+
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.41 2007/01/25 04:35:10 momjian Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -65,9 +65,12 @@
6565
#include "utils/lsyscache.h"
6666

6767

68-
/* GUC variable */
68+
/* GUC variables */
6969
char *default_tablespace = NULL;
70+
char *temp_tablespaces = NULL;
7071

72+
int next_temp_tablespace;
73+
int num_temp_tablespaces;
7174

7275
static bool remove_tablespace_directories(Oid tablespaceoid, bool redo);
7376
static void set_short_version(const char *path);
@@ -930,6 +933,142 @@ GetDefaultTablespace(void)
930933
return result;
931934
}
932935

936+
/*
937+
* Routines for handling the GUC variable 'temp_tablespaces'.
938+
*/
939+
940+
/* assign_hook: validate new temp_tablespaces, do extra actions as needed */
941+
const char *
942+
assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
943+
{
944+
char *rawname;
945+
List *namelist;
946+
ListCell *l;
947+
948+
/* Need a modifiable copy of string */
949+
rawname = pstrdup(newval);
950+
951+
/* Parse string into list of identifiers */
952+
if (!SplitIdentifierString(rawname, ',', &namelist))
953+
{
954+
/* syntax error in name list */
955+
pfree(rawname);
956+
list_free(namelist);
957+
return NULL;
958+
}
959+
960+
num_temp_tablespaces = 0;
961+
foreach(l, namelist)
962+
{
963+
char *curname = (char *) lfirst(l);
964+
965+
/*
966+
* If we aren't inside a transaction, we cannot do database access so
967+
* cannot verify the individual names. Must accept the list on faith.
968+
*/
969+
if (source >= PGC_S_INTERACTIVE && IsTransactionState())
970+
{
971+
/*
972+
* Verify that all the names are valid tablspace names
973+
* We do not check for USAGE rights should we?
974+
*/
975+
if (get_tablespace_oid(curname) == InvalidOid)
976+
ereport((source == PGC_S_TEST) ? NOTICE : ERROR,
977+
(errcode(ERRCODE_UNDEFINED_OBJECT),
978+
errmsg("tablespace \"%s\" does not exist", curname)));
979+
}
980+
num_temp_tablespaces++;
981+
}
982+
983+
/*
984+
* Select the first tablespace to use
985+
*/
986+
next_temp_tablespace = MyProcPid % num_temp_tablespaces;
987+
988+
pfree(rawname);
989+
list_free(namelist);
990+
return newval;
991+
}
992+
993+
/*
994+
* GetTempTablespace -- get the OID of the tablespace for temporary objects
995+
*
996+
* May return InvalidOid to indicate "use the database's default tablespace"
997+
*
998+
* This exists to hide the temp_tablespace GUC variable.
999+
*/
1000+
Oid
1001+
GetTempTablespace(void)
1002+
{
1003+
Oid result;
1004+
char *curname = NULL;
1005+
char *rawname;
1006+
List *namelist;
1007+
ListCell *l;
1008+
int i = 0;
1009+
1010+
if ( temp_tablespaces == NULL )
1011+
return InvalidOid;
1012+
1013+
/* Need a modifiable version of temp_tablespaces */
1014+
rawname = pstrdup(temp_tablespaces);
1015+
1016+
/* Parse string into list of identifiers */
1017+
if (!SplitIdentifierString(rawname, ',', &namelist))
1018+
{
1019+
/* syntax error in name list */
1020+
pfree(rawname);
1021+
list_free(namelist);
1022+
return InvalidOid;
1023+
}
1024+
1025+
/*
1026+
* Iterate through the list of namespaces until the one we need
1027+
* (next_temp_tablespace)
1028+
*/
1029+
foreach(l, namelist)
1030+
{
1031+
curname = (char *) lfirst(l);
1032+
if ( i == next_temp_tablespace )
1033+
break;
1034+
i++;
1035+
}
1036+
1037+
1038+
/* Prepare for the next time the function is called */
1039+
next_temp_tablespace++;
1040+
if (next_temp_tablespace == num_temp_tablespaces)
1041+
next_temp_tablespace = 0;
1042+
1043+
/* Fast path for temp_tablespaces == "" */
1044+
if ( curname == NULL || curname[0] == '\0') {
1045+
list_free(namelist);
1046+
pfree(rawname);
1047+
return InvalidOid;
1048+
}
1049+
1050+
/*
1051+
* It is tempting to cache this lookup for more speed, but then we would
1052+
* fail to detect the case where the tablespace was dropped since the GUC
1053+
* variable was set. Note also that we don't complain if the value fails
1054+
* to refer to an existing tablespace; we just silently return InvalidOid,
1055+
* causing the new object to be created in the database's tablespace.
1056+
*/
1057+
result = get_tablespace_oid(curname);
1058+
1059+
/* We don't free rawname before because curname points to a part of it */
1060+
pfree(rawname);
1061+
1062+
/*
1063+
* Allow explicit specification of database's default tablespace in
1064+
* default_tablespace without triggering permissions checks.
1065+
*/
1066+
if (result == MyDatabaseTableSpace)
1067+
result = InvalidOid;
1068+
1069+
list_free(namelist);
1070+
return result;
1071+
}
9331072

9341073
/*
9351074
* get_tablespace_oid - given a tablespace name, look up the OID

src/backend/executor/execMain.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.284 2007/01/25 02:17:26 momjian Exp $
29+
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.285 2007/01/25 04:35:10 momjian Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -2409,6 +2409,10 @@ OpenIntoRel(QueryDesc *queryDesc)
24092409
errmsg("tablespace \"%s\" does not exist",
24102410
parseTree->intoTableSpaceName)));
24112411
}
2412+
else if (parseTree->into->istemp)
2413+
{
2414+
tablespaceId = GetTempTablespace();
2415+
}
24122416
else
24132417
{
24142418
tablespaceId = GetDefaultTablespace();

src/backend/storage/file/fd.c

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.134 2007/01/09 22:03:51 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.135 2007/01/25 04:35:10 momjian Exp $
1111
*
1212
* NOTES:
1313
*
@@ -46,6 +46,8 @@
4646
#include <unistd.h>
4747
#include <fcntl.h>
4848

49+
#include "commands/tablespace.h"
50+
4951
#include "miscadmin.h"
5052
#include "access/xact.h"
5153
#include "storage/fd.h"
@@ -76,6 +78,7 @@
7678
*/
7779
#define FD_MINFREE 10
7880

81+
#define OIDCHARS 10 /* max chars printed by %u */
7982

8083
/*
8184
* A number of platforms allow individual processes to open many more files
@@ -880,13 +883,51 @@ OpenTemporaryFile(bool interXact)
880883
{
881884
char tempfilepath[MAXPGPATH];
882885
File file;
886+
Oid oid;
887+
char *path;
888+
int pathlen;
883889

884890
/*
885-
* Generate a tempfile name that should be unique within the current
886-
* database instance.
891+
* Take a look what should be the path of the temporary file
887892
*/
888-
snprintf(tempfilepath, sizeof(tempfilepath),
889-
"%s/%s%d.%ld", PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX,
893+
oid = GetTempTablespace();
894+
if (oid != InvalidOid)
895+
{
896+
/*
897+
* As we got a valid tablespace, try to create the
898+
* file there
899+
*/
900+
901+
pathlen = strlen("pg_tblspc/") + OIDCHARS + 1;
902+
path = (char *) palloc(pathlen);
903+
snprintf(path, pathlen, "pg_tblspc/%u", oid );
904+
905+
/*
906+
* Generate a tempfile name that should be unique within the current
907+
* database instance.
908+
*/
909+
snprintf(tempfilepath, sizeof(tempfilepath),
910+
"%s/%s%d.%ld", path, PG_TEMP_FILE_PREFIX,
911+
MyProcPid, tempFileCounter++);
912+
pfree(path);
913+
file = PathNameOpenFile(tempfilepath,
914+
O_RDWR | O_CREAT | O_TRUNC | PG_BINARY,
915+
0600);
916+
}
917+
918+
/*
919+
* Create a normal temporary file if no tablespace returned or
920+
* couldn't create the file in the tablespace "oid"
921+
*/
922+
if (oid == InvalidOid || file <= 0)
923+
{
924+
path = PG_TEMP_FILES_DIR;
925+
/*
926+
* Generate a tempfile name that should be unique within the current
927+
* database instance.
928+
*/
929+
snprintf(tempfilepath, sizeof(tempfilepath),
930+
"%s/%s%d.%ld", path, PG_TEMP_FILE_PREFIX,
890931
MyProcPid, tempFileCounter++);
891932

892933
/*
@@ -918,7 +959,8 @@ OpenTemporaryFile(bool interXact)
918959
if (file <= 0)
919960
elog(ERROR, "could not create temporary file \"%s\": %m",
920961
tempfilepath);
921-
}
962+
}
963+
}
922964

923965
/* Mark it for deletion at close */
924966
VfdCache[file].fdstate |= FD_TEMPORARY;
@@ -1292,6 +1334,20 @@ AllocateFile(const char *name, const char *mode)
12921334
errno = save_errno;
12931335
}
12941336

1337+
/*
1338+
* TEMPORARY hack to log the Windows error code on fopen failures, in
1339+
* hopes of diagnosing some hard-to-reproduce problems.
1340+
*/
1341+
#ifdef WIN32
1342+
{
1343+
int save_errno = errno;
1344+
1345+
elog(LOG, "Windows fopen(\"%s\",\"%s\") failed: code %lu, errno %d",
1346+
name, mode, GetLastError(), save_errno);
1347+
errno = save_errno;
1348+
}
1349+
#endif
1350+
12951351
return NULL;
12961352
}
12971353

0 commit comments

Comments
 (0)