*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
%token <ival> 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
| Boot_CreateStmt
| Boot_InsertStmt
| Boot_DeclareIndexStmt
+ | Boot_DeclareUniqueIndexStmt
| Boot_BuildIndsStmt
;
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");
}
}
;
+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(); }
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
"declare" { return(XDECLARE); }
"build" { return(XBUILD); }
"indices" { return(INDICES); }
+"unique" { return(UNIQUE); }
"index" { return(INDEX); }
"on" { return(ON); }
"using" { return(USING); }
#
#
# 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.
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"; }
# ----------------
*
*
* 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
heap_create(char *relname,
TupleDesc tupDesc,
bool isnoname,
- bool istemp)
+ bool istemp,
+ bool storage_create)
{
unsigned i;
Oid relid;
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
*/
* ----------------
*/
- 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);
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
}
/* ----------------
- * 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;
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.
* 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
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);
}
*
*
* 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
* ----------------
*/
indexRelation = heap_create(indexRelationName,
- indexTupDesc, false, istemp);
+ indexTupDesc, false, istemp, false);
/* ----------------
* construct the index relation descriptor
*/
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).
* ----------------
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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
{
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
#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)
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.
_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;
}
int fd;
int vfd;
+ Assert(reln->rd_fd < 0);
path = relpath(reln->rd_rel->relname.data);
#ifndef __CYGWIN32__
}
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)
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
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);
*/
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
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* catalog changes on the same day...)
*/
-#define CATALOG_VERSION_NO 199910241
+#define CATALOG_VERSION_NO 199911041
#endif
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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));
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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 */