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"); }