diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index ce2d7d496e..2ad7a7cfc7 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.27 1999/07/17 20:16:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.28 1999/11/04 08:00:58 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -80,7 +80,7 @@ static Oid objectid; %token CONST ID %token OPEN XCLOSE XCREATE INSERT_TUPLE %token STRING XDEFINE -%token XDECLARE INDEX ON USING XBUILD INDICES +%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE %token COMMA EQUALS LPAREN RPAREN %token OBJ_ID XBOOTSTRAP NULLVAL %start TopLevel @@ -106,6 +106,7 @@ Boot_Query : | Boot_CreateStmt | Boot_InsertStmt | Boot_DeclareIndexStmt + | Boot_DeclareUniqueIndexStmt | Boot_BuildIndsStmt ; @@ -164,7 +165,7 @@ Boot_CreateStmt: puts("creating bootstrap relation"); tupdesc = CreateTupleDesc(numattr,attrtypes); reldesc = heap_create(LexIDStr($3), tupdesc, - false, false); + false, false, true); if (DebugMode) puts("bootstrap relation created ok"); } @@ -230,6 +231,19 @@ Boot_DeclareIndexStmt: } ; +Boot_DeclareUniqueIndexStmt: + XDECLARE UNIQUE INDEX boot_ident ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN + { + DO_START; + + DefineIndex(LexIDStr($6), + LexIDStr($4), + LexIDStr($8), + $10, NIL, 1, 0, 0, NIL); + DO_END; + } + ; + Boot_BuildIndsStmt: XBUILD INDICES { build_indices(); } diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l index a7254994ec..0c1e0fb7d8 100644 --- a/src/backend/bootstrap/bootscanner.l +++ b/src/backend/bootstrap/bootscanner.l @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.15 1999/09/11 22:26:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.16 1999/11/04 08:00:58 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -90,6 +90,7 @@ insert { return(INSERT_TUPLE); } "declare" { return(XDECLARE); } "build" { return(XBUILD); } "indices" { return(INDICES); } +"unique" { return(UNIQUE); } "index" { return(INDEX); } "on" { return(ON); } "using" { return(USING); } diff --git a/src/backend/catalog/genbki.sh.in b/src/backend/catalog/genbki.sh.in index d7b925f27e..9b6bf27f48 100644 --- a/src/backend/catalog/genbki.sh.in +++ b/src/backend/catalog/genbki.sh.in @@ -10,7 +10,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh.in,v 1.3 1999/06/04 21:12:06 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh.in,v 1.4 1999/11/04 08:00:56 inoue Exp $ # # NOTES # non-essential whitespace is removed from the generated file. @@ -164,6 +164,20 @@ raw == 1 { print; next; } print "declare index " data } +/^DECLARE_UNIQUE_INDEX\(/ { +# ---- +# end any prior catalog data insertions before starting a define unique index +# ---- + if (reln_open == 1) { +# print "show"; + print "close " catalog; + reln_open = 0; + } + + data = substr($0, 22, length($0) - 22); + print "declare unique index " data +} + /^BUILD_INDICES/ { print "build indices"; } # ---------------- diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index eb934f6d3d..52cd68b82a 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.105 1999/10/26 03:12:33 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.106 1999/11/04 08:00:56 inoue Exp $ * * * INTERFACE ROUTINES @@ -176,7 +176,8 @@ Relation heap_create(char *relname, TupleDesc tupDesc, bool isnoname, - bool istemp) + bool istemp, + bool storage_create) { unsigned i; Oid relid; @@ -264,7 +265,8 @@ heap_create(char *relname, rel = (Relation) palloc(len); MemSet((char *) rel, 0, len); - + rel->rd_fd = -1; /* table is not open */ + rel->rd_unlinked = TRUE; /* table is not created yet */ /* * create a new tuple descriptor from the one passed in */ @@ -316,9 +318,9 @@ heap_create(char *relname, * ---------------- */ - rel->rd_nonameunlinked = TRUE; /* change once table is created */ - rel->rd_fd = (File) smgrcreate(DEFAULT_SMGR, rel); - rel->rd_nonameunlinked = FALSE; + /* smgrcreate() is moved to heap_storage_create() */ + if (storage_create) + heap_storage_create(rel); RelationRegisterRelation(rel); @@ -334,6 +336,19 @@ heap_create(char *relname, return rel; } +bool +heap_storage_create(Relation rel) +{ + bool smgrcall = false; + + if (rel->rd_unlinked) + { + rel->rd_fd = (File) smgrcreate(DEFAULT_SMGR, rel); + rel->rd_unlinked = FALSE; + smgrcall = true; + } + return smgrcall; +} /* ---------------------------------------------------------------- * heap_create_with_catalog - Create a cataloged relation @@ -795,16 +810,26 @@ heap_create_with_catalog(char *relname, } /* ---------------- - * ok, relation does not already exist so now we - * create an uncataloged relation and pull its relation oid - * from the newly formed relation descriptor. + * get_temp_rel_by_name() couldn't check the simultaneous + * creation. Uniqueness will be really checked by unique + * indexes of system tables but we couldn't check it here. + * We have to pospone to create the disk file for this + * relation. + * Another boolean parameter "storage_create" was added + * to heap_create() function. If the parameter is false + * heap_create() only registers an uncataloged relation + * to relation cache and heap_storage_create() should be + * called later. + * We could pull its relation oid from the newly formed + * relation descriptor. * - * Note: The call to heap_create() does all the "real" work - * of creating the disk file for the relation. - * This changes relname for noname and temp tables. + * Note: The call to heap_create() changes relname for + * noname and temp tables. + * The call to heap_storage_create() does all the "real" + * work of creating the disk file for the relation. * ---------------- */ - new_rel_desc = heap_create(relname, tupdesc, false, istemp); + new_rel_desc = heap_create(relname, tupdesc, false, istemp, false); new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid; @@ -843,6 +868,10 @@ heap_create_with_catalog(char *relname, pfree(temp_relname); } + /* + * We create the disk file for this relation here + */ + heap_storage_create(new_rel_desc); /* ---------------- * ok, the relation has been cataloged, so close our relations * and return the oid of the newly created relation. @@ -1519,10 +1548,10 @@ heap_destroy_with_catalog(char *relname) * unlink the relation's physical file and finish up. * ---------------- */ - if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked)) + if (!(rel->rd_isnoname) || !(rel->rd_unlinked)) smgrunlink(DEFAULT_SMGR, rel); - rel->rd_nonameunlinked = TRUE; + rel->rd_unlinked = TRUE; /* * Close relcache entry, but *keep* AccessExclusiveLock on the @@ -1548,9 +1577,9 @@ void heap_destroy(Relation rel) { ReleaseRelationBuffers(rel); - if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked)) + if (!(rel->rd_isnoname) || !(rel->rd_unlinked)) smgrunlink(DEFAULT_SMGR, rel); - rel->rd_nonameunlinked = TRUE; + rel->rd_unlinked = TRUE; heap_close(rel, NoLock); RemoveFromNoNameRelList(rel); } diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index a8c2adf7cb..65d297a250 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.93 1999/11/01 02:29:24 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.94 1999/11/04 08:00:56 inoue Exp $ * * * INTERFACE ROUTINES @@ -997,7 +997,7 @@ index_create(char *heapRelationName, * ---------------- */ indexRelation = heap_create(indexRelationName, - indexTupDesc, false, istemp); + indexTupDesc, false, istemp, false); /* ---------------- * construct the index relation descriptor @@ -1014,6 +1014,10 @@ index_create(char *heapRelationName, */ indexoid = UpdateRelationRelation(indexRelation, temp_relname); + /* + * We create the disk file for this relation here + */ + heap_storage_create(indexRelation); /* ---------------- * Now get the index procedure (only relevant for functional indices). * ---------------- diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 9c1b7b8bb4..dc69953e21 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: execAmi.c,v 1.42 1999/09/18 19:06:47 tgl Exp $ + * $Id: execAmi.c,v 1.43 1999/11/04 08:00:57 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -503,7 +503,7 @@ ExecCreatR(TupleDesc tupType, * heap_create creates a name if the argument to heap_create is * '\0 ' */ - relDesc = heap_create(NULL, tupType, true, false); + relDesc = heap_create(NULL, tupType, true, false, true); } else { diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index c76f533511..ae9a784866 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.57 1999/10/25 03:07:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.58 1999/11/04 08:01:00 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -120,6 +120,7 @@ mdcreate(Relation reln) vfd; char *path; + Assert(reln->rd_unlinked && reln->rd_fd < 0); path = relpath(reln->rd_rel->relname.data); #ifndef __CYGWIN32__ fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL, 0600); @@ -128,28 +129,49 @@ mdcreate(Relation reln) #endif /* - * If the file already exists and is empty, we pretend that the create - * succeeded. During bootstrap processing, we skip that check, - * because pg_time, pg_variable, and pg_log get created before their - * .bki file entries are processed. + * During bootstrap processing, we skip that check, because pg_time, + * pg_variable, and pg_log get created before their .bki file entries + * are processed. * - * As the result of this pretence it was possible to have in pg_class > 1 - * records with the same relname. Actually, it should be fixed in - * upper levels, too, but... - vadim 05/06/97 + * For cataloged relations,pg_class is guaranteed to have an unique + * record with the same relname by the unique index. + * So we are able to reuse existent files for new catloged relations. + * Currently we reuse them in the following cases. + * 1. they are empty. + * 2. they are used for Index relations and their size == BLCKSZ * 2. */ if (fd < 0) { - if (!IsBootstrapProcessingMode()) + if (!IsBootstrapProcessingMode() && + reln->rd_rel->relkind == RELKIND_UNCATALOGED) return -1; + #ifndef __CYGWIN32__ - fd = FileNameOpenFile(path, O_RDWR, 0600); /* Bootstrap */ + fd = FileNameOpenFile(path, O_RDWR, 0600); #else - fd = FileNameOpenFile(path, O_RDWR | O_BINARY, 0600); /* Bootstrap */ + fd = FileNameOpenFile(path, O_RDWR | O_BINARY, 0600); #endif if (fd < 0) return -1; + if (!IsBootstrapProcessingMode()) + { + bool reuse = false; + int len = FileSeek(fd, 0L, SEEK_END); + + if (len == 0) + reuse = true; + else if (reln->rd_rel->relkind == RELKIND_INDEX && + len == BLCKSZ * 2) + reuse = true; + if (!reuse) + { + FileClose(fd); + return -1; + } + } } + reln->rd_unlinked = false; vfd = _fdvec_alloc(); if (vfd < 0) @@ -176,6 +198,11 @@ mdunlink(Relation reln) MdfdVec *v; MemoryContext oldcxt; + /* If the relation is already unlinked,we have nothing to do + * any more. + */ + if (reln->rd_unlinked && reln->rd_fd < 0) + return SM_SUCCESS; /* * Force all segments of the relation to be opened, so that we * won't miss deleting any of them. @@ -218,8 +245,9 @@ mdunlink(Relation reln) _fdvec_free(fd); - /* be sure to mark relation closed */ + /* be sure to mark relation closed && unlinked */ reln->rd_fd = -1; + reln->rd_unlinked = true; return SM_SUCCESS; } @@ -290,6 +318,7 @@ mdopen(Relation reln) int fd; int vfd; + Assert(reln->rd_fd < 0); path = relpath(reln->rd_rel->relname.data); #ifndef __CYGWIN32__ @@ -311,10 +340,14 @@ mdopen(Relation reln) } if (fd < 0) { - elog(ERROR, "mdopen: couldn't open %s: %m", path); + elog(NOTICE, "mdopen: couldn't open %s: %m", path); + /* mark relation closed and unlinked */ + reln->rd_fd = -1; + reln->rd_unlinked = true; return -1; } } + reln->rd_unlinked = false; vfd = _fdvec_alloc(); if (vfd < 0) diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index a1c86a60d3..6ec382e48a 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.29 1999/09/02 02:57:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.30 1999/11/04 08:01:01 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -182,7 +182,8 @@ smgropen(int16 which, Relation reln) { int fd; - if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0) + if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0 && + !reln->rd_unlinked) elog(ERROR, "cannot open %s", reln->rd_rel->relname.data); return fd; diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index fab04036d2..0090c82614 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.74 1999/10/03 23:55:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.75 1999/11/04 08:00:59 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -1065,7 +1065,7 @@ RelationIdCacheGetRelation(Oid relationId) if (rd->rd_fd == -1) { rd->rd_fd = smgropen(DEFAULT_SMGR, rd); - Assert(rd->rd_fd != -1); + Assert(rd->rd_fd != -1 || rd->rd_unlinked); } RelationIncrementReferenceCount(rd); @@ -1099,7 +1099,7 @@ RelationNameCacheGetRelation(char *relationName) if (rd->rd_fd == -1) { rd->rd_fd = smgropen(DEFAULT_SMGR, rd); - Assert(rd->rd_fd != -1); + Assert(rd->rd_fd != -1 || rd->rd_unlinked); } RelationIncrementReferenceCount(rd); @@ -1613,10 +1613,10 @@ RelationPurgeLocalRelation(bool xactCommitted) */ if (reln->rd_isnoname) { - if (!(reln->rd_nonameunlinked)) + if (!(reln->rd_unlinked)) { smgrunlink(DEFAULT_SMGR, reln); - reln->rd_nonameunlinked = TRUE; + reln->rd_unlinked = TRUE; } } else diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 6175662908..7ac22873d1 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -36,7 +36,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.1 1999/10/24 20:42:26 tgl Exp $ + * $Id: catversion.h,v 1.2 1999/11/04 08:01:06 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -51,6 +51,6 @@ * catalog changes on the same day...) */ -#define CATALOG_VERSION_NO 199910241 +#define CATALOG_VERSION_NO 199911041 #endif diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 1cb86b501c..9d311038cb 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: heap.h,v 1.24 1999/10/26 03:12:37 momjian Exp $ + * $Id: heap.h,v 1.25 1999/11/04 08:01:04 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -23,7 +23,8 @@ typedef struct RawColumnDefault extern Oid RelnameFindRelid(char *relname); extern Relation heap_create(char *relname, TupleDesc att, - bool isnoname, bool istemp); + bool isnoname, bool istemp, bool storage_create); +extern bool heap_storage_create(Relation rel); extern Oid heap_create_with_catalog(char *relname, TupleDesc tupdesc, char relkind, bool istemp); diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index e39ce1c62d..5d3d34e876 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -7,7 +7,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: indexing.h,v 1.27 1999/11/01 04:00:57 momjian Exp $ + * $Id: indexing.h,v 1.28 1999/11/04 08:01:06 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -119,11 +119,11 @@ DECLARE_INDEX(pg_index_indexrelid_index on pg_index using btree(indexrelid oid_o DECLARE_INDEX(pg_proc_oid_index on pg_proc using btree(oid oid_ops)); DECLARE_INDEX(pg_proc_proname_narg_type_index on pg_proc using btree(proname name_ops, pronargs int2_ops, proargtypes oid8_ops)); -DECLARE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_ops)); -DECLARE_INDEX(pg_type_typname_index on pg_type using btree(typname name_ops)); +DECLARE_UNIQUE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_type_typname_index on pg_type using btree(typname name_ops)); -DECLARE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops)); -DECLARE_INDEX(pg_class_relname_index on pg_class using btree(relname name_ops)); +DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_class_relname_index on pg_class using btree(relname name_ops)); DECLARE_INDEX(pg_attrdef_adrelid_index on pg_attrdef using btree(adrelid oid_ops)); diff --git a/src/include/postgres.h b/src/include/postgres.h index ddc8400733..0beb504d38 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -6,7 +6,7 @@ * * Copyright (c) 1995, Regents of the University of California * - * $Id: postgres.h,v 1.28 1999/10/25 03:07:55 tgl Exp $ + * $Id: postgres.h,v 1.29 1999/11/04 08:01:07 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -138,6 +138,7 @@ typedef uint32 CommandId; #define DATA(x) extern int errno #define DESCR(x) extern int errno #define DECLARE_INDEX(x) extern int errno +#define DECLARE_UNIQUE_INDEX(x) extern int errno #define BUILD_INDICES #define BOOTSTRAP diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 308f9a6d64..28ea74c5e2 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: rel.h,v 1.27 1999/09/29 16:06:28 wieck Exp $ + * $Id: rel.h,v 1.28 1999/11/04 08:01:09 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -78,7 +78,7 @@ typedef struct RelationData bool rd_myxactonly; /* rel uses the local buffer mgr */ bool rd_isnailed; /* rel is nailed in cache */ bool rd_isnoname; /* rel has no name */ - bool rd_nonameunlinked; /* noname rel already unlinked */ + bool rd_unlinked; /* rel already unlinked or not created yet */ Form_pg_am rd_am; /* AM tuple */ Form_pg_class rd_rel; /* RELATION tuple */ Oid rd_id; /* relation's object id */