diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/doc/src/sgml/ref/create_database.sgml a/doc/src/sgml/ref/create_database.sgml
*** pgsql/doc/src/sgml/ref/create_database.sgml Mon Sep 3 08:57:49 2001
--- a/doc/src/sgml/ref/create_database.sgml Tue Sep 11 14:04:35 2001
***************
*** 25,30 ****
--- 25,31 ----
CREATE DATABASE name
[ WITH [ LOCATION = 'dbpath' ]
+ [ INDEX_LOCATION = 'idxpath' ]
[ TEMPLATE = template ]
[ ENCODING = encoding ] ]
***************
*** 52,57 ****
--- 53,69 ----
An alternate filesystem location in which to store the new database,
+ specified as a string literal;
+ or DEFAULT to use the default location.
+
+
+
+
+
+ idxpath
+
+
+ An alternate filesystem location in which to store the new database indexes,
specified as a string literal;
or DEFAULT to use the default location.
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/catalog/catalog.c a/src/backend/catalog/catalog.c
*** pgsql/src/backend/catalog/catalog.c Fri Aug 10 14:57:33 2001
--- a/src/backend/catalog/catalog.c Sun Sep 9 16:18:26 2001
***************
*** 46,51 ****
--- 46,77 ----
}
return path;
}
+ /*
+ * relidxpath - construct path to a relation's file
+ *
+ * Result is a palloc'd string.
+ */
+
+ char *
+ relidxpath(RelFileNode rnode)
+ {
+ char *path;
+
+ if (rnode.tblNode == (Oid) 0) /* "global tablespace" */
+ {
+ /* Shared system relations live in {datadir}/global */
+ path = (char *) palloc(strlen(DataDir) + 8 + sizeof(NameData) + 1);
+ sprintf(path, "%s/global/%u", DataDir, rnode.relNode);
+ }
+ else
+ {
+ path = (char *) palloc(strlen(DataDir) + 6 + 2 * sizeof(NameData) + 3);
+ sprintf(path, "%s/base/%u_index/%u", DataDir,
+ rnode.tblNode,rnode.relNode);
+ }
+ return path;
+ }
+
/*
* GetDatabasePath - construct path to a database dir
***************
*** 70,75 ****
--- 96,121 ----
sprintf(path, "%s/base/%u", DataDir, tblNode);
}
return path;
+ }
+
+
+ char *
+ GetIndexPath(Oid tblNode)
+ {
+ char *path;
+
+ if (tblNode == (Oid) 0) /* "global tablespace" */
+ {
+ /* Shared system relations live in {datadir}/global */
+ path = (char *) palloc(strlen(DataDir) + 8);
+ sprintf(path, "%s/global", DataDir);
+ }
+ else
+ {
+ path = (char *) palloc(strlen(DataDir) + 6 + sizeof(NameData) + 1);
+ sprintf(path, "%s/base/%u_index", DataDir, tblNode);
+ }
+ return path;
}
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/commands/dbcommands.c a/src/backend/commands/dbcommands.c
*** pgsql/src/backend/commands/dbcommands.c Thu Sep 6 00:57:28 2001
--- a/src/backend/commands/dbcommands.c Mon Sep 10 16:24:08 2001
***************
*** 45,53 ****
static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
! char *dbpath);
static bool get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb);
static char *resolve_alt_dbpath(const char *dbpath, Oid dboid);
static bool remove_dbdirs(const char *real_loc, const char *altloc);
/*
--- 45,54 ----
static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
! char *dbpath,char *idxpath);
static bool get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb);
static char *resolve_alt_dbpath(const char *dbpath, Oid dboid);
+ static char *resolve_alt_idxpath(const char *dbpath, Oid dboid);
static bool remove_dbdirs(const char *real_loc, const char *altloc);
/*
***************
*** 56,67 ****
void
createdb(const char *dbname, const char *dbpath,
! const char *dbtemplate, int encoding)
{
char *nominal_loc;
char *alt_loc;
char *target_dir;
char src_loc[MAXPGPATH];
char buf[2 * MAXPGPATH + 100];
bool use_super,
use_createdb;
--- 57,72 ----
void
createdb(const char *dbname, const char *dbpath,
! const char *dbtemplate, int encoding,const char *idxpath)
{
char *nominal_loc;
+ char *nominal_idx_loc;
char *alt_loc;
+ char *alt_idx_loc;
char *target_dir;
+ char *target_idx_dir;
char src_loc[MAXPGPATH];
+ char src_idxloc[MAXPGPATH];
char buf[2 * MAXPGPATH + 100];
bool use_super,
use_createdb;
***************
*** 73,78 ****
--- 78,84 ----
TransactionId src_vacuumxid;
TransactionId src_frozenxid;
char src_dbpath[MAXPGPATH];
+ char src_idxpath[MAXPGPATH];
Relation pg_database_rel;
HeapTuple tuple;
TupleDesc pg_database_dsc;
***************
*** 80,85 ****
--- 86,92 ----
char new_record_nulls[Natts_pg_database];
Oid dboid;
+
if (!get_user_info(GetUserId(), &use_super, &use_createdb))
elog(ERROR, "current user name is invalid");
***************
*** 98,104 ****
* idea, so accept possibility of race to create. We will check again
* after we grab the exclusive lock.
*/
! if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
/*
--- 105,111 ----
* idea, so accept possibility of race to create. We will check again
* after we grab the exclusive lock.
*/
! if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,NULL))
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
/*
***************
*** 110,116 ****
if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_lastsysoid,
&src_vacuumxid, &src_frozenxid,
! src_dbpath))
elog(ERROR, "CREATE DATABASE: template \"%s\" does not exist",
dbtemplate);
--- 117,123 ----
if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_lastsysoid,
&src_vacuumxid, &src_frozenxid,
! src_dbpath,src_idxpath))
elog(ERROR, "CREATE DATABASE: template \"%s\" does not exist",
dbtemplate);
***************
*** 126,138 ****
}
/*
! * Determine physical path of source database
*/
alt_loc = resolve_alt_dbpath(src_dbpath, src_dboid);
if (!alt_loc)
alt_loc = GetDatabasePath(src_dboid);
strcpy(src_loc, alt_loc);
/*
* The source DB can't have any active backends, except this one
* (exception is to allow CREATE DB while connected to template1).
--- 133,150 ----
}
/*
! * Determine physical path of source database and indexes
*/
alt_loc = resolve_alt_dbpath(src_dbpath, src_dboid);
if (!alt_loc)
alt_loc = GetDatabasePath(src_dboid);
strcpy(src_loc, alt_loc);
+ alt_loc = resolve_alt_dbpath(src_idxpath, src_dboid);
+ if (!alt_loc)
+ alt_loc = GetIndexPath(src_dboid);
+ strcpy(src_idxloc, alt_loc);
+
/*
* The source DB can't have any active backends, except this one
* (exception is to allow CREATE DB while connected to template1).
***************
*** 165,170 ****
--- 177,185 ----
* specified.
*/
nominal_loc = GetDatabasePath(dboid);
+ nominal_idx_loc = GetIndexPath(dboid);
+
+
alt_loc = resolve_alt_dbpath(dbpath, dboid);
if (strchr(nominal_loc, '\''))
***************
*** 207,215 ****
--- 222,252 ----
nominal_loc, alt_loc);
}
+ /* create symlink for default index space
+ if idxpath is null then just symlink
+ datpath to datpath_index
+ */
+
+ alt_idx_loc = resolve_alt_idxpath(idxpath, dboid);
+ target_idx_dir = alt_idx_loc ? alt_idx_loc : nominal_idx_loc;
+
+ if (mkdir(target_idx_dir, S_IRWXU) != 0)
+ elog(ERROR, "CREATE DATABASE: unable to create index directory '%s': %m",
+ target_dir);
+
+ if(alt_idx_loc)
+ {
+ if (symlink(alt_idx_loc, nominal_idx_loc) != 0)
+ elog(ERROR, "CREATE DATABASE: could not link '%s' to '%s': %m",
+ nominal_loc, alt_loc);
+
+ }
+
/* Copy the template database to the new location */
snprintf(buf, sizeof(buf), "cp -r '%s' '%s'", src_loc, target_dir);
+ elog(NOTICE, buf);
+
if (system(buf) != 0)
{
if (remove_dbdirs(nominal_loc, alt_loc))
***************
*** 218,230 ****
elog(ERROR, "CREATE DATABASE: could not initialize database directory; delete failed as well");
}
/*
* Now OK to grab exclusive lock on pg_database.
*/
pg_database_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
/* Check to see if someone else created same DB name meanwhile. */
! if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
{
/* Don't hold lock while doing recursive remove */
heap_close(pg_database_rel, AccessExclusiveLock);
--- 255,280 ----
elog(ERROR, "CREATE DATABASE: could not initialize database directory; delete failed as well");
}
+ /* Copy the template database index files to the new location */
+ snprintf(buf, sizeof(buf), "cp -r '%s'/* '%s'", src_idxloc, target_idx_dir);
+
+ if (system(buf) != 0)
+ {
+ if (remove_dbdirs(nominal_idx_loc, alt_idx_loc))
+ elog(ERROR, "CREATE DATABASE: could not initialize index directory");
+ else
+ elog(ERROR, "CREATE DATABASE: could not initialize index directory; delete failed as well");
+ if (! remove_dbdirs(nominal_loc, alt_loc))
+ elog(ERROR, "CREATE DATABASE: could not initialize index directory; data dir delete failed as well");
+ }
+
/*
* Now OK to grab exclusive lock on pg_database.
*/
pg_database_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
/* Check to see if someone else created same DB name meanwhile. */
! if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,NULL))
{
/* Don't hold lock while doing recursive remove */
heap_close(pg_database_rel, AccessExclusiveLock);
***************
*** 250,255 ****
--- 300,307 ----
/* no nulls here, GetRawDatabaseInfo doesn't like them */
new_record[Anum_pg_database_datpath - 1] =
DirectFunctionCall1(textin, CStringGetDatum(dbpath ? dbpath : ""));
+ new_record[Anum_pg_database_idxpath - 1] =
+ DirectFunctionCall1(textin, CStringGetDatum(idxpath ? idxpath : ""));
memset(new_record_nulls, ' ', sizeof(new_record_nulls));
***************
*** 298,304 ****
--- 350,359 ----
Oid db_id;
char *alt_loc;
char *nominal_loc;
+ char *alt_idx_loc;
+ char *nominal_idx_loc;
char dbpath[MAXPGPATH];
+ char idxpath[MAXPGPATH];
Relation pgdbrel;
HeapScanDesc pgdbscan;
ScanKeyData key;
***************
*** 327,333 ****
pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
if (!get_db_info(dbname, &db_id, &db_owner, NULL,
! &db_istemplate, NULL, NULL, NULL, dbpath))
elog(ERROR, "DROP DATABASE: database \"%s\" does not exist", dbname);
if (!use_super && GetUserId() != db_owner)
--- 382,388 ----
pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
if (!get_db_info(dbname, &db_id, &db_owner, NULL,
! &db_istemplate, NULL, NULL, NULL, dbpath,idxpath))
elog(ERROR, "DROP DATABASE: database \"%s\" does not exist", dbname);
if (!use_super && GetUserId() != db_owner)
***************
*** 344,349 ****
--- 399,407 ----
nominal_loc = GetDatabasePath(db_id);
alt_loc = resolve_alt_dbpath(dbpath, db_id);
+ nominal_idx_loc = GetIndexPath(db_id);
+ alt_idx_loc = resolve_alt_idxpath(idxpath, db_id);
+
/*
* Check for active backends in the target database.
*/
***************
*** 399,404 ****
--- 457,463 ----
* Remove the database's subdirectory and everything in it.
*/
remove_dbdirs(nominal_loc, alt_loc);
+ remove_dbdirs(nominal_idx_loc, alt_idx_loc);
/*
* Force dirty buffers out to disk, so that newly-connecting backends
***************
*** 419,425 ****
get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
! char *dbpath)
{
Relation relation;
ScanKeyData scanKey;
--- 478,484 ----
get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
! char *dbpath,char *idxpath)
{
Relation relation;
ScanKeyData scanKey;
***************
*** 484,489 ****
--- 543,567 ----
else
strcpy(dbpath, "");
}
+
+ /* idx path (as registered in pg_database) */
+ if (idxpath)
+ {
+ tmptext = DatumGetTextP(heap_getattr(tuple,
+ Anum_pg_database_idxpath,
+ RelationGetDescr(relation),
+ &isnull));
+ if (!isnull)
+ {
+ Assert(VARSIZE(tmptext) - VARHDRSZ < MAXPGPATH);
+
+ strncpy(idxpath, VARDATA(tmptext), VARSIZE(tmptext) - VARHDRSZ);
+ *(idxpath + VARSIZE(tmptext) - VARHDRSZ) = '\0';
+ }
+ else
+ strcpy(idxpath, "");
+ }
+
}
heap_endscan(scan);
***************
*** 553,591 ****
return ret;
}
static bool
remove_dbdirs(const char *nominal_loc, const char *alt_loc)
{
- const char *target_dir;
char buf[MAXPGPATH + 100];
bool success = true;
- target_dir = alt_loc ? alt_loc : nominal_loc;
-
/*
* Close virtual file descriptors so the kernel has more available for
* the system() call below.
*/
closeAllVfds();
! if (alt_loc)
{
- /* remove symlink */
- if (unlink(nominal_loc) != 0)
- {
- elog(NOTICE, "could not remove '%s': %m", nominal_loc);
- success = false;
- }
- }
! snprintf(buf, sizeof(buf), "rm -rf '%s'", target_dir);
! if (system(buf) != 0)
{
! elog(NOTICE, "database directory '%s' could not be removed",
! target_dir);
! success = false;
}
return success;
--- 631,711 ----
return ret;
}
+ static char *
+ resolve_alt_idxpath(const char *dbpath, Oid dboid)
+ {
+ const char *prefix;
+ char *ret;
+ size_t len;
+
+ if (dbpath == NULL || dbpath[0] == '\0')
+ return NULL;
+
+ if (strchr(dbpath, '/'))
+ {
+ if (dbpath[0] != '/')
+ elog(ERROR, "Relative paths are not allowed as database locations");
+ #ifndef ALLOW_ABSOLUTE_DBPATHS
+ elog(ERROR, "Absolute paths are not allowed as database locations");
+ #endif
+ prefix = dbpath;
+ }
+ else
+ {
+ /* must be environment variable */
+ char *var = getenv(dbpath);
+
+ if (!var)
+ elog(ERROR, "Postmaster environment variable '%s' not set", dbpath);
+ if (var[0] != '/')
+ elog(ERROR, "Postmaster environment variable '%s' must be absolute path", dbpath);
+ prefix = var;
+ }
+
+ len = strlen(prefix) + 6 + sizeof(Oid) * 8 + 1;
+ ret = palloc(len);
+ snprintf(ret, len, "%s/base/%u_index", prefix, dboid);
+
+ return ret;
+ }
+
static bool
remove_dbdirs(const char *nominal_loc, const char *alt_loc)
{
char buf[MAXPGPATH + 100];
bool success = true;
/*
* Close virtual file descriptors so the kernel has more available for
* the system() call below.
*/
closeAllVfds();
! if(alt_loc)
{
! snprintf(buf, sizeof(buf), "rm -rf '%s'", alt_loc);
!
!
! if (system(buf) != 0)
! {
! elog(NOTICE, "database directory '%s' could not be removed",
! alt_loc);
! success = false;
! }
! }
! if(nominal_loc)
{
! snprintf(buf, sizeof(buf), "rm -rf '%s'", nominal_loc);
!
! if (system(buf) != 0)
! {
! elog(NOTICE, "database directory '%s' could not be removed",
! nominal_loc);
! success = false;
! }
}
return success;
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/nodes/copyfuncs.c a/src/backend/nodes/copyfuncs.c
*** pgsql/src/backend/nodes/copyfuncs.c Sun Aug 26 12:55:59 2001
--- a/src/backend/nodes/copyfuncs.c Sun Sep 9 14:53:36 2001
***************
*** 2220,2225 ****
--- 2220,2227 ----
newnode->dbname = pstrdup(from->dbname);
if (from->dbpath)
newnode->dbpath = pstrdup(from->dbpath);
+ if (from->idxpath)
+ newnode->idxpath = pstrdup(from->idxpath);
if (from->dbtemplate)
newnode->dbtemplate = pstrdup(from->dbtemplate);
newnode->encoding = from->encoding;
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/parser/gram.y a/src/backend/parser/gram.y
*** pgsql/src/backend/parser/gram.y Thu Sep 6 00:57:28 2001
--- a/src/backend/parser/gram.y Sun Sep 9 15:01:23 2001
***************
*** 347,353 ****
DATABASE, DELIMITERS, DO,
EACH, ENCODING, EXCLUSIVE, EXPLAIN,
FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
! ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
MAXVALUE, MINVALUE, MODE, MOVE,
NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
--- 347,353 ----
DATABASE, DELIMITERS, DO,
EACH, ENCODING, EXCLUSIVE, EXPLAIN,
FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
! ILIKE, INCREMENT, INDEX, INDEX_LOCATION, INHERITS, INSTEAD, ISNULL,
LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
MAXVALUE, MINVALUE, MODE, MOVE,
NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
***************
*** 2969,2974 ****
--- 2969,2977 ----
case 3:
n->encoding = lfirsti(lnext(optitem));
break;
+ case 4:
+ n->idxpath = (char *) lsecond(optitem);
+ break;
}
}
$$ = (Node *)n;
***************
*** 2978,2983 ****
--- 2981,2987 ----
CreatedbStmt *n = makeNode(CreatedbStmt);
n->dbname = $3;
n->dbpath = NULL;
+ n->idxpath = NULL;
n->dbtemplate = NULL;
n->encoding = -1;
$$ = (Node *)n;
***************
*** 3002,3007 ****
--- 3006,3019 ----
{
$$ = lconsi(1, makeList1(NULL));
}
+ | INDEX_LOCATION '=' Sconst
+ {
+ $$ = lconsi(4, makeList1($3));
+ }
+ | INDEX_LOCATION '=' DEFAULT
+ {
+ $$ = lconsi(4, makeList1(NULL));
+ }
| TEMPLATE '=' name
{
$$ = lconsi(2, makeList1($3));
***************
*** 5637,5642 ****
--- 5649,5655 ----
| IMMEDIATE { $$ = "immediate"; }
| INCREMENT { $$ = "increment"; }
| INDEX { $$ = "index"; }
+ | INDEX_LOCATION { $$ = "index_location"; }
| INHERITS { $$ = "inherits"; }
| INSENSITIVE { $$ = "insensitive"; }
| INSERT { $$ = "insert"; }
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/parser/keywords.c a/src/backend/parser/keywords.c
*** pgsql/src/backend/parser/keywords.c Sun Aug 26 12:56:00 2001
--- a/src/backend/parser/keywords.c Sun Sep 9 14:53:42 2001
***************
*** 133,138 ****
--- 133,139 ----
{"in", IN},
{"increment", INCREMENT},
{"index", INDEX},
+ {"index_location", INDEX_LOCATION},
{"inherits", INHERITS},
{"initially", INITIALLY},
{"inner", INNER_P},
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/storage/smgr/md.c a/src/backend/storage/smgr/md.c
*** pgsql/src/backend/storage/smgr/md.c Fri Aug 24 10:07:49 2001
--- a/src/backend/storage/smgr/md.c Sun Sep 9 14:53:46 2001
***************
*** 18,23 ****
--- 18,24 ----
#include
#include
#include
+ #include
#include "catalog/catalog.h"
#include "miscadmin.h"
***************
*** 126,134 ****
int fd,
vfd;
Assert(reln->rd_fd < 0);
! path = relpath(reln->rd_node);
fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600);
--- 127,143 ----
int fd,
vfd;
+
Assert(reln->rd_fd < 0);
! if(reln->rd_rel->relkind == RELKIND_INDEX)
! {
! path = relidxpath(reln->rd_node);
! }
! else
! {
! path = relpath(reln->rd_node);
! }
fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600);
***************
*** 179,186 ****
--- 188,201 ----
int status = SM_SUCCESS;
int save_errno = 0;
char *path;
+ struct stat buf;
path = relpath(rnode);
+ if(stat(path,&buf) == -1) /* lets try for an index... */
+ {
+ pfree(path);
+ path = relidxpath(rnode);
+ }
/* Delete the first segment, or only segment if not doing segmenting */
if (unlink(path) < 0)
***************
*** 303,309 ****
Assert(reln->rd_fd < 0);
! path = relpath(reln->rd_node);
fd = FileNameOpenFile(path, O_RDWR | PG_BINARY, 0600);
--- 318,331 ----
Assert(reln->rd_fd < 0);
! if(reln->rd_rel->relkind == RELKIND_INDEX)
! {
! path = relidxpath(reln->rd_node);
! }
! else
! {
! path = relpath(reln->rd_node);
! }
fd = FileNameOpenFile(path, O_RDWR | PG_BINARY, 0600);
***************
*** 941,947 ****
*fullpath;
/* be sure we have enough space for the '.segno', if any */
! path = relpath(reln->rd_node);
if (segno > 0)
{
--- 963,976 ----
*fullpath;
/* be sure we have enough space for the '.segno', if any */
! if(reln->rd_rel->relkind == RELKIND_INDEX)
! {
! path = relidxpath(reln->rd_node);
! }
! else
! {
! path = relpath(reln->rd_node);
! }
if (segno > 0)
{
***************
*** 1066,1074 ****
#ifndef LET_OS_MANAGE_FILESIZE
BlockNumber segno;
#endif
path = relpath(rnode);
!
#ifndef LET_OS_MANAGE_FILESIZE
/* append the '.segno', if needed */
segno = blkno / ((BlockNumber) RELSEG_SIZE);
--- 1095,1109 ----
#ifndef LET_OS_MANAGE_FILESIZE
BlockNumber segno;
#endif
+ struct stat buf;
path = relpath(rnode);
! if(stat(path,&buf) == -1) /* lets try for an index... */
! {
! pfree(path);
! path = relidxpath(rnode);
! }
!
#ifndef LET_OS_MANAGE_FILESIZE
/* append the '.segno', if needed */
segno = blkno / ((BlockNumber) RELSEG_SIZE);
***************
*** 1085,1092 ****
/* call fd.c to allow other FDs to be closed if needed */
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, 0600);
if (fd < 0)
elog(DEBUG, "_mdfd_blind_getseg: couldn't open %s: %m", path);
!
pfree(path);
return fd;
--- 1120,1128 ----
/* call fd.c to allow other FDs to be closed if needed */
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, 0600);
if (fd < 0)
+ {
elog(DEBUG, "_mdfd_blind_getseg: couldn't open %s: %m", path);
! }
pfree(path);
return fd;
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/storage/smgr/smgr.c a/src/backend/storage/smgr/smgr.c
*** pgsql/src/backend/storage/smgr/smgr.c Mon Jul 2 16:50:46 2001
--- a/src/backend/storage/smgr/smgr.c Sun Sep 9 14:53:46 2001
***************
*** 171,177 ****
int
smgrcreate(int16 which, Relation reln)
{
! int fd;
PendingRelDelete *pending;
if ((fd = (*(smgrsw[which].smgr_create)) (reln)) < 0)
--- 171,177 ----
int
smgrcreate(int16 which, Relation reln)
{
! int fd;
PendingRelDelete *pending;
if ((fd = (*(smgrsw[which].smgr_create)) (reln)) < 0)
***************
*** 267,273 ****
return -1;
if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0)
if (!failOK)
! elog(ERROR, "cannot open %s: %m", RelationGetRelationName(reln));
return fd;
}
--- 267,273 ----
return -1;
if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0)
if (!failOK)
! elog(ERROR, "smgropen: cannot open %s: %m", RelationGetRelationName(reln));
return fd;
}
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/backend/tcop/utility.c a/src/backend/tcop/utility.c
*** pgsql/src/backend/tcop/utility.c Fri Sep 7 21:10:20 2001
--- a/src/backend/tcop/utility.c Sun Sep 9 14:53:46 2001
***************
*** 620,626 ****
set_ps_display(commandTag = "CREATE DATABASE");
createdb(stmt->dbname, stmt->dbpath,
! stmt->dbtemplate, stmt->encoding);
}
break;
--- 620,626 ----
set_ps_display(commandTag = "CREATE DATABASE");
createdb(stmt->dbname, stmt->dbpath,
! stmt->dbtemplate, stmt->encoding,stmt->idxpath);
}
break;
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/include/catalog/catalog.h a/src/include/catalog/catalog.h
*** pgsql/src/include/catalog/catalog.h Wed May 30 16:52:34 2001
--- a/src/include/catalog/catalog.h Sun Sep 9 14:53:49 2001
***************
*** 19,25 ****
--- 19,27 ----
#include "storage/relfilenode.h"
extern char *relpath(RelFileNode rnode);
+ extern char *relidxpath(RelFileNode rnode);
extern char *GetDatabasePath(Oid tblNode);
+ extern char *GetIndexPath(Oid tblNode);
extern bool IsSystemRelationName(const char *relname);
extern bool IsSharedSystemRelationName(const char *relname);
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/include/catalog/pg_attribute.h a/src/include/catalog/pg_attribute.h
*** pgsql/src/include/catalog/pg_attribute.h Sun Aug 26 12:56:00 2001
--- a/src/include/catalog/pg_attribute.h Sun Sep 9 15:05:23 2001
***************
*** 280,285 ****
--- 280,286 ----
DATA(insert ( 1262 datfrozenxid 28 0 4 8 0 -1 -1 t p f i f f));
/* do not mark datpath as toastable; GetRawDatabaseInfo won't cope */
DATA(insert ( 1262 datpath 25 0 -1 9 0 -1 -1 f p f i f f));
+ DATA(insert ( 1262 idxpath 25 0 -1 10 0 -1 -1 f p f i f f));
DATA(insert ( 1262 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1262 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/include/catalog/pg_class.h a/src/include/catalog/pg_class.h
*** pgsql/src/include/catalog/pg_class.h Sun Aug 26 12:56:01 2001
--- a/src/include/catalog/pg_class.h Sun Sep 9 15:04:48 2001
***************
*** 142,148 ****
DESCR("");
DATA(insert OID = 1261 ( pg_group 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ ));
DESCR("");
! DATA(insert OID = 1262 ( pg_database 88 PGUID 0 1262 0 0 0 0 f t r 9 0 0 0 0 0 t f f f _null_ ));
DESCR("");
DATA(insert OID = 376 ( pg_xactlock 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ ));
DESCR("");
--- 142,148 ----
DESCR("");
DATA(insert OID = 1261 ( pg_group 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ ));
DESCR("");
! DATA(insert OID = 1262 ( pg_database 88 PGUID 0 1262 0 0 0 0 f t r 10 0 0 0 0 0 t f f f _null_ ));
DESCR("");
DATA(insert OID = 376 ( pg_xactlock 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ ));
DESCR("");
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/include/catalog/pg_database.h a/src/include/catalog/pg_database.h
*** pgsql/src/include/catalog/pg_database.h Sun Aug 26 12:56:02 2001
--- a/src/include/catalog/pg_database.h Sun Sep 9 16:37:43 2001
***************
*** 42,47 ****
--- 42,48 ----
TransactionId datvacuumxid; /* all XIDs before this are vacuumed */
TransactionId datfrozenxid; /* all XIDs before this are frozen */
text datpath; /* VARIABLE LENGTH FIELD */
+ text idxpath; /* VARIABLE LENGTH FIELD */
} FormData_pg_database;
/* ----------------
***************
*** 55,61 ****
* compiler constants for pg_database
* ----------------
*/
! #define Natts_pg_database 9
#define Anum_pg_database_datname 1
#define Anum_pg_database_datdba 2
#define Anum_pg_database_encoding 3
--- 56,62 ----
* compiler constants for pg_database
* ----------------
*/
! #define Natts_pg_database 10
#define Anum_pg_database_datname 1
#define Anum_pg_database_datdba 2
#define Anum_pg_database_encoding 3
***************
*** 65,72 ****
#define Anum_pg_database_datvacuumxid 7
#define Anum_pg_database_datfrozenxid 8
#define Anum_pg_database_datpath 9
! DATA(insert OID = 1 ( template1 PGUID ENCODING t t 0 0 0 "" ));
DESCR("Default template database");
#define TemplateDbOid 1
--- 66,74 ----
#define Anum_pg_database_datvacuumxid 7
#define Anum_pg_database_datfrozenxid 8
#define Anum_pg_database_datpath 9
+ #define Anum_pg_database_idxpath 10
! DATA(insert OID = 1 ( template1 PGUID ENCODING t t 0 0 0 "" ""));
DESCR("Default template database");
#define TemplateDbOid 1
***************
*** 80,82 ****
--- 82,88 ----
#undef DATAMARKOID
#endif /* PG_DATABASE_H */
+
+
+
+
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/include/commands/dbcommands.h a/src/include/commands/dbcommands.h
*** pgsql/src/include/commands/dbcommands.h Wed Mar 21 23:00:42 2001
--- a/src/include/commands/dbcommands.h Sun Sep 9 14:53:49 2001
***************
*** 15,21 ****
#define DBCOMMANDS_H
extern void createdb(const char *dbname, const char *dbpath,
! const char *dbtemplate, int encoding);
extern void dropdb(const char *dbname);
#endif /* DBCOMMANDS_H */
--- 15,21 ----
#define DBCOMMANDS_H
extern void createdb(const char *dbname, const char *dbpath,
! const char *dbtemplate, int encoding,const char *idxpath);
extern void dropdb(const char *dbname);
#endif /* DBCOMMANDS_H */
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/include/nodes/parsenodes.h a/src/include/nodes/parsenodes.h
*** pgsql/src/include/nodes/parsenodes.h Sun Aug 26 12:56:02 2001
--- a/src/include/nodes/parsenodes.h Sun Sep 9 14:53:49 2001
***************
*** 656,661 ****
--- 656,662 ----
NodeTag type;
char *dbname; /* name of database to create */
char *dbpath; /* location of database (NULL = default) */
+ char *idxpath; /* locaiton of database INDEXES (NULL = default) */
char *dbtemplate; /* template to use (NULL = default) */
int encoding; /* MULTIBYTE encoding (-1 = use default) */
} CreatedbStmt;
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/interfaces/ecpg/preproc/keywords.c a/src/interfaces/ecpg/preproc/keywords.c
*** pgsql/src/interfaces/ecpg/preproc/keywords.c Thu Aug 16 16:38:55 2001
--- a/src/interfaces/ecpg/preproc/keywords.c Sun Sep 9 14:53:49 2001
***************
*** 131,136 ****
--- 131,137 ----
{"in", IN},
{"increment", INCREMENT},
{"index", INDEX},
+ {"index_location", INDEX_LOCATION},
{"inherits", INHERITS},
{"initially", INITIALLY},
{"inner", INNER_P},
diff -r -c --exclude *.o --exclude *.a --exclude *.so pgsql/src/interfaces/ecpg/preproc/preproc.y a/src/interfaces/ecpg/preproc/preproc.y
*** pgsql/src/interfaces/ecpg/preproc/preproc.y Sun Aug 19 05:21:44 2001
--- a/src/interfaces/ecpg/preproc/preproc.y Sun Sep 9 15:02:09 2001
***************
*** 219,225 ****
COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE,
DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
FORCE, FORWARD, FUNCTION, HANDLER, INCREMENT,
! INDEX, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LIMIT,
LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE,
MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER,
NONE, NOTHING, NOTIFY, NOTNULL, OFFSET, OIDS,
--- 219,225 ----
COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE,
DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
FORCE, FORWARD, FUNCTION, HANDLER, INCREMENT,
! INDEX, INDEX_LOCATION, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LIMIT,
LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE,
MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER,
NONE, NOTHING, NOTIFY, NOTNULL, OFFSET, OIDS,
***************
*** 2231,2236 ****
--- 2231,2238 ----
createdb_opt_item: LOCATION '=' StringConst { $$ = cat2_str(make_str("location ="), $3); }
| LOCATION '=' DEFAULT { $$ = make_str("location = default"); }
+ | INDEX_LOCATION '=' StringConst { $$ = cat2_str(make_str("index_location ="), $3); }
+ | INDEX_LOCATION '=' DEFAULT { $$ = make_str("index_location = default"); }
| TEMPLATE '=' name { $$ = cat2_str(make_str("template ="), $3); }
| TEMPLATE '=' DEFAULT { $$ = make_str("template = default"); }
| ENCODING '=' PosIntStringConst
***************
*** 5022,5027 ****
--- 5024,5030 ----
| IMMEDIATE { $$ = make_str("immediate"); }
| INCREMENT { $$ = make_str("increment"); }
| INDEX { $$ = make_str("index"); }
+ | INDEX_LOCATION { $$ = make_str("index_location"); }
| INHERITS { $$ = make_str("inherits"); }
| INSENSITIVE { $$ = make_str("insensitive"); }
| INSERT { $$ = make_str("insert"); }