Make it possible to execute crashed CREATE/DROP commands again.

Now indexes of pg_class and pg_type are unique indexes
and guarantee the uniqueness of correponding attributes.
heap_create() was changed to take another boolean parameter
which allows to postpone the creation of disk file.
The name of rd_nonameunlinked was changed to rd_unlinked.
It is used generally(not only for noname relations) now.
Requires initdb.
This commit is contained in:
Hiroshi Inoue 1999-11-04 08:01:09 +00:00
parent a2c834f709
commit 2e2189a568
14 changed files with 156 additions and 58 deletions

View File

@ -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 <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
@ -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(); }

View File

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

View File

@ -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"; }
# ----------------

View File

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

View File

@ -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).
* ----------------

View File

@ -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
{

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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));

View File

@ -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

View File

@ -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 */