Clean up various to-do items associated with system indexes:

pg_database now has unique indexes on oid and on datname.
pg_shadow now has unique indexes on usename and on usesysid.
pg_am now has unique index on oid.
pg_opclass now has unique index on oid.
pg_amproc now has unique index on amid+amopclaid+amprocnum.
Remove pg_rewrite's unnecessary index on oid, delete unused RULEOID syscache.
Remove index on pg_listener and associated syscache for performance reasons
(caching rows that are certain to change before you need 'em again is
rather pointless).
Change pg_attrdef's nonunique index on adrelid into a unique index on
adrelid+adnum.

Fix various incorrect settings of pg_class.relisshared, make that the
primary reference point for whether a relation is shared or not.
IsSharedSystemRelationName() is now only consulted to initialize relisshared
during initial creation of tables and indexes.  In theory we might now
support shared user relations, though it's not clear how one would get
entries for them into pg_class &etc of multiple databases.

Fix recently reported bug that pg_attribute rows created for an index all have
the same OID.  (Proof that non-unique OID doesn't matter unless it's
actually used to do lookups ;-))

There's no need to treat pg_trigger, pg_attrdef, pg_relcheck as bootstrap
relations.  Convert them into plain system catalogs without hardwired
entries in pg_class and friends.

Unify global.bki and template1.bki into a single init script postgres.bki,
since the alleged distinction between them was misleading and pointless.
Not to mention that it didn't work for setting up indexes on shared
system relations.

Rationalize locking of pg_shadow, pg_group, pg_attrdef (no need to use
AccessExclusiveLock where ExclusiveLock or even RowExclusiveLock will do).
Also, hold locks until transaction commit where necessary.
This commit is contained in:
Tom Lane 2001-06-12 05:55:50 +00:00
parent d2c8358188
commit 1d584f97b9
30 changed files with 471 additions and 647 deletions

View File

@ -1,4 +1,6 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/bki.sgml,v 1.6 2000/12/23 16:24:29 petere Exp $ --> <!--
$Header: /cvsroot/pgsql/doc/src/sgml/bki.sgml,v 1.7 2001/06/12 05:55:48 tgl Exp $
-->
<chapter id="bki"> <chapter id="bki">
<title><acronym>BKI</acronym> Backend Interface</title> <title><acronym>BKI</acronym> Backend Interface</title>
@ -15,16 +17,14 @@
</para> </para>
<para> <para>
<application>initdb</application> uses <acronym>BKI</acronym> files <application>initdb</application> uses a <acronym>BKI</acronym> file
to do part of its job when creating a new database cluster. The to do part of its job when creating a new database cluster. The
input files used by <application>initbd</application> are created as input file used by <application>initdb</application> is created as
part of building and installing <productname>Postgres</productname> part of building and installing <productname>Postgres</productname>
by a program named <filename>genbki.sh</filename> from some by a program named <filename>genbki.sh</filename> from some
specially formatted C header files in the source tree. The created specially formatted C header files in the source tree. The created
BKI files are called <filename>global.bki</filename> (for global BKI file is called <filename>postgres.bki</filename> and is
catalogs) and <filename>template1.bki</filename> (for the catalogs normally installed in the
initially stored in the template1 database and then duplicated in
every created database) and are normally installed in the
<filename>share</filename> subdirectory of the installation tree. <filename>share</filename> subdirectory of the installation tree.
</para> </para>
@ -39,7 +39,7 @@
<para> <para>
This section describes how the <productname>Postgres</productname> This section describes how the <productname>Postgres</productname>
backend interprets <acronym>BKI</acronym> files. This description backend interprets <acronym>BKI</acronym> files. This description
will be easier to understand if the <filename>global.bki</filename> will be easier to understand if the <filename>postgres.bki</filename>
file is at hand as an example. You should also study the source file is at hand as an example. You should also study the source
code of <application>initdb</application> to get an idea of how the code of <application>initdb</application> to get an idea of how the
backend is invoked. backend is invoked.
@ -49,7 +49,7 @@
BKI input consists of a sequence of commands. Commands are made up BKI input consists of a sequence of commands. Commands are made up
of a number of tokens, depending on the syntax of the command. of a number of tokens, depending on the syntax of the command.
Tokens are usually separated by whitespace, but need not be if Tokens are usually separated by whitespace, but need not be if
there is no ambiguity. There is not special command separator; the there is no ambiguity. There is no special command separator; the
next token that syntactically cannot belong to the preceeding next token that syntactically cannot belong to the preceeding
command starts a new one. (Usually you would put a new command on command starts a new one. (Usually you would put a new command on
a new line, for clarity.) Tokens can be certain key words, special a new line, for clarity.) Tokens can be certain key words, special
@ -155,13 +155,13 @@
values and <replaceable values and <replaceable
class="parameter">oid_value</replaceable> for its OID. If class="parameter">oid_value</replaceable> for its OID. If
<replaceable class="parameter">oid_value</replaceable> is zero <replaceable class="parameter">oid_value</replaceable> is zero
(0) or the clause is ommitted, then the next available OID is (0) or the clause is omitted, then the next available OID is
used. used.
</para> </para>
<para> <para>
NULL values can be specified using the special key word NULL values can be specified using the special key word
<literal>_null_</literal>. Values containing spaces should be <literal>_null_</literal>. Values containing spaces must be
double quoted. double quoted.
</para> </para>
</listitem> </listitem>

View File

@ -1,6 +1,6 @@
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.17 2001/05/14 20:30:19 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.18 2001/06/12 05:55:48 tgl Exp $
--> -->
<chapter id="catalogs"> <chapter id="catalogs">
@ -645,7 +645,8 @@
<entry>relisshared</entry> <entry>relisshared</entry>
<entry><type>bool</type></entry> <entry><type>bool</type></entry>
<entry></entry> <entry></entry>
<entry>XXX (This is not what it seems to be.)</entry> <entry>True if this table is shared across all databases in the
cluster.</entry>
</row> </row>
<row> <row>

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.71 2001/03/22 06:16:06 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.72 2001/06/12 05:55:49 tgl Exp $
* *
* NOTES * NOTES
* The old interface functions have been converted to macros * The old interface functions have been converted to macros
@ -738,44 +738,46 @@ heap_freetuple(HeapTuple htup)
} }
/* ---------------------------------------------------------------- /* ----------------
* other misc functions * heap_addheader
* ---------------------------------------------------------------- *
* This routine forms a HeapTuple by copying the given structure (tuple
* data) and adding a generic header. Note that the tuple data is
* presumed to contain no null fields. It is typically only useful
* for null-free system tables.
* ----------------
*/ */
HeapTuple HeapTuple
heap_addheader(uint32 natts, /* max domain index */ heap_addheader(int natts, /* max domain index */
int structlen, /* its length */ Size structlen, /* its length */
char *structure) /* pointer to the struct */ void *structure) /* pointer to the struct */
{ {
HeapTuple tuple; HeapTuple tuple;
HeapTupleHeader td; /* tuple data */ HeapTupleHeader td;
unsigned long len; Size len;
int hoff; int hoff;
AssertArg(natts > 0); AssertArg(natts > 0);
len = offsetof(HeapTupleHeaderData, t_bits); /* header needs no null bitmap */
hoff = MAXALIGN(offsetof(HeapTupleHeaderData, t_bits));
len = hoff + structlen;
hoff = len = MAXALIGN(len); /* be conservative */
len += structlen;
tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len); tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len);
tuple->t_datamcxt = CurrentMemoryContext;
td = tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
tuple->t_len = len; tuple->t_len = len;
ItemPointerSetInvalid(&(tuple->t_self)); ItemPointerSetInvalid(&(tuple->t_self));
tuple->t_tableOid = InvalidOid; tuple->t_tableOid = InvalidOid;
tuple->t_datamcxt = CurrentMemoryContext;
tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
MemSet((char *) td, 0, len); MemSet((char *) td, 0, len);
td->t_hoff = hoff; td->t_hoff = hoff;
td->t_natts = natts; td->t_natts = natts;
td->t_infomask = 0; td->t_infomask = HEAP_XMAX_INVALID; /* XXX sufficient? */
td->t_infomask |= HEAP_XMAX_INVALID;
if (structlen > 0) memcpy((char *) td + hoff, structure, structlen);
memcpy((char *) td + hoff, structure, (size_t) structlen);
return tuple; return tuple;
} }

View File

@ -2,7 +2,7 @@
# #
# Makefile for catalog # Makefile for catalog
# #
# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.34 2001/05/14 21:58:10 momjian Exp $ # $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.35 2001/06/12 05:55:49 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -14,42 +14,36 @@ OBJS = catalog.o heap.o index.o indexing.o aclchk.o \
pg_aggregate.o pg_largeobject.o pg_operator.o pg_proc.o \ pg_aggregate.o pg_largeobject.o pg_operator.o pg_proc.o \
pg_type.o pg_type.o
BKIFILES = global.bki template1.bki global.description template1.description BKIFILES = postgres.bki postgres.description
all: SUBSYS.o $(BKIFILES) all: SUBSYS.o $(BKIFILES)
SUBSYS.o: $(OBJS) SUBSYS.o: $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS) $(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
# Note: there are some undocumented dependencies on the ordering in which
# the catalog header files are assembled into postgres.bki. In particular,
# indexing.h had better be last.
GLOBAL_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_database.h pg_shadow.h pg_group.h pg_log.h \
)
TEMPLATE1_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_proc.h pg_type.h pg_attribute.h pg_class.h \ pg_proc.h pg_type.h pg_attribute.h pg_class.h \
pg_inherits.h pg_index.h pg_statistic.h \ pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h \ pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_listener.h pg_description.h indexing.h \ pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h \
pg_database.h pg_shadow.h pg_group.h pg_log.h indexing.h \
) )
pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include) pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
global.bki global.description: genbki.sh $(GLOBAL_BKI_SRCS) $(top_srcdir)/src/include/catalog/indexing.h \ postgres.bki postgres.description: genbki.sh $(POSTGRES_BKI_SRCS) \
$(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/config.h $(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/config.h
CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o global $(pg_includes) $(GLOBAL_BKI_SRCS) --set-version=$(VERSION) CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o postgres $(pg_includes) $(POSTGRES_BKI_SRCS) --set-version=$(VERSION)
template1.bki template1.description: genbki.sh $(TEMPLATE1_BKI_SRCS) \
$(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/config.h
CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o template1 $(pg_includes) $(TEMPLATE1_BKI_SRCS) --set-version=$(VERSION)
.PHONY: install-bki .PHONY: install-bki
install-bki: $(BKIFILES) installdirs install-bki: $(BKIFILES) installdirs
$(INSTALL_DATA) global.bki $(DESTDIR)$(datadir)/global.bki $(INSTALL_DATA) postgres.bki $(DESTDIR)$(datadir)/postgres.bki
$(INSTALL_DATA) global.description $(DESTDIR)$(datadir)/global.description $(INSTALL_DATA) postgres.description $(DESTDIR)$(datadir)/postgres.description
$(INSTALL_DATA) template1.bki $(DESTDIR)$(datadir)/template1.bki
$(INSTALL_DATA) template1.description $(DESTDIR)$(datadir)/template1.description
installdirs: installdirs:
$(mkinstalldirs) $(DESTDIR)$(datadir) $(mkinstalldirs) $(DESTDIR)$(datadir)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.166 2001/05/30 12:57:36 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.167 2001/06/12 05:55:49 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -218,8 +218,9 @@ heap_create(char *relname,
} }
/* /*
* real ugly stuff to assign the proper relid in the relation * Real ugly stuff to assign the proper relid in the relation
* descriptor follows. * descriptor follows. Note that only "bootstrapped" relations
* whose OIDs are hard-coded in pg_class.h need be listed here.
*/ */
if (relname && IsSystemRelationName(relname)) if (relname && IsSystemRelationName(relname))
{ {
@ -263,12 +264,6 @@ heap_create(char *relname,
tblNode = InvalidOid; tblNode = InvalidOid;
relid = RelOid_pg_log; relid = RelOid_pg_log;
} }
else if (strcmp(AttrDefaultRelationName, relname) == 0)
relid = RelOid_pg_attrdef;
else if (strcmp(RelCheckRelationName, relname) == 0)
relid = RelOid_pg_relcheck;
else if (strcmp(TriggerRelationName, relname) == 0)
relid = RelOid_pg_trigger;
else else
{ {
relid = newoid(); relid = newoid();
@ -566,7 +561,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
tup = heap_addheader(Natts_pg_attribute, tup = heap_addheader(Natts_pg_attribute,
ATTRIBUTE_TUPLE_SIZE, ATTRIBUTE_TUPLE_SIZE,
(char *) *dpp); (void *) *dpp);
heap_insert(rel, tup); heap_insert(rel, tup);
@ -583,16 +578,18 @@ AddNewAttributeTuples(Oid new_rel_oid,
dpp = SysAtt; dpp = SysAtt;
for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++) for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
{ {
/* Fill in the correct relation OID */ Form_pg_attribute attStruct;
/* HACK: we are writing on static data here */
(*dpp)->attrelid = new_rel_oid;
/* Unneeded since they should be OK in the constant data anyway */
/* (*dpp)->attstattarget = 0; */
/* (*dpp)->attcacheoff = -1; */
tup = heap_addheader(Natts_pg_attribute, tup = heap_addheader(Natts_pg_attribute,
ATTRIBUTE_TUPLE_SIZE, ATTRIBUTE_TUPLE_SIZE,
(char *) *dpp); (void *) *dpp);
/* Fill in the correct relation OID in the copied tuple */
attStruct = (Form_pg_attribute) GETSTRUCT(tup);
attStruct->attrelid = new_rel_oid;
/* Unneeded since they should be OK in the constant data anyway */
/* attStruct->attstattarget = 0; */
/* attStruct->attcacheoff = -1; */
heap_insert(rel, tup); heap_insert(rel, tup);
@ -603,13 +600,13 @@ AddNewAttributeTuples(Oid new_rel_oid,
dpp++; dpp++;
} }
heap_close(rel, RowExclusiveLock);
/* /*
* close pg_attribute indices * close pg_attribute indices
*/ */
if (hasindex) if (hasindex)
CatalogCloseIndices(Num_pg_attr_indices, idescs); CatalogCloseIndices(Num_pg_attr_indices, idescs);
heap_close(rel, RowExclusiveLock);
} }
/* -------------------------------- /* --------------------------------
@ -686,7 +683,7 @@ AddNewRelationTuple(Relation pg_class_desc,
*/ */
tup = heap_addheader(Natts_pg_class_fixed, tup = heap_addheader(Natts_pg_class_fixed,
CLASS_TUPLE_SIZE, CLASS_TUPLE_SIZE,
(char *) new_rel_reltup); (void *) new_rel_reltup);
/* force tuple to have the desired OID */ /* force tuple to have the desired OID */
tup->t_data->t_oid = new_rel_oid; tup->t_data->t_oid = new_rel_oid;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.153 2001/06/01 02:41:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.154 2001/06/12 05:55:49 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -343,17 +343,19 @@ AccessMethodObjectIdGetForm(Oid accessMethodObjectId,
static void static void
ConstructIndexReldesc(Relation indexRelation, Oid amoid) ConstructIndexReldesc(Relation indexRelation, Oid amoid)
{ {
indexRelation->rd_am = AccessMethodObjectIdGetForm(amoid,
CacheMemoryContext);
/* /*
* XXX missing the initialization of some other fields * Fill in a copy of relevant pg_am entry
*/
indexRelation->rd_am = AccessMethodObjectIdGetForm(amoid,
CacheMemoryContext);
/*
* Set up some additional fields of the index' pg_class entry.
* In particular, initialize knowledge of whether the index is shared.
*/ */
indexRelation->rd_rel->relowner = GetUserId(); indexRelation->rd_rel->relowner = GetUserId();
indexRelation->rd_rel->relam = amoid; indexRelation->rd_rel->relam = amoid;
indexRelation->rd_rel->reltuples = 1; /* XXX */ indexRelation->rd_rel->relisshared =
IsSharedSystemRelationName(RelationGetPhysicalRelationName(indexRelation));
indexRelation->rd_rel->relkind = RELKIND_INDEX; indexRelation->rd_rel->relkind = RELKIND_INDEX;
} }
@ -374,7 +376,7 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname)
/* XXX Natts_pg_class_fixed is a hack - see pg_class.h */ /* XXX Natts_pg_class_fixed is a hack - see pg_class.h */
tuple = heap_addheader(Natts_pg_class_fixed, tuple = heap_addheader(Natts_pg_class_fixed,
CLASS_TUPLE_SIZE, CLASS_TUPLE_SIZE,
(char *) indexRelation->rd_rel); (void *) indexRelation->rd_rel);
/* /*
* the new tuple must have the same oid as the relcache entry for the * the new tuple must have the same oid as the relcache entry for the
@ -428,23 +430,16 @@ InitializeAttributeOids(Relation indexRelation,
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* AppendAttributeTuples * AppendAttributeTuples
*
* XXX For now, only change the ATTNUM attribute value
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
static void static void
AppendAttributeTuples(Relation indexRelation, int numatts) AppendAttributeTuples(Relation indexRelation, int numatts)
{ {
Relation pg_attribute; Relation pg_attribute;
HeapTuple init_tuple,
cur_tuple = NULL,
new_tuple;
bool hasind; bool hasind;
Relation idescs[Num_pg_attr_indices]; Relation idescs[Num_pg_attr_indices];
Datum value[Natts_pg_attribute];
char nullv[Natts_pg_attribute];
char replace[Natts_pg_attribute];
TupleDesc indexTupDesc; TupleDesc indexTupDesc;
HeapTuple new_tuple;
int i; int i;
/* /*
@ -452,27 +447,6 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
*/ */
pg_attribute = heap_openr(AttributeRelationName, RowExclusiveLock); pg_attribute = heap_openr(AttributeRelationName, RowExclusiveLock);
/*
* initialize *null, *replace and *value
*/
MemSet(nullv, ' ', Natts_pg_attribute);
MemSet(replace, ' ', Natts_pg_attribute);
/* ----------
* create the first attribute tuple.
* XXX For now, only change the ATTNUM attribute value
* ----------
*/
replace[Anum_pg_attribute_attnum - 1] = 'r';
replace[Anum_pg_attribute_attcacheoff - 1] = 'r';
value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(1);
value[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1);
init_tuple = heap_addheader(Natts_pg_attribute,
ATTRIBUTE_TUPLE_SIZE,
(char *) (indexRelation->rd_att->attrs[0]));
hasind = false; hasind = false;
if (!IsIgnoringSystemIndexes() && pg_attribute->rd_rel->relhasindex) if (!IsIgnoringSystemIndexes() && pg_attribute->rd_rel->relhasindex)
{ {
@ -481,60 +455,35 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
} }
/* /*
* insert the first attribute tuple. * insert data from new index's tupdesc into pg_attribute
*/
cur_tuple = heap_modifytuple(init_tuple,
pg_attribute,
value,
nullv,
replace);
heap_freetuple(init_tuple);
heap_insert(pg_attribute, cur_tuple);
if (hasind)
CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, cur_tuple);
/*
* now we use the information in the index cur_tuple descriptor to
* form the remaining attribute tuples.
*/ */
indexTupDesc = RelationGetDescr(indexRelation); indexTupDesc = RelationGetDescr(indexRelation);
for (i = 1; i < numatts; i += 1) for (i = 0; i < numatts; i++)
{ {
/* /*
* process the remaining attributes... * There used to be very grotty code here to set these fields,
* but I think it's unnecessary. They should be set already.
*/ */
memmove(GETSTRUCT(cur_tuple), Assert(indexTupDesc->attrs[i]->attnum == i+1);
(char *) indexTupDesc->attrs[i], Assert(indexTupDesc->attrs[i]->attcacheoff == -1);
ATTRIBUTE_TUPLE_SIZE);
value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(i + 1); new_tuple = heap_addheader(Natts_pg_attribute,
ATTRIBUTE_TUPLE_SIZE,
new_tuple = heap_modifytuple(cur_tuple, (void *) indexTupDesc->attrs[i]);
pg_attribute,
value,
nullv,
replace);
heap_freetuple(cur_tuple);
heap_insert(pg_attribute, new_tuple); heap_insert(pg_attribute, new_tuple);
if (hasind) if (hasind)
CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, new_tuple); CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, new_tuple);
/* heap_freetuple(new_tuple);
* ModifyHeapTuple returns a new copy of a cur_tuple so we free
* the original and use the copy..
*/
cur_tuple = new_tuple;
} }
if (cur_tuple)
heap_freetuple(cur_tuple);
heap_close(pg_attribute, RowExclusiveLock);
if (hasind) if (hasind)
CatalogCloseIndices(Num_pg_attr_indices, idescs); CatalogCloseIndices(Num_pg_attr_indices, idescs);
heap_close(pg_attribute, RowExclusiveLock);
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
@ -613,7 +562,7 @@ UpdateIndexRelation(Oid indexoid,
*/ */
tuple = heap_addheader(Natts_pg_index, tuple = heap_addheader(Natts_pg_index,
itupLen, itupLen,
(char *) indexForm); (void *) indexForm);
/* /*
* insert the tuple into the pg_index * insert the tuple into the pg_index
@ -1994,7 +1943,7 @@ reindex_index(Oid indexId, bool force, bool inplace)
if (!inplace) if (!inplace)
{ {
inplace = IsSharedSystemRelationName(NameStr(iRel->rd_rel->relname)); inplace = iRel->rd_rel->relisshared;
if (!inplace) if (!inplace)
setNewRelfilenode(iRel); setNewRelfilenode(iRel);
} }
@ -2114,7 +2063,7 @@ reindex_relation(Oid relid, bool force)
* Shared system indexes must be overwritten because it's impossible * Shared system indexes must be overwritten because it's impossible
* to update pg_class tuples of all databases. * to update pg_class tuples of all databases.
*/ */
if (IsSharedSystemRelationName(NameStr(rel->rd_rel->relname))) if (rel->rd_rel->relisshared)
{ {
if (IsIgnoringSystemIndexes()) if (IsIgnoringSystemIndexes())
{ {

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.77 2001/03/22 03:59:20 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.78 2001/06/12 05:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -28,21 +28,25 @@
#include "utils/syscache.h" #include "utils/syscache.h"
/* /*
* Names of indices - they match all system caches * Names of indices for each system catalog.
*/ */
char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] = char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] =
{AggregateNameTypeIndex}; {AggregateNameTypeIndex};
char *Name_pg_am_indices[Num_pg_am_indices] = char *Name_pg_am_indices[Num_pg_am_indices] =
{AmNameIndex}; {AmNameIndex, AmOidIndex};
char *Name_pg_amop_indices[Num_pg_amop_indices] = char *Name_pg_amop_indices[Num_pg_amop_indices] =
{AccessMethodOpidIndex, AccessMethodStrategyIndex}; {AccessMethodOpidIndex, AccessMethodStrategyIndex};
char *Name_pg_amproc_indices[Num_pg_amproc_indices] =
{AccessProcedureIndex};
char *Name_pg_attr_indices[Num_pg_attr_indices] = char *Name_pg_attr_indices[Num_pg_attr_indices] =
{AttributeRelidNameIndex, AttributeRelidNumIndex}; {AttributeRelidNameIndex, AttributeRelidNumIndex};
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
{AttrDefaultIndex}; {AttrDefaultIndex};
char *Name_pg_class_indices[Num_pg_class_indices] = char *Name_pg_class_indices[Num_pg_class_indices] =
{ClassNameIndex, ClassOidIndex}; {ClassNameIndex, ClassOidIndex};
char *Name_pg_database_indices[Num_pg_database_indices] =
{DatabaseNameIndex, DatabaseOidIndex};
char *Name_pg_group_indices[Num_pg_group_indices] = char *Name_pg_group_indices[Num_pg_group_indices] =
{GroupNameIndex, GroupSysidIndex}; {GroupNameIndex, GroupSysidIndex};
char *Name_pg_index_indices[Num_pg_index_indices] = char *Name_pg_index_indices[Num_pg_index_indices] =
@ -53,10 +57,8 @@ char *Name_pg_language_indices[Num_pg_language_indices] =
{LanguageOidIndex, LanguageNameIndex}; {LanguageOidIndex, LanguageNameIndex};
char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] = char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] =
{LargeObjectLOidPNIndex}; {LargeObjectLOidPNIndex};
char *Name_pg_listener_indices[Num_pg_listener_indices] =
{ListenerPidRelnameIndex};
char *Name_pg_opclass_indices[Num_pg_opclass_indices] = char *Name_pg_opclass_indices[Num_pg_opclass_indices] =
{OpclassNameIndex, OpclassDeftypeIndex}; {OpclassDeftypeIndex, OpclassNameIndex, OpclassOidIndex};
char *Name_pg_operator_indices[Num_pg_operator_indices] = char *Name_pg_operator_indices[Num_pg_operator_indices] =
{OperatorOidIndex, OperatorNameIndex}; {OperatorOidIndex, OperatorNameIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] = char *Name_pg_proc_indices[Num_pg_proc_indices] =
@ -64,7 +66,7 @@ char *Name_pg_proc_indices[Num_pg_proc_indices] =
char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] = char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] =
{RelCheckIndex}; {RelCheckIndex};
char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] = char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
{RewriteOidIndex, RewriteRulenameIndex}; {RewriteRulenameIndex};
char *Name_pg_shadow_indices[Num_pg_shadow_indices] = char *Name_pg_shadow_indices[Num_pg_shadow_indices] =
{ShadowNameIndex, ShadowSysidIndex}; {ShadowNameIndex, ShadowSysidIndex};
char *Name_pg_statistic_indices[Num_pg_statistic_indices] = char *Name_pg_statistic_indices[Num_pg_statistic_indices] =

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.77 2001/03/22 03:59:21 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.78 2001/06/12 05:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -80,7 +80,6 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/pg_listener.h" #include "catalog/pg_listener.h"
#include "commands/async.h" #include "commands/async.h"
#include "lib/dllist.h" #include "lib/dllist.h"
@ -195,11 +194,12 @@ void
Async_Listen(char *relname, int pid) Async_Listen(char *relname, int pid)
{ {
Relation lRel; Relation lRel;
HeapScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
Datum values[Natts_pg_listener]; Datum values[Natts_pg_listener];
char nulls[Natts_pg_listener]; char nulls[Natts_pg_listener];
int i; int i;
TupleDesc tupDesc; bool alreadyListener = false;
if (Trace_notify) if (Trace_notify)
elog(DEBUG, "Async_Listen: %s", relname); elog(DEBUG, "Async_Listen: %s", relname);
@ -207,12 +207,23 @@ Async_Listen(char *relname, int pid)
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock); lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
/* Detect whether we are already listening on this relname */ /* Detect whether we are already listening on this relname */
if (SearchSysCacheExists(LISTENREL, scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
Int32GetDatum(pid), while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
PointerGetDatum(relname), {
0, 0)) Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
if (listener->listenerpid == pid &&
strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
{
alreadyListener = true;
/* No need to scan the rest of the table */
break;
}
}
heap_endscan(scan);
if (alreadyListener)
{ {
/* No need to scan the rest of the table */
heap_close(lRel, AccessExclusiveLock); heap_close(lRel, AccessExclusiveLock);
elog(NOTICE, "Async_Listen: We are already listening on %s", relname); elog(NOTICE, "Async_Listen: We are already listening on %s", relname);
return; return;
@ -233,9 +244,10 @@ Async_Listen(char *relname, int pid)
values[i++] = (Datum) pid; values[i++] = (Datum) pid;
values[i++] = (Datum) 0; /* no notifies pending */ values[i++] = (Datum) 0; /* no notifies pending */
tupDesc = lRel->rd_att; tuple = heap_formtuple(RelationGetDescr(lRel), values, nulls);
tuple = heap_formtuple(tupDesc, values, nulls);
heap_insert(lRel, tuple); heap_insert(lRel, tuple);
#ifdef NOT_USED /* currently there are no indexes */
if (RelationGetForm(lRel)->relhasindex) if (RelationGetForm(lRel)->relhasindex)
{ {
Relation idescs[Num_pg_listener_indices]; Relation idescs[Num_pg_listener_indices];
@ -244,6 +256,7 @@ Async_Listen(char *relname, int pid)
CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, tuple); CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, tuple);
CatalogCloseIndices(Num_pg_listener_indices, idescs); CatalogCloseIndices(Num_pg_listener_indices, idescs);
} }
#endif
heap_freetuple(tuple); heap_freetuple(tuple);
@ -280,7 +293,8 @@ void
Async_Unlisten(char *relname, int pid) Async_Unlisten(char *relname, int pid)
{ {
Relation lRel; Relation lRel;
HeapTuple lTuple; HeapScanDesc scan;
HeapTuple tuple;
/* Handle specially the `unlisten "*"' command */ /* Handle specially the `unlisten "*"' command */
if ((!relname) || (*relname == '\0') || (strcmp(relname, "*") == 0)) if ((!relname) || (*relname == '\0') || (strcmp(relname, "*") == 0))
@ -293,16 +307,26 @@ Async_Unlisten(char *relname, int pid)
elog(DEBUG, "Async_Unlisten %s", relname); elog(DEBUG, "Async_Unlisten %s", relname);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock); lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
/* Note we assume there can be only one matching tuple. */
lTuple = SearchSysCache(LISTENREL, scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
Int32GetDatum(pid), while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
PointerGetDatum(relname),
0, 0);
if (HeapTupleIsValid(lTuple))
{ {
simple_heap_delete(lRel, &lTuple->t_self); Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
ReleaseSysCache(lTuple);
if (listener->listenerpid == pid &&
strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
{
/* Found the matching tuple, delete it */
simple_heap_delete(lRel, &tuple->t_self);
/*
* We assume there can be only one match, so no need
* to scan the rest of the table
*/
break;
}
} }
heap_endscan(scan);
heap_close(lRel, AccessExclusiveLock); heap_close(lRel, AccessExclusiveLock);
/* /*
@ -332,7 +356,7 @@ Async_UnlistenAll()
{ {
Relation lRel; Relation lRel;
TupleDesc tdesc; TupleDesc tdesc;
HeapScanDesc sRel; HeapScanDesc scan;
HeapTuple lTuple; HeapTuple lTuple;
ScanKeyData key[1]; ScanKeyData key[1];
@ -347,12 +371,12 @@ Async_UnlistenAll()
Anum_pg_listener_pid, Anum_pg_listener_pid,
F_INT4EQ, F_INT4EQ,
Int32GetDatum(MyProcPid)); Int32GetDatum(MyProcPid));
sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key); scan = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0))) while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
simple_heap_delete(lRel, &lTuple->t_self); simple_heap_delete(lRel, &lTuple->t_self);
heap_endscan(sRel); heap_endscan(scan);
heap_close(lRel, AccessExclusiveLock); heap_close(lRel, AccessExclusiveLock);
} }
@ -418,16 +442,12 @@ AtCommit_Notify()
{ {
Relation lRel; Relation lRel;
TupleDesc tdesc; TupleDesc tdesc;
HeapScanDesc sRel; HeapScanDesc scan;
HeapTuple lTuple, HeapTuple lTuple,
rTuple; rTuple;
Datum d, Datum value[Natts_pg_listener];
value[Natts_pg_listener];
char repl[Natts_pg_listener], char repl[Natts_pg_listener],
nulls[Natts_pg_listener]; nulls[Natts_pg_listener];
bool isnull;
char *relname;
int32 listenerPID;
if (!pendingNotifies) if (!pendingNotifies)
return; /* no NOTIFY statements in this return; /* no NOTIFY statements in this
@ -446,10 +466,6 @@ AtCommit_Notify()
if (Trace_notify) if (Trace_notify)
elog(DEBUG, "AtCommit_Notify"); elog(DEBUG, "AtCommit_Notify");
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
/* preset data to update notify column to MyProcPid */ /* preset data to update notify column to MyProcPid */
nulls[0] = nulls[1] = nulls[2] = ' '; nulls[0] = nulls[1] = nulls[2] = ' ';
repl[0] = repl[1] = repl[2] = ' '; repl[0] = repl[1] = repl[2] = ' ';
@ -457,83 +473,81 @@ AtCommit_Notify()
value[0] = value[1] = value[2] = (Datum) 0; value[0] = value[1] = value[2] = (Datum) 0;
value[Anum_pg_listener_notify - 1] = Int32GetDatum(MyProcPid); value[Anum_pg_listener_notify - 1] = Int32GetDatum(MyProcPid);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0))) lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
{ {
d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc, &isnull); Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(lTuple);
relname = (char *) DatumGetPointer(d); char *relname = NameStr(listener->relname);
int32 listenerPID = listener->listenerpid;
if (AsyncExistsPendingNotify(relname)) if (! AsyncExistsPendingNotify(relname))
continue;
if (listenerPID == MyProcPid)
{ {
d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull); /*
listenerPID = DatumGetInt32(d); * Self-notify: no need to bother with table update.
* Indeed, we *must not* clear the notification field in
* this path, or we could lose an outside notify, which'd
* be bad for applications that ignore self-notify messages.
*/
if (listenerPID == MyProcPid) if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: notifying self");
NotifyMyFrontEnd(relname, listenerPID);
}
else
{
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: notifying pid %d",
listenerPID);
/*
* If someone has already notified this listener, we don't
* bother modifying the table, but we do still send a
* SIGUSR2 signal, just in case that backend missed the
* earlier signal for some reason. It's OK to send the
* signal first, because the other guy can't read
* pg_listener until we unlock it.
*/
if (kill(listenerPID, SIGUSR2) < 0)
{ {
/* /*
* Self-notify: no need to bother with table update. * Get rid of pg_listener entry if it refers to a PID
* Indeed, we *must not* clear the notification field in * that no longer exists. Presumably, that backend
* this path, or we could lose an outside notify, which'd * crashed without deleting its pg_listener entries.
* be bad for applications that ignore self-notify * This code used to only delete the entry if
* messages. * errno==ESRCH, but as far as I can see we should
* just do it for any failure (certainly at least for
* EPERM too...)
*/ */
simple_heap_delete(lRel, &lTuple->t_self);
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: notifying self");
NotifyMyFrontEnd(relname, listenerPID);
} }
else else if (listener->notification == 0)
{ {
if (Trace_notify) rTuple = heap_modifytuple(lTuple, lRel,
elog(DEBUG, "AtCommit_Notify: notifying pid %d", listenerPID); value, nulls, repl);
simple_heap_update(lRel, &lTuple->t_self, rTuple);
/* #ifdef NOT_USED /* currently there are no indexes */
* If someone has already notified this listener, we don't if (RelationGetForm(lRel)->relhasindex)
* bother modifying the table, but we do still send a
* SIGUSR2 signal, just in case that backend missed the
* earlier signal for some reason. It's OK to send the
* signal first, because the other guy can't read
* pg_listener until we unlock it.
*/
if (kill(listenerPID, SIGUSR2) < 0)
{ {
Relation idescs[Num_pg_listener_indices];
/* CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs);
* Get rid of pg_listener entry if it refers to a PID CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
* that no longer exists. Presumably, that backend CatalogCloseIndices(Num_pg_listener_indices, idescs);
* crashed without deleting its pg_listener entries.
* This code used to only delete the entry if
* errno==ESRCH, but as far as I can see we should
* just do it for any failure (certainly at least for
* EPERM too...)
*/
simple_heap_delete(lRel, &lTuple->t_self);
}
else
{
d = heap_getattr(lTuple, Anum_pg_listener_notify,
tdesc, &isnull);
if (DatumGetInt32(d) == 0)
{
rTuple = heap_modifytuple(lTuple, lRel,
value, nulls, repl);
simple_heap_update(lRel, &lTuple->t_self, rTuple);
if (RelationGetForm(lRel)->relhasindex)
{
Relation idescs[Num_pg_listener_indices];
CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
CatalogCloseIndices(Num_pg_listener_indices, idescs);
}
}
} }
#endif
} }
} }
} }
heap_endscan(sRel); heap_endscan(scan);
/* /*
* We do NOT release the lock on pg_listener here; we need to hold it * We do NOT release the lock on pg_listener here; we need to hold it
@ -745,16 +759,12 @@ ProcessIncomingNotify(void)
Relation lRel; Relation lRel;
TupleDesc tdesc; TupleDesc tdesc;
ScanKeyData key[1]; ScanKeyData key[1];
HeapScanDesc sRel; HeapScanDesc scan;
HeapTuple lTuple, HeapTuple lTuple,
rTuple; rTuple;
Datum d, Datum value[Natts_pg_listener];
value[Natts_pg_listener];
char repl[Natts_pg_listener], char repl[Natts_pg_listener],
nulls[Natts_pg_listener]; nulls[Natts_pg_listener];
bool isnull;
char *relname;
int32 sourcePID;
if (Trace_notify) if (Trace_notify)
elog(DEBUG, "ProcessIncomingNotify"); elog(DEBUG, "ProcessIncomingNotify");
@ -773,7 +783,7 @@ ProcessIncomingNotify(void)
Anum_pg_listener_pid, Anum_pg_listener_pid,
F_INT4EQ, F_INT4EQ,
Int32GetDatum(MyProcPid)); Int32GetDatum(MyProcPid));
sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key); scan = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
/* Prepare data for rewriting 0 into notification field */ /* Prepare data for rewriting 0 into notification field */
nulls[0] = nulls[1] = nulls[2] = ' '; nulls[0] = nulls[1] = nulls[2] = ' ';
@ -782,14 +792,14 @@ ProcessIncomingNotify(void)
value[0] = value[1] = value[2] = (Datum) 0; value[0] = value[1] = value[2] = (Datum) 0;
value[Anum_pg_listener_notify - 1] = Int32GetDatum(0); value[Anum_pg_listener_notify - 1] = Int32GetDatum(0);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0))) while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
{ {
d = heap_getattr(lTuple, Anum_pg_listener_notify, tdesc, &isnull); Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(lTuple);
sourcePID = DatumGetInt32(d); char *relname = NameStr(listener->relname);
int32 sourcePID = listener->notification;
if (sourcePID != 0) if (sourcePID != 0)
{ {
d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc, &isnull);
relname = (char *) DatumGetPointer(d);
/* Notify the frontend */ /* Notify the frontend */
if (Trace_notify) if (Trace_notify)
@ -800,6 +810,8 @@ ProcessIncomingNotify(void)
/* Rewrite the tuple with 0 in notification column */ /* Rewrite the tuple with 0 in notification column */
rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl); rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl);
simple_heap_update(lRel, &lTuple->t_self, rTuple); simple_heap_update(lRel, &lTuple->t_self, rTuple);
#ifdef NOT_USED /* currently there are no indexes */
if (RelationGetForm(lRel)->relhasindex) if (RelationGetForm(lRel)->relhasindex)
{ {
Relation idescs[Num_pg_listener_indices]; Relation idescs[Num_pg_listener_indices];
@ -808,9 +820,10 @@ ProcessIncomingNotify(void)
CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple); CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
CatalogCloseIndices(Num_pg_listener_indices, idescs); CatalogCloseIndices(Num_pg_listener_indices, idescs);
} }
#endif
} }
} }
heap_endscan(sRel); heap_endscan(scan);
/* /*
* We do NOT release the lock on pg_listener here; we need to hold it * We do NOT release the lock on pg_listener here; we need to hold it
@ -876,7 +889,7 @@ AsyncExistsPendingNotify(char *relname)
p = DLGetSucc(p)) p = DLGetSucc(p))
{ {
/* Use NAMEDATALEN for relname comparison. DZ - 26-08-1996 */ /* Use NAMEDATALEN for relname comparison. DZ - 26-08-1996 */
if (!strncmp((const char *) DLE_VAL(p), relname, NAMEDATALEN)) if (strncmp((const char *) DLE_VAL(p), relname, NAMEDATALEN) == 0)
return 1; return 1;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.132 2001/06/07 00:09:28 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.133 2001/06/12 05:55:49 tgl Exp $
* *
* NOTES * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
@ -411,8 +411,8 @@ AlterTableAddColumn(const char *relationName,
attributeD.attrelid = reltup->t_data->t_oid; attributeD.attrelid = reltup->t_data->t_oid;
attributeTuple = heap_addheader(Natts_pg_attribute, attributeTuple = heap_addheader(Natts_pg_attribute,
sizeof attributeD, ATTRIBUTE_TUPLE_SIZE,
(char *) &attributeD); (void *) &attributeD);
attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple); attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple);
@ -481,7 +481,7 @@ AlterTableAddColumn(const char *relationName,
if (hasindex) if (hasindex)
CatalogCloseIndices(Num_pg_attr_indices, idescs); CatalogCloseIndices(Num_pg_attr_indices, idescs);
heap_close(attrdesc, RowExclusiveLock); heap_close(attrdesc, NoLock);
/* /*
* Update number of attributes in pg_class tuple * Update number of attributes in pg_class tuple
@ -580,17 +580,15 @@ AlterTableAlterColumnDefault(const char *relationName,
PointerGetDatum(colName), PointerGetDatum(colName),
0, 0); 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
heap_close(rel, AccessExclusiveLock);
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
relationName, colName); relationName, colName);
}
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
if (newDefault) /* SET DEFAULT */ if (newDefault)
{ {
/* SET DEFAULT */
List *rawDefaults = NIL; List *rawDefaults = NIL;
RawColumnDefault *rawEnt; RawColumnDefault *rawEnt;
@ -608,15 +606,14 @@ AlterTableAlterColumnDefault(const char *relationName,
*/ */
AddRelationRawConstraints(rel, rawDefaults, NIL); AddRelationRawConstraints(rel, rawDefaults, NIL);
} }
else else
/* DROP DEFAULT */
{ {
/* DROP DEFAULT */
Relation attr_rel; Relation attr_rel;
ScanKeyData scankeys[3]; ScanKeyData scankeys[3];
HeapScanDesc scan; HeapScanDesc scan;
attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock); attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&scankeys[0], 0x0, ScanKeyEntryInitialize(&scankeys[0], 0x0,
Anum_pg_attribute_attrelid, F_OIDEQ, Anum_pg_attribute_attrelid, F_OIDEQ,
ObjectIdGetDatum(myrelid)); ObjectIdGetDatum(myrelid));
@ -665,7 +662,7 @@ drop_default(Oid relid, int16 attnum)
Relation attrdef_rel; Relation attrdef_rel;
HeapTuple tuple; HeapTuple tuple;
attrdef_rel = heap_openr(AttrDefaultRelationName, AccessExclusiveLock); attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&scankeys[0], 0x0, ScanKeyEntryInitialize(&scankeys[0], 0x0,
Anum_pg_attrdef_adrelid, F_OIDEQ, Anum_pg_attrdef_adrelid, F_OIDEQ,
ObjectIdGetDatum(relid)); ObjectIdGetDatum(relid));
@ -778,7 +775,7 @@ AlterTableAlterColumnStatistics(const char *relationName,
} }
heap_freetuple(tuple); heap_freetuple(tuple);
heap_close(attrelation, RowExclusiveLock); heap_close(attrelation, NoLock);
} }
@ -1010,8 +1007,7 @@ AlterTableDropColumn(const char *relationName,
{ {
#ifdef _DROP_COLUMN_HACK__ #ifdef _DROP_COLUMN_HACK__
Relation rel, Relation rel,
attrdesc, attrdesc;
adrel;
Oid myrelid, Oid myrelid,
attoid; attoid;
HeapTuple reltup; HeapTuple reltup;
@ -1023,8 +1019,6 @@ AlterTableDropColumn(const char *relationName,
int attnum; int attnum;
bool hasindex; bool hasindex;
char dropColname[32]; char dropColname[32];
void *sysscan;
ScanKeyData scankeys[2];
if (inh) if (inh)
elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet"); elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet");
@ -1136,30 +1130,9 @@ AlterTableDropColumn(const char *relationName,
/* delete comments */ /* delete comments */
DeleteComments(attoid); DeleteComments(attoid);
/* delete attrdef */
adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid,
F_OIDEQ, ObjectIdGetDatum(myrelid));
/*-------- /* delete attrdef */
* Oops pg_attrdef doesn't have (adrelid,adnum) index drop_default(myrelid, attnum);
*
* ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum,
* F_INT2EQ, Int16GetDatum(attnum));
* sysscan = systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys);
*--------
*/
sysscan = systable_beginscan(adrel, AttrDefaultIndex, 1, scankeys);
while (HeapTupleIsValid(tup = systable_getnext(sysscan)))
{
if (((Form_pg_attrdef) GETSTRUCT(tup))->adnum == attnum)
{
simple_heap_delete(adrel, &tup->t_self);
break;
}
}
systable_endscan(sysscan);
heap_close(adrel, NoLock);
/* /*
* Remove objects which reference this column * Remove objects which reference this column
@ -1318,10 +1291,7 @@ AlterTableAddConstraint(char *relationName,
heap_endscan(scan); heap_endscan(scan);
if (!successful) if (!successful)
{
heap_close(rel, NoLock);
elog(ERROR, "AlterTableAddConstraint: rejected due to CHECK constraint %s", name); elog(ERROR, "AlterTableAddConstraint: rejected due to CHECK constraint %s", name);
}
/* /*
* Call AddRelationRawConstraints to do the * Call AddRelationRawConstraints to do the
@ -1768,7 +1738,7 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
* unlock everything and return * unlock everything and return
*/ */
heap_freetuple(tuple); heap_freetuple(tuple);
heap_close(class_rel, RowExclusiveLock); heap_close(class_rel, NoLock);
} }

View File

@ -1,6 +1,7 @@
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* dbcommands.c * dbcommands.c
* Database management commands (create/drop database).
* *
* *
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
@ -8,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.74 2001/03/22 03:59:22 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.75 2001/06/12 05:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -25,6 +26,7 @@
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/indexing.h"
#include "commands/comment.h" #include "commands/comment.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -241,9 +243,8 @@ createdb(const char *dbname, const char *dbpath,
heap_insert(pg_database_rel, tuple); heap_insert(pg_database_rel, tuple);
/* /*
* Update indexes (there aren't any currently) * Update indexes
*/ */
#ifdef Num_pg_database_indices
if (RelationGetForm(pg_database_rel)->relhasindex) if (RelationGetForm(pg_database_rel)->relhasindex)
{ {
Relation idescs[Num_pg_database_indices]; Relation idescs[Num_pg_database_indices];
@ -254,7 +255,6 @@ createdb(const char *dbname, const char *dbpath,
tuple); tuple);
CatalogCloseIndices(Num_pg_database_indices, idescs); CatalogCloseIndices(Num_pg_database_indices, idescs);
} }
#endif
/* Close pg_database, but keep lock till commit */ /* Close pg_database, but keep lock till commit */
heap_close(pg_database_rel, NoLock); heap_close(pg_database_rel, NoLock);
@ -333,7 +333,7 @@ dropdb(const char *dbname)
elog(ERROR, "DROP DATABASE: database \"%s\" is being accessed by other users", dbname); elog(ERROR, "DROP DATABASE: database \"%s\" is being accessed by other users", dbname);
/* /*
* Find the database's tuple by OID (should be unique, we trust). * Find the database's tuple by OID (should be unique).
*/ */
ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber, ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,
F_OIDEQ, ObjectIdGetDatum(db_id)); F_OIDEQ, ObjectIdGetDatum(db_id));
@ -343,7 +343,6 @@ dropdb(const char *dbname)
tup = heap_getnext(pgdbscan, 0); tup = heap_getnext(pgdbscan, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{ {
/* /*
* This error should never come up since the existence of the * This error should never come up since the existence of the
* database is checked earlier * database is checked earlier

View File

@ -6,17 +6,17 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.75 2001/03/22 06:16:12 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.76 2001/06/12 05:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include "postgres.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
@ -31,9 +31,9 @@
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/syscache.h" #include "utils/syscache.h"
static void CheckPgUserAclNotNull(void); static void CheckPgUserAclNotNull(void);
#define SQL_LENGTH 512
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
* write_password_file / update_pg_pwd * write_password_file / update_pg_pwd
@ -121,8 +121,7 @@ write_password_file(Relation rel)
"%s" "%s"
CRYPT_PWD_FILE_SEPSTR CRYPT_PWD_FILE_SEPSTR
"%s\n", "%s\n",
DatumGetCString(DirectFunctionCall1(nameout, DatumGetCString(DirectFunctionCall1(nameout, datum_n)),
NameGetDatum(DatumGetName(datum_n)))),
null_p ? "" : null_p ? "" :
DatumGetCString(DirectFunctionCall1(textout, datum_p)), DatumGetCString(DirectFunctionCall1(textout, datum_p)),
null_v ? "\\N" : null_v ? "\\N" :
@ -168,10 +167,16 @@ write_password_file(Relation rel)
Datum Datum
update_pg_pwd(PG_FUNCTION_ARGS) update_pg_pwd(PG_FUNCTION_ARGS)
{ {
Relation rel = heap_openr(ShadowRelationName, AccessExclusiveLock); /*
* ExclusiveLock ensures no one modifies pg_shadow while we read it,
* and that only one backend rewrites the flat file at a time. It's
* OK to allow normal reads of pg_shadow in parallel, however.
*/
Relation rel = heap_openr(ShadowRelationName, ExclusiveLock);
write_password_file(rel); write_password_file(rel);
heap_close(rel, AccessExclusiveLock); /* OK to release lock, since we did not modify the relation */
heap_close(rel, ExclusiveLock);
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
} }
@ -210,39 +215,41 @@ CreateUser(CreateUserStmt *stmt)
* to be sure of what the next usesysid should be, and we need to * to be sure of what the next usesysid should be, and we need to
* protect our update of the flat password file. * protect our update of the flat password file.
*/ */
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_rel = heap_openr(ShadowRelationName, ExclusiveLock);
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL); scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL);
while (!user_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (!user_exists && !sysid_exists &&
HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
Datum datum; Datum datum;
bool null; bool null;
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &null); datum = heap_getattr(tuple, Anum_pg_shadow_usename,
user_exists = datum && !null && (strcmp((char *) datum, stmt->user) == 0); pg_shadow_dsc, &null);
Assert(!null);
user_exists = (strcmp((char *) DatumGetName(datum), stmt->user) == 0);
datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null); datum = heap_getattr(tuple, Anum_pg_shadow_usesysid,
pg_shadow_dsc, &null);
Assert(!null);
if (havesysid) /* customized id wanted */ if (havesysid) /* customized id wanted */
sysid_exists = datum && !null && ((int) datum == stmt->sysid); sysid_exists = (DatumGetInt32(datum) == stmt->sysid);
else else
/* pick 1 + max */
{ {
if ((int) datum > max_id) /* pick 1 + max */
max_id = (int) datum; if (DatumGetInt32(datum) > max_id)
max_id = DatumGetInt32(datum);
} }
} }
heap_endscan(scan); heap_endscan(scan);
if (user_exists || sysid_exists) if (user_exists)
{ elog(ERROR, "CREATE USER: user name \"%s\" already exists",
heap_close(pg_shadow_rel, AccessExclusiveLock); stmt->user);
if (user_exists) if (sysid_exists)
elog(ERROR, "CREATE USER: user name \"%s\" already exists", stmt->user); elog(ERROR, "CREATE USER: sysid %d is already assigned",
else stmt->sysid);
elog(ERROR, "CREATE USER: sysid %d is already assigned", stmt->sysid);
return;
}
/* /*
* Build a tuple to insert * Build a tuple to insert
@ -252,12 +259,12 @@ CreateUser(CreateUserStmt *stmt)
new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1); new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1);
AssertState(BoolIsValid(stmt->createdb)); AssertState(BoolIsValid(stmt->createdb));
new_record[Anum_pg_shadow_usecreatedb - 1] = (Datum) (stmt->createdb); new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(stmt->createdb);
new_record[Anum_pg_shadow_usetrace - 1] = (Datum) (false); new_record[Anum_pg_shadow_usetrace - 1] = BoolGetDatum(false);
AssertState(BoolIsValid(stmt->createuser)); AssertState(BoolIsValid(stmt->createuser));
new_record[Anum_pg_shadow_usesuper - 1] = (Datum) (stmt->createuser); new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(stmt->createuser);
/* superuser gets catupd right by default */ /* superuser gets catupd right by default */
new_record[Anum_pg_shadow_usecatupd - 1] = (Datum) (stmt->createuser); new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(stmt->createuser);
if (stmt->password) if (stmt->password)
new_record[Anum_pg_shadow_passwd - 1] = new_record[Anum_pg_shadow_passwd - 1] =
@ -278,13 +285,11 @@ CreateUser(CreateUserStmt *stmt)
new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n'; new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n';
tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls);
Assert(tuple);
/* /*
* Insert a new record in the pg_shadow table * Insert new record in the pg_shadow table
*/ */
if (heap_insert(pg_shadow_rel, tuple) == InvalidOid) heap_insert(pg_shadow_rel, tuple);
elog(ERROR, "CREATE USER: heap_insert failed");
/* /*
* Update indexes * Update indexes
@ -322,9 +327,9 @@ CreateUser(CreateUserStmt *stmt)
write_password_file(pg_shadow_rel); write_password_file(pg_shadow_rel);
/* /*
* Now we can clean up. * Now we can clean up; but keep lock until commit.
*/ */
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, NoLock);
} }
@ -348,8 +353,11 @@ AlterUser(AlterUserStmt *stmt)
/* must be superuser or just want to change your own password */ /* must be superuser or just want to change your own password */
if (!superuser() && if (!superuser() &&
!(stmt->createdb == 0 && stmt->createuser == 0 && !stmt->validUntil !(stmt->createdb == 0 &&
&& stmt->password && strcmp(GetUserName(GetUserId()), stmt->user) == 0)) stmt->createuser == 0 &&
!stmt->validUntil &&
stmt->password &&
strcmp(GetUserName(GetUserId()), stmt->user) == 0))
elog(ERROR, "ALTER USER: permission denied"); elog(ERROR, "ALTER USER: permission denied");
/* changes to the flat password file cannot be rolled back */ /* changes to the flat password file cannot be rolled back */
@ -361,17 +369,14 @@ AlterUser(AlterUserStmt *stmt)
* secure exclusive lock to protect our update of the flat password * secure exclusive lock to protect our update of the flat password
* file. * file.
*/ */
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_rel = heap_openr(ShadowRelationName, ExclusiveLock);
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
tuple = SearchSysCache(SHADOWNAME, tuple = SearchSysCache(SHADOWNAME,
PointerGetDatum(stmt->user), PointerGetDatum(stmt->user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
heap_close(pg_shadow_rel, AccessExclusiveLock);
elog(ERROR, "ALTER USER: user \"%s\" does not exist", stmt->user); elog(ERROR, "ALTER USER: user \"%s\" does not exist", stmt->user);
}
/* /*
* Build a tuple to update, perusing the information just obtained * Build a tuple to update, perusing the information just obtained
@ -483,8 +488,7 @@ AlterUser(AlterUserStmt *stmt)
/* /*
* Now we can clean up. * Now we can clean up.
*/ */
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, NoLock);
} }
@ -510,7 +514,7 @@ DropUser(DropUserStmt *stmt)
* deleted. Note we secure exclusive lock, because we need to protect * deleted. Note we secure exclusive lock, because we need to protect
* our update of the flat password file. * our update of the flat password file.
*/ */
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_rel = heap_openr(ShadowRelationName, ExclusiveLock);
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
foreach(item, stmt->users) foreach(item, stmt->users)
@ -530,11 +534,8 @@ DropUser(DropUserStmt *stmt)
PointerGetDatum(user), PointerGetDatum(user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
heap_close(pg_shadow_rel, AccessExclusiveLock);
elog(ERROR, "DROP USER: user \"%s\" does not exist%s", user, elog(ERROR, "DROP USER: user \"%s\" does not exist%s", user,
(length(stmt->users) > 1) ? " (no users removed)" : ""); (length(stmt->users) > 1) ? " (no users removed)" : "");
}
usesysid = DatumGetInt32(heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null)); usesysid = DatumGetInt32(heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null));
@ -546,28 +547,30 @@ DropUser(DropUserStmt *stmt)
* don't read the manual, it doesn't seem to be the behaviour one * don't read the manual, it doesn't seem to be the behaviour one
* would expect either.) -- petere 2000/01/14) * would expect either.) -- petere 2000/01/14)
*/ */
pg_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock); pg_rel = heap_openr(DatabaseRelationName, AccessShareLock);
pg_dsc = RelationGetDescr(pg_rel); pg_dsc = RelationGetDescr(pg_rel);
ScanKeyEntryInitialize(&scankey, 0x0, Anum_pg_database_datdba, F_INT4EQ, ScanKeyEntryInitialize(&scankey, 0x0,
Anum_pg_database_datdba, F_INT4EQ,
Int32GetDatum(usesysid)); Int32GetDatum(usesysid));
scan = heap_beginscan(pg_rel, false, SnapshotNow, 1, &scankey); scan = heap_beginscan(pg_rel, false, SnapshotNow, 1, &scankey);
if (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0))) if (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0)))
{ {
datum = heap_getattr(tmp_tuple, Anum_pg_database_datname, pg_dsc, &null); char *dbname;
heap_close(pg_shadow_rel, AccessExclusiveLock);
datum = heap_getattr(tmp_tuple, Anum_pg_database_datname,
pg_dsc, &null);
Assert(!null);
dbname = DatumGetCString(DirectFunctionCall1(nameout, datum));
elog(ERROR, "DROP USER: user \"%s\" owns database \"%s\", cannot be removed%s", elog(ERROR, "DROP USER: user \"%s\" owns database \"%s\", cannot be removed%s",
user, user, dbname,
DatumGetCString(DirectFunctionCall1(nameout, (length(stmt->users) > 1) ? " (no users removed)" : "");
NameGetDatum(DatumGetName(datum)))),
(length(stmt->users) > 1) ? " (no users removed)" : ""
);
} }
heap_endscan(scan); heap_endscan(scan);
heap_close(pg_rel, AccessExclusiveLock); heap_close(pg_rel, AccessShareLock);
/* /*
* Somehow we'd have to check for tables, views, etc. owned by the * Somehow we'd have to check for tables, views, etc. owned by the
@ -587,7 +590,7 @@ DropUser(DropUserStmt *stmt)
* *
* try calling alter group drop user for every group * try calling alter group drop user for every group
*/ */
pg_rel = heap_openr(GroupRelationName, AccessExclusiveLock); pg_rel = heap_openr(GroupRelationName, ExclusiveLock);
pg_dsc = RelationGetDescr(pg_rel); pg_dsc = RelationGetDescr(pg_rel);
scan = heap_beginscan(pg_rel, false, SnapshotNow, 0, NULL); scan = heap_beginscan(pg_rel, false, SnapshotNow, 0, NULL);
while (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0)))
@ -602,7 +605,7 @@ DropUser(DropUserStmt *stmt)
AlterGroup(&ags, "DROP USER"); AlterGroup(&ags, "DROP USER");
} }
heap_endscan(scan); heap_endscan(scan);
heap_close(pg_rel, AccessExclusiveLock); heap_close(pg_rel, ExclusiveLock);
/* /*
* Advance command counter so that later iterations of this loop * Advance command counter so that later iterations of this loop
@ -622,7 +625,7 @@ DropUser(DropUserStmt *stmt)
/* /*
* Now we can clean up. * Now we can clean up.
*/ */
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, NoLock);
} }
@ -681,38 +684,41 @@ CreateGroup(CreateGroupStmt *stmt)
if (!superuser()) if (!superuser())
elog(ERROR, "CREATE GROUP: permission denied"); elog(ERROR, "CREATE GROUP: permission denied");
pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock); pg_group_rel = heap_openr(GroupRelationName, ExclusiveLock);
pg_group_dsc = RelationGetDescr(pg_group_rel); pg_group_dsc = RelationGetDescr(pg_group_rel);
scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL); scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL);
while (!group_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, false))) while (!group_exists && !sysid_exists &&
HeapTupleIsValid(tuple = heap_getnext(scan, false)))
{ {
Datum datum; Datum datum;
bool null; bool null;
datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null); datum = heap_getattr(tuple, Anum_pg_group_groname,
group_exists = datum && !null && (strcmp((char *) datum, stmt->name) == 0); pg_group_dsc, &null);
Assert(!null);
group_exists = (strcmp((char *) DatumGetName(datum), stmt->name) == 0);
datum = heap_getattr(tuple, Anum_pg_group_grosysid, pg_group_dsc, &null); datum = heap_getattr(tuple, Anum_pg_group_grosysid,
pg_group_dsc, &null);
Assert(!null);
if (stmt->sysid >= 0) /* customized id wanted */ if (stmt->sysid >= 0) /* customized id wanted */
sysid_exists = datum && !null && ((int) datum == stmt->sysid); sysid_exists = (DatumGetInt32(datum) == stmt->sysid);
else else
/* pick 1 + max */
{ {
if ((int) datum > max_id) /* pick 1 + max */
max_id = (int) datum; if (DatumGetInt32(datum) > max_id)
max_id = DatumGetInt32(datum);
} }
} }
heap_endscan(scan); heap_endscan(scan);
if (group_exists || sysid_exists) if (group_exists)
{ elog(ERROR, "CREATE GROUP: group name \"%s\" already exists",
heap_close(pg_group_rel, AccessExclusiveLock); stmt->name);
if (group_exists) if (sysid_exists)
elog(ERROR, "CREATE GROUP: group name \"%s\" already exists", stmt->name); elog(ERROR, "CREATE GROUP: group sysid %d is already assigned",
else stmt->sysid);
elog(ERROR, "CREATE GROUP: group sysid %d is already assigned", stmt->sysid);
}
/* /*
* Translate the given user names to ids * Translate the given user names to ids
@ -790,7 +796,7 @@ CreateGroup(CreateGroupStmt *stmt)
CatalogCloseIndices(Num_pg_group_indices, idescs); CatalogCloseIndices(Num_pg_group_indices, idescs);
} }
heap_close(pg_group_rel, AccessExclusiveLock); heap_close(pg_group_rel, NoLock);
} }
@ -811,7 +817,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
if (!superuser()) if (!superuser())
elog(ERROR, "%s: permission denied", tag); elog(ERROR, "%s: permission denied", tag);
pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock); pg_group_rel = heap_openr(GroupRelationName, ExclusiveLock);
pg_group_dsc = RelationGetDescr(pg_group_rel); pg_group_dsc = RelationGetDescr(pg_group_rel);
/* /*
@ -1052,7 +1058,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
ReleaseSysCache(group_tuple); ReleaseSysCache(group_tuple);
heap_close(pg_group_rel, AccessExclusiveLock); heap_close(pg_group_rel, NoLock);
} }
@ -1078,7 +1084,7 @@ DropGroup(DropGroupStmt *stmt)
/* /*
* Scan the pg_group table and delete all matching groups. * Scan the pg_group table and delete all matching groups.
*/ */
pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock); pg_group_rel = heap_openr(GroupRelationName, ExclusiveLock);
pg_group_dsc = RelationGetDescr(pg_group_rel); pg_group_dsc = RelationGetDescr(pg_group_rel);
scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL); scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL);
@ -1087,8 +1093,9 @@ DropGroup(DropGroupStmt *stmt)
Datum datum; Datum datum;
bool null; bool null;
datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null); datum = heap_getattr(tuple, Anum_pg_group_groname,
if (datum && !null && strcmp((char *) datum, stmt->name) == 0) pg_group_dsc, &null);
if (!null && strcmp((char *) DatumGetName(datum), stmt->name) == 0)
{ {
gro_exists = true; gro_exists = true;
simple_heap_delete(pg_group_rel, &tuple->t_self); simple_heap_delete(pg_group_rel, &tuple->t_self);
@ -1101,10 +1108,7 @@ DropGroup(DropGroupStmt *stmt)
* Did we find any? * Did we find any?
*/ */
if (!gro_exists) if (!gro_exists)
{
heap_close(pg_group_rel, AccessExclusiveLock);
elog(ERROR, "DROP GROUP: group \"%s\" does not exist", stmt->name); elog(ERROR, "DROP GROUP: group \"%s\" does not exist", stmt->name);
}
heap_close(pg_group_rel, AccessExclusiveLock); heap_close(pg_group_rel, NoLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.45 2001/03/22 03:59:46 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.46 2001/06/12 05:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -107,16 +107,12 @@ InitLockTable(int maxBackends)
void void
RelationInitLockInfo(Relation relation) RelationInitLockInfo(Relation relation)
{ {
char *relname;
Assert(RelationIsValid(relation)); Assert(RelationIsValid(relation));
Assert(OidIsValid(RelationGetRelid(relation))); Assert(OidIsValid(RelationGetRelid(relation)));
relname = (char *) RelationGetPhysicalRelationName(relation);
relation->rd_lockInfo.lockRelId.relId = RelationGetRelid(relation); relation->rd_lockInfo.lockRelId.relId = RelationGetRelid(relation);
if (IsSharedSystemRelationName(relname)) if (relation->rd_rel->relisshared)
relation->rd_lockInfo.lockRelId.dbId = InvalidOid; relation->rd_lockInfo.lockRelId.dbId = InvalidOid;
else else
relation->rd_lockInfo.lockRelId.dbId = MyDatabaseId; relation->rd_lockInfo.lockRelId.dbId = MyDatabaseId;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.136 2001/06/01 02:41:36 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.137 2001/06/12 05:55:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1116,7 +1116,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
*/ */
RelationInitLockInfo(relation); /* see lmgr.c */ RelationInitLockInfo(relation); /* see lmgr.c */
if (IsSharedSystemRelationName(NameStr(relation->rd_rel->relname))) if (relation->rd_rel->relisshared)
relation->rd_node.tblNode = InvalidOid; relation->rd_node.tblNode = InvalidOid;
else else
relation->rd_node.tblNode = MyDatabaseId; relation->rd_node.tblNode = MyDatabaseId;
@ -1201,7 +1201,6 @@ IndexedAccessMethodInitialize(Relation relation)
* catalogs... * catalogs...
* *
* NOTE: we assume we are already switched into CacheMemoryContext. * NOTE: we assume we are already switched into CacheMemoryContext.
*
*/ */
static void static void
formrdesc(char *relationName, formrdesc(char *relationName,
@ -1245,15 +1244,10 @@ formrdesc(char *relationName,
strcpy(RelationGetPhysicalRelationName(relation), relationName); strcpy(RelationGetPhysicalRelationName(relation), relationName);
/* /*
* For debugging purposes, it's important to distinguish between * It's important to distinguish between shared and non-shared relations,
* shared and non-shared relations, even at bootstrap time. There's * even at bootstrap time, to make sure we know where they are stored.
* code in the buffer manager that traces allocations that has to know
* about this.
*/ */
if (IsSystemRelationName(relationName)) relation->rd_rel->relisshared = IsSharedSystemRelationName(relationName);
relation->rd_rel->relisshared = IsSharedSystemRelationName(relationName);
else
relation->rd_rel->relisshared = false;
relation->rd_rel->relpages = 1; relation->rd_rel->relpages = 1;
relation->rd_rel->reltuples = 1; relation->rd_rel->reltuples = 1;
@ -1286,7 +1280,7 @@ formrdesc(char *relationName,
*/ */
RelationInitLockInfo(relation); /* see lmgr.c */ RelationInitLockInfo(relation); /* see lmgr.c */
if (IsSharedSystemRelationName(relationName)) if (relation->rd_rel->relisshared)
relation->rd_node.tblNode = InvalidOid; relation->rd_node.tblNode = InvalidOid;
else else
relation->rd_node.tblNode = MyDatabaseId; relation->rd_node.tblNode = MyDatabaseId;
@ -1301,14 +1295,15 @@ formrdesc(char *relationName,
/* In bootstrap mode, we have no indexes */ /* In bootstrap mode, we have no indexes */
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
{ {
for (i = 0; IndexedCatalogNames[i] != NULL; i++) /*
{ * This list is incomplete, but it only has to work for the
if (strcmp(IndexedCatalogNames[i], relationName) == 0) * set of rels that formrdesc is used for ...
{ */
relation->rd_rel->relhasindex = true; if (strcmp(relationName, RelationRelationName) == 0 ||
break; strcmp(relationName, AttributeRelationName) == 0 ||
} strcmp(relationName, ProcedureRelationName) == 0 ||
} strcmp(relationName, TypeRelationName) == 0)
relation->rd_rel->relhasindex = true;
} }
/* /*
@ -1323,7 +1318,6 @@ formrdesc(char *relationName,
* *
* Update the phony data inserted by formrdesc() with real info * Update the phony data inserted by formrdesc() with real info
* from pg_class. * from pg_class.
*
*/ */
static void static void
fixrdesc(char *relationName) fixrdesc(char *relationName)

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.61 2001/05/07 00:43:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.62 2001/06/12 05:55:49 tgl Exp $
* *
* NOTES * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
@ -31,7 +31,6 @@
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_listener.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
@ -214,15 +213,6 @@ static struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{ListenerRelationName, /* LISTENREL */
ListenerPidRelnameIndex,
2,
{
Anum_pg_listener_pid,
Anum_pg_listener_relname,
0,
0
}},
{OperatorRelationName, /* OPERNAME */ {OperatorRelationName, /* OPERNAME */
OperatorNameIndex, OperatorNameIndex,
4, 4,
@ -277,7 +267,7 @@ static struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{RewriteRelationName, /* REWRITENAME */ {RewriteRelationName, /* RULENAME */
RewriteRulenameIndex, RewriteRulenameIndex,
1, 1,
{ {
@ -286,15 +276,6 @@ static struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{RewriteRelationName, /* RULEOID */
RewriteOidIndex,
1,
{
ObjectIdAttributeNumber,
0,
0,
0
}},
{ShadowRelationName, /* SHADOWNAME */ {ShadowRelationName, /* SHADOWNAME */
ShadowNameIndex, ShadowNameIndex,
1, 1,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.57 2001/05/14 20:30:21 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.58 2001/06/12 05:55:50 tgl Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
@ -30,6 +30,7 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "storage/backendid.h" #include "storage/backendid.h"
ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST; ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST;
bool Noversion = false; bool Noversion = false;
@ -84,36 +85,26 @@ int SortMem = 512;
int NBuffers = DEF_NBUFFERS; int NBuffers = DEF_NBUFFERS;
char *IndexedCatalogNames[] = {
AttributeRelationName,
ProcedureRelationName,
TypeRelationName,
RelationRelationName,
0
};
/* ---------------- /* ----------------
* we just do a linear search now so there's no requirement that the list * List of relations that are shared across all databases in an installation.
*
* This used to be binary-searched, requiring that it be kept in sorted order.
* We just do a linear search now so there's no requirement that the list
* be ordered. The list is so small it shouldn't make much difference. * be ordered. The list is so small it shouldn't make much difference.
* make sure the list is null-terminated * make sure the list is null-terminated
* - jolly 8/19/95 * - jolly 8/19/95
*
* OLD COMMENT
* WARNING WARNING WARNING WARNING WARNING WARNING
*
* keep SharedSystemRelationNames[] in SORTED order! A binary search
* is done on it in catalog.c!
*
* XXX this is a serious hack which should be fixed -cim 1/26/90
* ---------------- * ----------------
*/ */
char *SharedSystemRelationNames[] = { char *SharedSystemRelationNames[] = {
DatabaseRelationName, DatabaseRelationName,
DatabaseNameIndex,
DatabaseOidIndex,
GroupRelationName, GroupRelationName,
GroupNameIndex, GroupNameIndex,
GroupSysidIndex, GroupSysidIndex,
LogRelationName, LogRelationName,
ShadowRelationName, ShadowRelationName,
0 ShadowNameIndex,
ShadowSysidIndex,
NULL
}; };

View File

@ -15,15 +15,19 @@
# changed to add site-local standard data. Either one can be copied # changed to add site-local standard data. Either one can be copied
# to produce a new database. # to produce a new database.
# #
# To create template1, we run the postgres (backend) program and # To create template1, we run the postgres (backend) program in bootstrap
# feed it data from the bki files that were installed. template0 is # mode and feed it data from the postgres.bki library file. After this
# made just by copying the completed template1. # initial bootstrap phase, some additional stuff is created by normal
# SQL commands fed to a standalone backend. Those commands are just
# embedded into this script (yeah, it's ugly).
#
# template0 is made just by copying the completed template1.
# #
# #
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # Portions Copyright (c) 1994, Regents of the University of California
# #
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.125 2001/05/12 01:48:49 petere Exp $ # $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.126 2001/06/12 05:55:50 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -338,11 +342,8 @@ fi
# Find the input files # Find the input files
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
TEMPLATE1_BKI="$datadir"/template1.bki POSTGRES_BKI="$datadir"/postgres.bki
GLOBAL_BKI="$datadir"/global.bki POSTGRES_DESCR="$datadir"/postgres.description
TEMPLATE1_DESCR="$datadir"/template1.description
GLOBAL_DESCR="$datadir"/global.description
PG_HBA_SAMPLE="$datadir"/pg_hba.conf.sample PG_HBA_SAMPLE="$datadir"/pg_hba.conf.sample
PG_IDENT_SAMPLE="$datadir"/pg_ident.conf.sample PG_IDENT_SAMPLE="$datadir"/pg_ident.conf.sample
@ -353,8 +354,8 @@ then
echo echo
echo "Initdb variables:" echo "Initdb variables:"
for var in PGDATA datadir PGPATH TEMPFILE MULTIBYTE MULTIBYTEID \ for var in PGDATA datadir PGPATH TEMPFILE MULTIBYTE MULTIBYTEID \
POSTGRES_SUPERUSERNAME POSTGRES_SUPERUSERID TEMPLATE1_BKI GLOBAL_BKI \ POSTGRES_SUPERUSERNAME POSTGRES_SUPERUSERID POSTGRES_BKI \
TEMPLATE1_DESCR GLOBAL_DESCR POSTGRESQL_CONF_SAMPLE \ POSTGRES_DESCR POSTGRESQL_CONF_SAMPLE \
PG_HBA_SAMPLE PG_IDENT_SAMPLE ; do PG_HBA_SAMPLE PG_IDENT_SAMPLE ; do
eval "echo ' '$var=\$$var" eval "echo ' '$var=\$$var"
done done
@ -364,8 +365,8 @@ if [ "$show_setting" = yes ] ; then
exit 0 exit 0
fi fi
for PREREQ_FILE in "$TEMPLATE1_BKI" "$GLOBAL_BKI" "$PG_HBA_SAMPLE" \ for PREREQ_FILE in "$POSTGRES_BKI" "$POSTGRES_DESCR" \
"$PG_IDENT_SAMPLE" "$PG_HBA_SAMPLE" "$PG_IDENT_SAMPLE" "$POSTGRESQL_CONF_SAMPLE"
do do
if [ ! -f "$PREREQ_FILE" ] ; then if [ ! -f "$PREREQ_FILE" ] ; then
( (
@ -377,7 +378,8 @@ do
fi fi
done done
for file in "$TEMPLATE1_BKI" "$GLOBAL_BKI"; do for file in "$POSTGRES_BKI"
do
if [ x"`sed 1q $file`" != x"# PostgreSQL $short_version" ]; then if [ x"`sed 1q $file`" != x"# PostgreSQL $short_version" ]; then
( (
echo "The input file '$file' needed by $CMDNAME does not" echo "The input file '$file' needed by $CMDNAME does not"
@ -445,7 +447,7 @@ fi
########################################################################## ##########################################################################
# #
# CREATE TEMPLATE1 DATABASE # RUN BKI SCRIPT IN BOOTSTRAP MODE TO CREATE TEMPLATE1
rm -rf "$PGDATA"/base/1 || exit_nicely rm -rf "$PGDATA"/base/1 || exit_nicely
mkdir "$PGDATA"/base/1 || exit_nicely mkdir "$PGDATA"/base/1 || exit_nicely
@ -455,35 +457,23 @@ then
BACKEND_TALK_ARG="-d" BACKEND_TALK_ARG="-d"
fi fi
BACKENDARGS="-boot -F -D$PGDATA $BACKEND_TALK_ARG"
FIRSTRUN="-boot -x1 -F -D$PGDATA $BACKEND_TALK_ARG" FIRSTRUN="-boot -x1 -F -D$PGDATA $BACKEND_TALK_ARG"
echo "Creating template1 database in $PGDATA/base/1" echo "Creating template1 database in $PGDATA/base/1"
[ "$debug" = yes ] && echo "Running: $PGPATH/postgres $FIRSTRUN template1" [ "$debug" = yes ] && echo "Running: $PGPATH/postgres $FIRSTRUN template1"
cat "$TEMPLATE1_BKI" \ cat "$POSTGRES_BKI" \
| sed -e "s/PGUID/$POSTGRES_SUPERUSERID/g" \ | sed -e "s/POSTGRES/$POSTGRES_SUPERUSERNAME/g" \
-e "s/PGUID/$POSTGRES_SUPERUSERID/g" \
-e "s/ENCODING/$MULTIBYTEID/g" \
| "$PGPATH"/postgres $FIRSTRUN template1 \ | "$PGPATH"/postgres $FIRSTRUN template1 \
|| exit_nicely || exit_nicely
echo $short_version > "$PGDATA"/base/1/PG_VERSION || exit_nicely echo $short_version > "$PGDATA"/base/1/PG_VERSION || exit_nicely
########################################################################## ##########################################################################
# #
# CREATE GLOBAL TABLES # CREATE CONFIG FILES
#
echo "Creating global relations in $PGDATA/global"
[ "$debug" = yes ] && echo "Running: $PGPATH/postgres $BACKENDARGS template1"
cat "$GLOBAL_BKI" \
| sed -e "s/POSTGRES/$POSTGRES_SUPERUSERNAME/g" \
-e "s/PGUID/$POSTGRES_SUPERUSERID/g" \
-e "s/ENCODING/$MULTIBYTEID/g" \
| "$PGPATH"/postgres $BACKENDARGS template1 \
|| exit_nicely
echo $short_version > "$PGDATA/PG_VERSION" || exit_nicely echo $short_version > "$PGDATA/PG_VERSION" || exit_nicely
@ -493,7 +483,6 @@ cp "$POSTGRESQL_CONF_SAMPLE" "$PGDATA"/postgresql.conf || exit_nicely
chmod 0600 "$PGDATA"/pg_hba.conf "$PGDATA"/pg_ident.conf \ chmod 0600 "$PGDATA"/pg_hba.conf "$PGDATA"/pg_ident.conf \
"$PGDATA"/postgresql.conf "$PGDATA"/postgresql.conf
########################################################################## ##########################################################################
# #
# CREATE VIEWS and other things # CREATE VIEWS and other things
@ -614,8 +603,7 @@ echo "CREATE VIEW pg_indexes AS \
echo "Loading pg_description." echo "Loading pg_description."
echo "COPY pg_description FROM STDIN" > $TEMPFILE echo "COPY pg_description FROM STDIN" > $TEMPFILE
cat "$TEMPLATE1_DESCR" >> $TEMPFILE cat "$POSTGRES_DESCR" >> $TEMPFILE
cat "$GLOBAL_DESCR" >> $TEMPFILE
cat $TEMPFILE \ cat $TEMPFILE \
| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely | "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: heapam.h,v 1.63 2001/03/22 04:00:27 momjian Exp $ * $Id: heapam.h,v 1.64 2001/06/12 05:55:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -234,7 +234,7 @@ extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor,
extern HeapTuple heap_modifytuple(HeapTuple tuple, extern HeapTuple heap_modifytuple(HeapTuple tuple,
Relation relation, Datum *replValue, char *replNull, char *repl); Relation relation, Datum *replValue, char *replNull, char *repl);
extern void heap_freetuple(HeapTuple tuple); extern void heap_freetuple(HeapTuple tuple);
HeapTuple heap_addheader(uint32 natts, int structlen, char *structure); extern HeapTuple heap_addheader(int natts, Size structlen, void *structure);
/* in common/heap/stats.c */ /* in common/heap/stats.c */
extern void PrintHeapAccessStatistics(HeapAccessStatistics stats); extern void PrintHeapAccessStatistics(HeapAccessStatistics stats);

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.81 2001/05/22 16:37:16 petere Exp $ * $Id: catversion.h,v 1.82 2001/06/12 05:55:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200105221 #define CATALOG_VERSION_NO 200106111
#endif #endif

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: indexing.h,v 1.49 2001/05/07 00:43:24 tgl Exp $ * $Id: indexing.h,v 1.50 2001/06/12 05:55:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -21,23 +21,24 @@
* Number of indices that exist for each system catalog * Number of indices that exist for each system catalog
*/ */
#define Num_pg_aggregate_indices 1 #define Num_pg_aggregate_indices 1
#define Num_pg_am_indices 1 #define Num_pg_am_indices 2
#define Num_pg_amop_indices 2 #define Num_pg_amop_indices 2
#define Num_pg_amproc_indices 1
#define Num_pg_attr_indices 2 #define Num_pg_attr_indices 2
#define Num_pg_attrdef_indices 1 #define Num_pg_attrdef_indices 1
#define Num_pg_class_indices 2 #define Num_pg_class_indices 2
#define Num_pg_database_indices 2
#define Num_pg_description_indices 1 #define Num_pg_description_indices 1
#define Num_pg_group_indices 2 #define Num_pg_group_indices 2
#define Num_pg_index_indices 2 #define Num_pg_index_indices 2
#define Num_pg_inherits_indices 1 #define Num_pg_inherits_indices 1
#define Num_pg_language_indices 2 #define Num_pg_language_indices 2
#define Num_pg_largeobject_indices 1 #define Num_pg_largeobject_indices 1
#define Num_pg_listener_indices 1 #define Num_pg_opclass_indices 3
#define Num_pg_opclass_indices 2
#define Num_pg_operator_indices 2 #define Num_pg_operator_indices 2
#define Num_pg_proc_indices 2 #define Num_pg_proc_indices 2
#define Num_pg_relcheck_indices 1 #define Num_pg_relcheck_indices 1
#define Num_pg_rewrite_indices 2 #define Num_pg_rewrite_indices 1
#define Num_pg_shadow_indices 2 #define Num_pg_shadow_indices 2
#define Num_pg_statistic_indices 1 #define Num_pg_statistic_indices 1
#define Num_pg_trigger_indices 3 #define Num_pg_trigger_indices 3
@ -48,13 +49,17 @@
*/ */
#define AccessMethodOpidIndex "pg_amop_opid_index" #define AccessMethodOpidIndex "pg_amop_opid_index"
#define AccessMethodStrategyIndex "pg_amop_strategy_index" #define AccessMethodStrategyIndex "pg_amop_strategy_index"
#define AccessProcedureIndex "pg_amproc_am_opcl_procnum_index"
#define AggregateNameTypeIndex "pg_aggregate_name_type_index" #define AggregateNameTypeIndex "pg_aggregate_name_type_index"
#define AmNameIndex "pg_am_name_index" #define AmNameIndex "pg_am_name_index"
#define AttrDefaultIndex "pg_attrdef_adrelid_index" #define AmOidIndex "pg_am_oid_index"
#define AttrDefaultIndex "pg_attrdef_adrelid_adnum_index"
#define AttributeRelidNameIndex "pg_attribute_relid_attnam_index" #define AttributeRelidNameIndex "pg_attribute_relid_attnam_index"
#define AttributeRelidNumIndex "pg_attribute_relid_attnum_index" #define AttributeRelidNumIndex "pg_attribute_relid_attnum_index"
#define ClassNameIndex "pg_class_relname_index" #define ClassNameIndex "pg_class_relname_index"
#define ClassOidIndex "pg_class_oid_index" #define ClassOidIndex "pg_class_oid_index"
#define DatabaseNameIndex "pg_database_datname_index"
#define DatabaseOidIndex "pg_database_oid_index"
#define DescriptionObjIndex "pg_description_objoid_index" #define DescriptionObjIndex "pg_description_objoid_index"
#define GroupNameIndex "pg_group_name_index" #define GroupNameIndex "pg_group_name_index"
#define GroupSysidIndex "pg_group_sysid_index" #define GroupSysidIndex "pg_group_sysid_index"
@ -64,18 +69,17 @@
#define LanguageNameIndex "pg_language_name_index" #define LanguageNameIndex "pg_language_name_index"
#define LanguageOidIndex "pg_language_oid_index" #define LanguageOidIndex "pg_language_oid_index"
#define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index" #define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index"
#define ListenerPidRelnameIndex "pg_listener_pid_relname_index"
#define OpclassDeftypeIndex "pg_opclass_deftype_index" #define OpclassDeftypeIndex "pg_opclass_deftype_index"
#define OpclassNameIndex "pg_opclass_name_index" #define OpclassNameIndex "pg_opclass_name_index"
#define OpclassOidIndex "pg_opclass_oid_index"
#define OperatorNameIndex "pg_operator_oprname_l_r_k_index" #define OperatorNameIndex "pg_operator_oprname_l_r_k_index"
#define OperatorOidIndex "pg_operator_oid_index" #define OperatorOidIndex "pg_operator_oid_index"
#define ProcedureNameIndex "pg_proc_proname_narg_type_index" #define ProcedureNameIndex "pg_proc_proname_narg_type_index"
#define ProcedureOidIndex "pg_proc_oid_index" #define ProcedureOidIndex "pg_proc_oid_index"
#define RelCheckIndex "pg_relcheck_rcrelid_index" #define RelCheckIndex "pg_relcheck_rcrelid_index"
#define RewriteOidIndex "pg_rewrite_oid_index"
#define RewriteRulenameIndex "pg_rewrite_rulename_index" #define RewriteRulenameIndex "pg_rewrite_rulename_index"
#define ShadowNameIndex "pg_shadow_name_index" #define ShadowNameIndex "pg_shadow_usename_index"
#define ShadowSysidIndex "pg_shadow_sysid_index" #define ShadowSysidIndex "pg_shadow_usesysid_index"
#define StatisticRelidAttnumIndex "pg_statistic_relid_att_index" #define StatisticRelidAttnumIndex "pg_statistic_relid_att_index"
#define TriggerConstrNameIndex "pg_trigger_tgconstrname_index" #define TriggerConstrNameIndex "pg_trigger_tgconstrname_index"
#define TriggerConstrRelidIndex "pg_trigger_tgconstrrelid_index" #define TriggerConstrRelidIndex "pg_trigger_tgconstrrelid_index"
@ -83,19 +87,21 @@
#define TypeNameIndex "pg_type_typname_index" #define TypeNameIndex "pg_type_typname_index"
#define TypeOidIndex "pg_type_oid_index" #define TypeOidIndex "pg_type_oid_index"
/* Arrays of names of indices for each system catalog */
extern char *Name_pg_aggregate_indices[]; extern char *Name_pg_aggregate_indices[];
extern char *Name_pg_am_indices[]; extern char *Name_pg_am_indices[];
extern char *Name_pg_amop_indices[]; extern char *Name_pg_amop_indices[];
extern char *Name_pg_amproc_indices[];
extern char *Name_pg_attr_indices[]; extern char *Name_pg_attr_indices[];
extern char *Name_pg_attrdef_indices[]; extern char *Name_pg_attrdef_indices[];
extern char *Name_pg_class_indices[]; extern char *Name_pg_class_indices[];
extern char *Name_pg_database_indices[];
extern char *Name_pg_description_indices[]; extern char *Name_pg_description_indices[];
extern char *Name_pg_group_indices[]; extern char *Name_pg_group_indices[];
extern char *Name_pg_index_indices[]; extern char *Name_pg_index_indices[];
extern char *Name_pg_inherits_indices[]; extern char *Name_pg_inherits_indices[];
extern char *Name_pg_language_indices[]; extern char *Name_pg_language_indices[];
extern char *Name_pg_largeobject_indices[]; extern char *Name_pg_largeobject_indices[];
extern char *Name_pg_listener_indices[];
extern char *Name_pg_opclass_indices[]; extern char *Name_pg_opclass_indices[];
extern char *Name_pg_operator_indices[]; extern char *Name_pg_operator_indices[];
extern char *Name_pg_proc_indices[]; extern char *Name_pg_proc_indices[];
@ -107,8 +113,6 @@ extern char *Name_pg_trigger_indices[];
extern char *Name_pg_type_indices[]; extern char *Name_pg_type_indices[];
extern char *IndexedCatalogNames[];
/* /*
* indexing.c prototypes * indexing.c prototypes
*/ */
@ -127,24 +131,36 @@ extern HeapTuple ClassNameIndexScan(Relation heapRelation, Datum relName);
extern HeapTuple ClassOidIndexScan(Relation heapRelation, Datum relId); extern HeapTuple ClassOidIndexScan(Relation heapRelation, Datum relId);
/*
* These macros are just to keep the C compiler from spitting up on the
* upcoming commands for genbki.sh.
*/
#define DECLARE_INDEX(x) extern int errno
#define DECLARE_UNIQUE_INDEX(x) extern int errno
#define BUILD_INDICES
/* /*
* What follows are lines processed by genbki.sh to create the statements * What follows are lines processed by genbki.sh to create the statements
* the bootstrap parser will turn into DefineIndex commands. * the bootstrap parser will turn into DefineIndex commands.
* *
* The keyword is DECLARE_INDEX every thing after that is just like in a * The keyword is DECLARE_INDEX or DECLARE_UNIQUE_INDEX. Everything after
* normal specification of the 'define index' POSTQUEL command. * that is just like in a normal 'create index' SQL command.
*/ */
DECLARE_UNIQUE_INDEX(pg_aggregate_name_type_index on pg_aggregate using btree(aggname name_ops, aggbasetype oid_ops)); DECLARE_UNIQUE_INDEX(pg_aggregate_name_type_index on pg_aggregate using btree(aggname name_ops, aggbasetype oid_ops));
DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops)); DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops));
DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_amop_opid_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_ops, amopid oid_ops)); DECLARE_UNIQUE_INDEX(pg_amop_opid_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_ops, amopid oid_ops));
DECLARE_UNIQUE_INDEX(pg_amop_strategy_index on pg_amop using btree(amopid oid_ops, amopclaid oid_ops, amopstrategy int2_ops)); DECLARE_UNIQUE_INDEX(pg_amop_strategy_index on pg_amop using btree(amopid oid_ops, amopclaid oid_ops, amopstrategy int2_ops));
/* This following index is not used for a cache and is not unique */ DECLARE_UNIQUE_INDEX(pg_amproc_am_opcl_procnum_index on pg_amproc using btree(amid oid_ops, amopclaid oid_ops, amprocnum int2_ops));
DECLARE_INDEX(pg_attrdef_adrelid_index on pg_attrdef using btree(adrelid oid_ops)); DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops));
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_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_UNIQUE_INDEX(pg_class_relname_index on pg_class using btree(relname name_ops));
DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops));
DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_description_objoid_index on pg_description using btree(objoid oid_ops)); DECLARE_UNIQUE_INDEX(pg_description_objoid_index on pg_description using btree(objoid oid_ops));
DECLARE_UNIQUE_INDEX(pg_group_name_index on pg_group using btree(groname name_ops)); DECLARE_UNIQUE_INDEX(pg_group_name_index on pg_group using btree(groname name_ops));
DECLARE_UNIQUE_INDEX(pg_group_sysid_index on pg_group using btree(grosysid int4_ops)); DECLARE_UNIQUE_INDEX(pg_group_sysid_index on pg_group using btree(grosysid int4_ops));
@ -155,22 +171,19 @@ DECLARE_UNIQUE_INDEX(pg_inherits_relid_seqno_index on pg_inherits using btree(in
DECLARE_UNIQUE_INDEX(pg_language_name_index on pg_language using btree(lanname name_ops)); DECLARE_UNIQUE_INDEX(pg_language_name_index on pg_language using btree(lanname name_ops));
DECLARE_UNIQUE_INDEX(pg_language_oid_index on pg_language using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_language_oid_index on pg_language using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_largeobject_loid_pn_index on pg_largeobject using btree(loid oid_ops, pageno int4_ops)); DECLARE_UNIQUE_INDEX(pg_largeobject_loid_pn_index on pg_largeobject using btree(loid oid_ops, pageno int4_ops));
DECLARE_UNIQUE_INDEX(pg_listener_pid_relname_index on pg_listener using btree(listenerpid int4_ops, relname name_ops));
/* This column needs to allow multiple zero entries, but is in the cache */ /* This column needs to allow multiple zero entries, but is in the cache */
DECLARE_INDEX(pg_opclass_deftype_index on pg_opclass using btree(opcdeftype oid_ops)); DECLARE_INDEX(pg_opclass_deftype_index on pg_opclass using btree(opcdeftype oid_ops));
DECLARE_UNIQUE_INDEX(pg_opclass_name_index on pg_opclass using btree(opcname name_ops)); DECLARE_UNIQUE_INDEX(pg_opclass_name_index on pg_opclass using btree(opcname name_ops));
DECLARE_UNIQUE_INDEX(pg_opclass_oid_index on pg_opclass using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_k_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprkind char_ops)); DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_k_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprkind char_ops));
DECLARE_UNIQUE_INDEX(pg_proc_oid_index on pg_proc using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_proc_oid_index on pg_proc using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_proc_proname_narg_type_index on pg_proc using btree(proname name_ops, pronargs int2_ops, proargtypes oidvector_ops)); DECLARE_UNIQUE_INDEX(pg_proc_proname_narg_type_index on pg_proc using btree(proname name_ops, pronargs int2_ops, proargtypes oidvector_ops));
/* This following index is not used for a cache and is not unique */ /* This following index is not used for a cache and is not unique */
DECLARE_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops)); DECLARE_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops));
DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_rewrite_rulename_index on pg_rewrite using btree(rulename name_ops)); DECLARE_UNIQUE_INDEX(pg_rewrite_rulename_index on pg_rewrite using btree(rulename name_ops));
/* DECLARE_UNIQUE_INDEX(pg_shadow_usename_index on pg_shadow using btree(usename name_ops));
xDECLARE_UNIQUE_INDEX(pg_shadow_name_index on pg_shadow using btree(usename name_ops)); DECLARE_UNIQUE_INDEX(pg_shadow_usesysid_index on pg_shadow using btree(usesysid int4_ops));
xDECLARE_UNIQUE_INDEX(pg_shadow_sysid_index on pg_shadow using btree(usesysid int4_ops));
*/
DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index on pg_statistic using btree(starelid oid_ops, staattnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));
DECLARE_INDEX(pg_trigger_tgconstrname_index on pg_trigger using btree(tgconstrname name_ops)); DECLARE_INDEX(pg_trigger_tgconstrname_index on pg_trigger using btree(tgconstrname name_ops));
DECLARE_INDEX(pg_trigger_tgconstrrelid_index on pg_trigger using btree(tgconstrrelid oid_ops)); DECLARE_INDEX(pg_trigger_tgconstrrelid_index on pg_trigger using btree(tgconstrrelid oid_ops));
@ -178,7 +191,7 @@ DECLARE_INDEX(pg_trigger_tgrelid_index on pg_trigger using btree(tgrelid oid_ops
DECLARE_UNIQUE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_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_UNIQUE_INDEX(pg_type_typname_index on pg_type using btree(typname name_ops));
/* now build indices in the initialization scripts */ /* last step of initialization script: build the indices declared above */
BUILD_INDICES BUILD_INDICES
#endif /* INDEXING_H */ #endif /* INDEXING_H */

View File

@ -27,7 +27,7 @@
* typedef struct FormData_pg_attrdef * typedef struct FormData_pg_attrdef
* ---------------- * ----------------
*/ */
CATALOG(pg_attrdef) BOOTSTRAP CATALOG(pg_attrdef)
{ {
Oid adrelid; Oid adrelid;
int2 adnum; int2 adnum;

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_attribute.h,v 1.72 2001/05/14 21:58:10 momjian Exp $ * $Id: pg_attribute.h,v 1.73 2001/06/12 05:55:50 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -213,6 +213,8 @@ typedef FormData_pg_attribute *Form_pg_attribute;
/* ---------------- /* ----------------
* initial contents of pg_attribute * initial contents of pg_attribute
*
* NOTE: only "bootstrapped" relations need to be declared here.
* ---------------- * ----------------
*/ */
@ -469,64 +471,6 @@ DATA(insert OID = 0 ( 1259 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1259 cmax 29 0 4 -6 0 -1 -1 t p f i f f)); DATA(insert OID = 0 ( 1259 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1259 tableoid 26 0 4 -7 0 -1 -1 t p f i f f)); DATA(insert OID = 0 ( 1259 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
/* ----------------
* pg_attrdef
* ----------------
*/
DATA(insert OID = 0 ( 1215 adrelid 26 0 4 1 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1215 adnum 21 0 2 2 0 -1 -1 t p f s f f));
DATA(insert OID = 0 ( 1215 adbin 25 0 -1 3 0 -1 -1 f x f i f f));
DATA(insert OID = 0 ( 1215 adsrc 25 0 -1 4 0 -1 -1 f x f i f f));
DATA(insert OID = 0 ( 1215 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert OID = 0 ( 1215 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1215 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1215 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1215 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1215 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1215 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
/* ----------------
* pg_relcheck
* ----------------
*/
DATA(insert OID = 0 ( 1216 rcrelid 26 0 4 1 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1216 rcname 19 0 NAMEDATALEN 2 0 -1 -1 f p f i f f));
DATA(insert OID = 0 ( 1216 rcbin 25 0 -1 3 0 -1 -1 f x f i f f));
DATA(insert OID = 0 ( 1216 rcsrc 25 0 -1 4 0 -1 -1 f x f i f f));
DATA(insert OID = 0 ( 1216 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert OID = 0 ( 1216 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1216 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1216 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1216 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1216 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1216 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
/* ----------------
* pg_trigger
* ----------------
*/
DATA(insert OID = 0 ( 1219 tgrelid 26 0 4 1 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 tgname 19 0 NAMEDATALEN 2 0 -1 -1 f p f i f f));
DATA(insert OID = 0 ( 1219 tgfoid 26 0 4 3 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 tgtype 21 0 2 4 0 -1 -1 t p f s f f));
DATA(insert OID = 0 ( 1219 tgenabled 16 0 1 5 0 -1 -1 t p f c f f));
DATA(insert OID = 0 ( 1219 tgisconstraint 16 0 1 6 0 -1 -1 t p f c f f));
DATA(insert OID = 0 ( 1219 tgconstrname 19 0 NAMEDATALEN 7 0 -1 -1 f p f i f f));
DATA(insert OID = 0 ( 1219 tgconstrrelid 26 0 4 8 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 tgdeferrable 16 0 1 9 0 -1 -1 t p f c f f));
DATA(insert OID = 0 ( 1219 tginitdeferred 16 0 1 10 0 -1 -1 t p f c f f));
DATA(insert OID = 0 ( 1219 tgnargs 21 0 2 11 0 -1 -1 t p f s f f));
DATA(insert OID = 0 ( 1219 tgattr 22 0 INDEX_MAX_KEYS*2 12 0 -1 -1 f p f i f f));
DATA(insert OID = 0 ( 1219 tgargs 17 0 -1 13 0 -1 -1 f x f i f f));
DATA(insert OID = 0 ( 1219 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert OID = 0 ( 1219 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert OID = 0 ( 1219 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
/* ---------------- /* ----------------
* pg_log - this relation is modified by special purpose access * pg_log - this relation is modified by special purpose access
* method code. The following is garbage but is needed * method code. The following is garbage but is needed

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_class.h,v 1.50 2001/05/30 14:40:13 momjian Exp $ * $Id: pg_class.h,v 1.51 2001/06/12 05:55:50 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -29,10 +29,6 @@
/* ---------------- /* ----------------
* pg_class definition. cpp turns this into * pg_class definition. cpp turns this into
* typedef struct FormData_pg_class * typedef struct FormData_pg_class
*
* Note: the #if 0, #endif around the BKI_BEGIN.. END block
* below keeps cpp from seeing what is meant for the
* genbki script
* ---------------- * ----------------
*/ */
@ -59,7 +55,6 @@ CATALOG(pg_class) BOOTSTRAP
bool relisshared; bool relisshared;
char relkind; char relkind;
int2 relnatts; int2 relnatts;
/* /*
* relnatts is the number of user attributes this class has. There * relnatts is the number of user attributes this class has. There
* must be exactly this many instances in Class pg_attribute for this * must be exactly this many instances in Class pg_attribute for this
@ -73,7 +68,6 @@ CATALOG(pg_class) BOOTSTRAP
bool relhaspkey; /* has PRIMARY KEY (not used) */ bool relhaspkey; /* has PRIMARY KEY (not used) */
bool relhasrules; /* has associated rules */ bool relhasrules; /* has associated rules */
bool relhassubclass; /* has derived classes */ bool relhassubclass; /* has derived classes */
/* /*
* relacl may or may not be present, see note above! * relacl may or may not be present, see note above!
*/ */
@ -129,6 +123,8 @@ typedef FormData_pg_class *Form_pg_class;
/* ---------------- /* ----------------
* initial contents of pg_class * initial contents of pg_class
*
* NOTE: only "bootstrapped" relations need to be declared here.
* ---------------- * ----------------
*/ */
@ -150,12 +146,6 @@ DATA(insert OID = 1269 ( pg_log 99 PGUID 0 1269 0 0 0 0 f t s 1 0 0 0 0 0 f
DESCR(""); 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 _null_ )); 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 _null_ ));
DESCR(""); DESCR("");
DATA(insert OID = 1215 ( pg_attrdef 109 PGUID 0 1215 0 0 0 0 t t r 4 0 0 0 0 0 f f f _null_ ));
DESCR("");
DATA(insert OID = 1216 ( pg_relcheck 110 PGUID 0 1216 0 0 0 0 t t r 4 0 0 0 0 0 f f f _null_ ));
DESCR("");
DATA(insert OID = 1219 ( pg_trigger 111 PGUID 0 1219 0 0 0 0 t t r 13 0 0 0 0 0 f f f _null_ ));
DESCR("");
#define RelOid_pg_type 1247 #define RelOid_pg_type 1247
#define RelOid_pg_attribute 1249 #define RelOid_pg_attribute 1249
@ -165,9 +155,6 @@ DESCR("");
#define RelOid_pg_group 1261 #define RelOid_pg_group 1261
#define RelOid_pg_database 1262 #define RelOid_pg_database 1262
#define RelOid_pg_log 1269 #define RelOid_pg_log 1269
#define RelOid_pg_attrdef 1215
#define RelOid_pg_relcheck 1216
#define RelOid_pg_trigger 1219
/* Xact lock pseudo-table */ /* Xact lock pseudo-table */
#define XactLockTableId 376 #define XactLockTableId 376

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_listener.h,v 1.8 2001/01/24 19:43:21 momjian Exp $ * $Id: pg_listener.h,v 1.9 2001/06/12 05:55:50 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -39,6 +39,13 @@ CATALOG(pg_listener)
int4 notification; int4 notification;
} FormData_pg_listener; } FormData_pg_listener;
/* ----------------
* Form_pg_listener corresponds to a pointer to a tuple with
* the format of pg_listener relation.
* ----------------
*/
typedef FormData_pg_listener *Form_pg_listener;
/* ---------------- /* ----------------
* compiler constants for pg_listener * compiler constants for pg_listener
* ---------------- * ----------------

View File

@ -27,7 +27,7 @@
* typedef struct FormData_pg_relcheck * typedef struct FormData_pg_relcheck
* ---------------- * ----------------
*/ */
CATALOG(pg_relcheck) BOOTSTRAP CATALOG(pg_relcheck)
{ {
Oid rcrelid; Oid rcrelid;
NameData rcname; NameData rcname;

View File

@ -27,7 +27,7 @@
* typedef struct FormData_pg_trigger * typedef struct FormData_pg_trigger
* ---------------- * ----------------
*/ */
CATALOG(pg_trigger) BOOTSTRAP CATALOG(pg_trigger)
{ {
Oid tgrelid; /* triggered relation */ Oid tgrelid; /* triggered relation */
NameData tgname; /* trigger' name */ NameData tgname; /* trigger' name */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_type.h,v 1.108 2001/06/09 21:41:42 tgl Exp $ * $Id: pg_type.h,v 1.109 2001/06/12 05:55:50 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -243,10 +243,6 @@ DATA(insert OID = 99 ( pg_log PGUID 4 4 t c t \054 1269 0 int4in int4out int4i
/* OIDS 100 - 199 */ /* OIDS 100 - 199 */
DATA(insert OID = 109 ( pg_attrdef PGUID 4 4 t c t \054 1215 0 int4in int4out int4in int4out i p _null_));
DATA(insert OID = 110 ( pg_relcheck PGUID 4 4 t c t \054 1216 0 int4in int4out int4in int4out i p _null_));
DATA(insert OID = 111 ( pg_trigger PGUID 4 4 t c t \054 1219 0 int4in int4out int4in int4out i p _null_));
/* OIDS 200 - 299 */ /* OIDS 200 - 299 */
DATA(insert OID = 210 ( smgr PGUID 2 12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p _null_ )); DATA(insert OID = 210 ( smgr PGUID 2 12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p _null_ ));

View File

@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1995, Regents of the University of California * Portions Copyright (c) 1995, Regents of the University of California
* *
* $Id: postgres.h,v 1.48 2001/03/23 18:26:01 tgl Exp $ * $Id: postgres.h,v 1.49 2001/06/12 05:55:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -569,18 +569,14 @@ extern int assertTest(int val);
* Section 4: genbki macros used by catalog/pg_xxx.h files * Section 4: genbki macros used by catalog/pg_xxx.h files
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
#define CATALOG(x) \ #define CATALOG(x) typedef struct CppConcat(FormData_,x)
typedef struct CppConcat(FormData_,x)
/* Huh? */
#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 #define BOOTSTRAP
/* these need to expand into some harmless, repeatable declaration */
#define DATA(x) extern int errno
#define DESCR(x) extern int errno
#define BKI_BEGIN #define BKI_BEGIN
#define BKI_END #define BKI_END

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: syscache.h,v 1.30 2001/05/07 00:43:26 tgl Exp $ * $Id: syscache.h,v 1.31 2001/06/12 05:55:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -42,20 +42,18 @@
#define INHRELID 11 #define INHRELID 11
#define LANGNAME 12 #define LANGNAME 12
#define LANGOID 13 #define LANGOID 13
#define LISTENREL 14 #define OPERNAME 14
#define OPERNAME 15 #define OPEROID 15
#define OPEROID 16 #define PROCNAME 16
#define PROCNAME 17 #define PROCOID 17
#define PROCOID 18 #define RELNAME 18
#define RELNAME 19 #define RELOID 19
#define RELOID 20 #define RULENAME 20
#define RULENAME 21 #define SHADOWNAME 21
#define RULEOID 22 #define SHADOWSYSID 22
#define SHADOWNAME 23 #define STATRELATT 23
#define SHADOWSYSID 24 #define TYPENAME 24
#define STATRELATT 25 #define TYPEOID 25
#define TYPENAME 26
#define TYPEOID 27
extern void InitCatalogCache(void); extern void InitCatalogCache(void);

View File

@ -480,8 +480,8 @@ WHERE p1.aggtransfn = p2.oid AND
(p2.pronargs = 1 AND p1.aggbasetype = 0))); (p2.pronargs = 1 AND p1.aggbasetype = 0)));
oid | aggname | oid | proname oid | aggname | oid | proname
-------+---------+-----+------------- -------+---------+-----+-------------
17009 | max | 768 | int4larger 16963 | max | 768 | int4larger
17023 | min | 769 | int4smaller 16977 | min | 769 | int4smaller
(2 rows) (2 rows)
-- Cross-check finalfn (if present) against its entry in pg_proc. -- Cross-check finalfn (if present) against its entry in pg_proc.

View File

@ -32,21 +32,23 @@ SELECT relname, relhasindex
pg_aggregate | t pg_aggregate | t
pg_am | t pg_am | t
pg_amop | t pg_amop | t
pg_amproc | t
pg_attrdef | t pg_attrdef | t
pg_attribute | t pg_attribute | t
pg_class | t pg_class | t
pg_database | t
pg_description | t pg_description | t
pg_group | t pg_group | t
pg_index | t pg_index | t
pg_inherits | t pg_inherits | t
pg_language | t pg_language | t
pg_largeobject | t pg_largeobject | t
pg_listener | t
pg_opclass | t pg_opclass | t
pg_operator | t pg_operator | t
pg_proc | t pg_proc | t
pg_relcheck | t pg_relcheck | t
pg_rewrite | t pg_rewrite | t
pg_shadow | t
pg_statistic | t pg_statistic | t
pg_trigger | t pg_trigger | t
pg_type | t pg_type | t
@ -55,5 +57,5 @@ SELECT relname, relhasindex
shighway | t shighway | t
tenk1 | t tenk1 | t
tenk2 | t tenk2 | t
(45 rows) (47 rows)