Commit a152ebee authored by Tom Lane's avatar Tom Lane

Fix problems seen in parallel regress tests when SI buffer overruns (causing

syscache and relcache flushes).  Relcache entry rebuild now preserves
original tupledesc, rewrite rules, and triggers if possible, so that pointers
to these things remain valid --- if these things change while relcache entry
has positive refcount, we elog(ERROR) to avoid later crash.  Arrange for
xact-local rels to be rebuilt when an SI inval message is seen for them,
so that they are updated by CommandCounterIncrement the same as regular rels.
(This is useful because of Hiroshi's recent changes to process our own SI
messages at CommandCounterIncrement time.)  This allows simplification of
some routines that previously hacked around the lack of an automatic update.
catcache now keeps its own copy of tupledesc for its relation, rather than
depending on the relcache's copy; this avoids needing to reinitialize catcache
during a cache flush, which saves some cycles and eliminates nasty circularity
problems that occur if a cache flush happens while trying to initialize a
catcache.
Eliminate a number of permanent memory leaks that used to happen during
catcache or relcache flush; not least of which was that catcache never
freed any cached tuples!  (Rule parsetree storage is still leaked, however;
will fix that separately.)
Nothing done yet about code that uses tuples retrieved by SearchSysCache
for longer than is safe.
parent ca0f1435
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.60 2000/01/26 05:55:53 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.61 2000/01/31 04:35:48 tgl Exp $
* *
* NOTES * NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be * some of the executor utility code such as "ExecTypeFromTL" should be
...@@ -226,6 +226,71 @@ FreeTupleDesc(TupleDesc tupdesc) ...@@ -226,6 +226,71 @@ FreeTupleDesc(TupleDesc tupdesc)
} }
bool
equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
{
int i;
if (tupdesc1->natts != tupdesc2->natts)
return false;
for (i = 0; i < tupdesc1->natts; i++)
{
Form_pg_attribute attr1 = tupdesc1->attrs[i];
Form_pg_attribute attr2 = tupdesc2->attrs[i];
/* We do not need to check every single field here, and in fact
* some fields such as attdisbursion probably shouldn't be compared.
*/
if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
return false;
if (attr1->atttypid != attr2->atttypid)
return false;
if (attr1->atttypmod != attr2->atttypmod)
return false;
if (attr1->attstorage != attr2->attstorage)
return false;
if (attr1->attnotnull != attr2->attnotnull)
return false;
}
if (tupdesc1->constr != NULL)
{
TupleConstr *constr1 = tupdesc1->constr;
TupleConstr *constr2 = tupdesc2->constr;
if (constr2 == NULL)
return false;
if (constr1->num_defval != constr2->num_defval)
return false;
for (i = 0; i < (int) constr1->num_defval; i++)
{
AttrDefault *defval1 = constr1->defval + i;
AttrDefault *defval2 = constr2->defval + i;
if (defval1->adnum != defval2->adnum)
return false;
if (strcmp(defval1->adbin, defval2->adbin) != 0)
return false;
}
if (constr1->num_check != constr2->num_check)
return false;
for (i = 0; i < (int) constr1->num_check; i++)
{
ConstrCheck *check1 = constr1->check + i;
ConstrCheck *check2 = constr2->check + i;
if (strcmp(check1->ccname, check2->ccname) != 0)
return false;
if (strcmp(check1->ccbin, check2->ccbin) != 0)
return false;
}
if (constr1->has_not_null != constr2->has_not_null)
return false;
}
else if (tupdesc2->constr != NULL)
return false;
return true;
}
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* TupleDescInitEntry * TupleDescInitEntry
* *
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.119 2000/01/26 05:56:10 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.120 2000/01/31 04:35:48 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -2098,18 +2098,6 @@ AddRelationRawConstraints(Relation rel, ...@@ -2098,18 +2098,6 @@ AddRelationRawConstraints(Relation rel,
heap_close(relrel, RowExclusiveLock); heap_close(relrel, RowExclusiveLock);
heap_freetuple(reltup); heap_freetuple(reltup);
/*
* Force rebuild of our own relcache entry, otherwise subsequent commands
* in this transaction won't see the new defaults/constraints.
* Must bump command counter or relcache rebuild won't see 'em either.
*
* (This might seem unnecessary, since we are sending out an SI message;
* but if the relation has just been created then relcache.c will ignore
* the SI message on the grounds that the rel is transaction-local...)
*/
CommandCounterIncrement();
RelationRebuildRelation(rel);
} }
static void static void
......
This diff is collapsed.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/lib/Attic/hasht.c,v 1.12 2000/01/26 05:56:26 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/lib/Attic/hasht.c,v 1.13 2000/01/31 04:35:51 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -22,14 +22,14 @@ ...@@ -22,14 +22,14 @@
* HashTableWalk * HashTableWalk
* *
* call function on every element in hashtable * call function on every element in hashtable
* one extra argument, arg may be supplied * one extra argument (arg) may be supplied
* ----------------------------------- * -----------------------------------
*/ */
void void
HashTableWalk(HTAB *hashtable, HashtFunc function, int arg) HashTableWalk(HTAB *hashtable, HashtFunc function, int arg)
{ {
long *hashent; long *hashent;
long *data; void *data;
int keysize; int keysize;
keysize = hashtable->hctl->keysize; keysize = hashtable->hctl->keysize;
...@@ -43,7 +43,7 @@ HashTableWalk(HTAB *hashtable, HashtFunc function, int arg) ...@@ -43,7 +43,7 @@ HashTableWalk(HTAB *hashtable, HashtFunc function, int arg)
* XXX the corresponding hash table insertion does NOT LONGALIGN * XXX the corresponding hash table insertion does NOT LONGALIGN
* -- make sure the keysize is ok * -- make sure the keysize is ok
*/ */
data = (long *) LONGALIGN((char *) hashent + keysize); data = (void *) LONGALIGN((char *) hashent + keysize);
(*function) (data, arg); (*function) (data, arg);
} }
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.58 2000/01/26 05:57:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.59 2000/01/31 04:35:51 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -35,9 +35,6 @@ static long comphash(long l, char *v); ...@@ -35,9 +35,6 @@ static long comphash(long l, char *v);
/* ---------------- /* ----------------
* variables, macros and other stuff * variables, macros and other stuff
*
* note CCSIZE allocates 51 buckets .. one was already allocated in
* the catcache structure.
* ---------------- * ----------------
*/ */
...@@ -64,17 +61,20 @@ GlobalMemory CacheCxt; /* context in which caches are allocated */ ...@@ -64,17 +61,20 @@ GlobalMemory CacheCxt; /* context in which caches are allocated */
/* ---------------- /* ----------------
* EQPROC is used in CatalogCacheInitializeCache * EQPROC is used in CatalogCacheInitializeCache to find the equality
* XXX this should be replaced by catalog lookups soon * functions for system types that are used as cache key fields.
*
* XXX this should be replaced by catalog lookups,
* but that seems to pose considerable risk of circularity...
* ---------------- * ----------------
*/ */
static long eqproc[] = { static const Oid eqproc[] = {
F_BOOLEQ, 0l, F_CHAREQ, F_NAMEEQ, 0l, F_BOOLEQ, InvalidOid, F_CHAREQ, F_NAMEEQ, InvalidOid,
F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, 0l, F_TEXTEQ, F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, F_OIDEQ, F_TEXTEQ,
F_OIDEQ, 0l, 0l, 0l, F_OIDVECTOREQ F_OIDEQ, InvalidOid, InvalidOid, InvalidOid, F_OIDVECTOREQ
}; };
#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-16] #define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-BOOLOID]
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* internal support functions * internal support functions
...@@ -169,12 +169,13 @@ CatalogCacheInitializeCache(struct catcache * cache, ...@@ -169,12 +169,13 @@ CatalogCacheInitializeCache(struct catcache * cache,
} }
/* ---------------- /* ----------------
* initialize the cache's relation id * initialize the cache's relation id and tuple descriptor
* ---------------- * ----------------
*/ */
Assert(RelationIsValid(relation)); Assert(RelationIsValid(relation));
cache->relationId = RelationGetRelid(relation); cache->relationId = RelationGetRelid(relation);
tupdesc = cache->cc_tupdesc = RelationGetDescr(relation); tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
cache->cc_tupdesc = tupdesc;
CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %u, %d keys", CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %u, %d keys",
cache->relationId, cache->cc_nkeys); cache->relationId, cache->cc_nkeys);
...@@ -254,22 +255,6 @@ CatalogCacheInitializeCache(struct catcache * cache, ...@@ -254,22 +255,6 @@ CatalogCacheInitializeCache(struct catcache * cache,
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
} }
/* --------------------------------
* CatalogCacheSetId
*
* XXX temporary function
* --------------------------------
*/
#ifdef NOT_USED
void
CatalogCacheSetId(CatCache *cacheInOutP, int id)
{
Assert(id == InvalidCatalogCacheId || id >= 0);
cacheInOutP->id = id;
}
#endif
/* ---------------- /* ----------------
* comphash * comphash
* Compute a hash value, somehow. * Compute a hash value, somehow.
...@@ -369,10 +354,12 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP, ...@@ -369,10 +354,12 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
Relation relation, Relation relation,
HeapTuple tuple) HeapTuple tuple)
{ {
bool isNull = '\0'; bool isNull = false;
/* XXX is this really needed? */
if (cacheInOutP->relationId == InvalidOid) if (cacheInOutP->relationId == InvalidOid)
CatalogCacheInitializeCache(cacheInOutP, relation); CatalogCacheInitializeCache(cacheInOutP, relation);
switch (cacheInOutP->cc_nkeys) switch (cacheInOutP->cc_nkeys)
{ {
case 4: case 4:
...@@ -417,8 +404,7 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP, ...@@ -417,8 +404,7 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
break; break;
default: default:
elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys", elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys",
cacheInOutP->cc_nkeys cacheInOutP->cc_nkeys);
);
break; break;
} }
...@@ -427,6 +413,8 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP, ...@@ -427,6 +413,8 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
/* -------------------------------- /* --------------------------------
* CatCacheRemoveCTup * CatCacheRemoveCTup
*
* NB: assumes caller has switched to CacheCxt
* -------------------------------- * --------------------------------
*/ */
static void static void
...@@ -436,19 +424,24 @@ CatCacheRemoveCTup(CatCache *cache, Dlelem *elt) ...@@ -436,19 +424,24 @@ CatCacheRemoveCTup(CatCache *cache, Dlelem *elt)
CatCTup *other_ct; CatCTup *other_ct;
Dlelem *other_elt; Dlelem *other_elt;
if (elt) if (!elt) /* probably-useless safety check */
ct = (CatCTup *) DLE_VAL(elt);
else
return; return;
/* We need to zap both linked-list elements as well as the tuple */
ct = (CatCTup *) DLE_VAL(elt);
other_elt = ct->ct_node; other_elt = ct->ct_node;
other_ct = (CatCTup *) DLE_VAL(other_elt); other_ct = (CatCTup *) DLE_VAL(other_elt);
heap_freetuple(ct->ct_tup);
DLRemove(other_elt); DLRemove(other_elt);
DLFreeElem(other_elt); DLFreeElem(other_elt);
free(other_ct); pfree(other_ct);
DLRemove(elt); DLRemove(elt);
DLFreeElem(elt); DLFreeElem(elt);
free(ct); pfree(ct);
--cache->cc_ntup; --cache->cc_ntup;
} }
...@@ -529,7 +522,6 @@ CatalogCacheIdInvalidate(int cacheId, /* XXX */ ...@@ -529,7 +522,6 @@ CatalogCacheIdInvalidate(int cacheId, /* XXX */
* ---------------- * ----------------
*/ */
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
/* sendpm('I', "Invalidated tuple"); */
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
...@@ -615,34 +607,26 @@ ResetSystemCache() ...@@ -615,34 +607,26 @@ ResetSystemCache()
* *
* A special case occurs when relId is itself one of the cacheable system * A special case occurs when relId is itself one of the cacheable system
* tables --- although those'll never be dropped, they can get flushed from * tables --- although those'll never be dropped, they can get flushed from
* the relcache (VACUUM causes this, for example). In that case we need to * the relcache (VACUUM causes this, for example). In that case we need
* force the next SearchSysCache() call to reinitialize the cache itself, * to flush all cache entries from that table. The brute-force method
* because we have info (such as cc_tupdesc) that is pointing at the about- * currently used takes care of that quite handily. (At one point we
* to-be-deleted relcache entry. * also tried to force re-execution of CatalogCacheInitializeCache for
* the cache(s) on that table. This is a bad idea since it leads to all
* kinds of trouble if a cache flush occurs while loading cache entries.
* We now avoid the need to do it by copying cc_tupdesc out of the relcache,
* rather than relying on the relcache to keep a tupdesc for us. Of course
* this assumes the tupdesc of a cachable system table will not change...)
* -------------------------------- * --------------------------------
*/ */
void void
SystemCacheRelationFlushed(Oid relId) SystemCacheRelationFlushed(Oid relId)
{ {
struct catcache *cache;
/* /*
* XXX Ideally we'd search the caches and just zap entries that actually * XXX Ideally we'd search the caches and just zap entries that actually
* refer to the indicated relation. For now, we take the brute-force * refer to or come from the indicated relation. For now, we take the
* approach: just flush the caches entirely. * brute-force approach: just flush the caches entirely.
*/ */
ResetSystemCache(); ResetSystemCache();
/*
* If relcache is dropping a system relation's cache entry, mark the
* associated cache structures invalid, so we can rebuild them from
* scratch (not just repopulate them) next time they are used.
*/
for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next)
{
if (cache->relationId == relId)
cache->relationId = InvalidOid;
}
} }
/* -------------------------------- /* --------------------------------
...@@ -715,11 +699,11 @@ InitSysCache(char *relname, ...@@ -715,11 +699,11 @@ InitSysCache(char *relname,
{ {
/* /*
* We can only do this optimization because the number of hash * We can only do this optimization because the number of hash
* buckets never changes. Without it, we call malloc() too much. * buckets never changes. Without it, we call palloc() too much.
* We could move this to dllist.c, but the way we do this is not * We could move this to dllist.c, but the way we do this is not
* dynamic/portabl, so why allow other routines to use it. * dynamic/portable, so why allow other routines to use it.
*/ */
Dllist *cache_begin = malloc((NCCBUCK + 1) * sizeof(Dllist)); Dllist *cache_begin = palloc((NCCBUCK + 1) * sizeof(Dllist));
for (i = 0; i <= NCCBUCK; ++i) for (i = 0; i <= NCCBUCK; ++i)
{ {
...@@ -927,7 +911,7 @@ SearchSysCache(struct catcache * cache, ...@@ -927,7 +911,7 @@ SearchSysCache(struct catcache * cache,
MemoryContext oldcxt; MemoryContext oldcxt;
/* ---------------- /* ----------------
* sanity checks * one-time startup overhead
* ---------------- * ----------------
*/ */
if (cache->relationId == InvalidOid) if (cache->relationId == InvalidOid)
...@@ -946,7 +930,7 @@ SearchSysCache(struct catcache * cache, ...@@ -946,7 +930,7 @@ SearchSysCache(struct catcache * cache,
* resolve self referencing informtion * resolve self referencing informtion
*/ */
if ((ntp = SearchSelfReferences(cache))) if ((ntp = SearchSelfReferences(cache)))
return heap_copytuple(ntp); return ntp;
/* ---------------- /* ----------------
* find the hash bucket in which to look for the tuple * find the hash bucket in which to look for the tuple
...@@ -995,10 +979,8 @@ SearchSysCache(struct catcache * cache, ...@@ -995,10 +979,8 @@ SearchSysCache(struct catcache * cache,
DLMoveToFront(elt); DLMoveToFront(elt);
#ifdef CACHEDEBUG #ifdef CACHEDEBUG
relation = heap_open(cache->relationId, NoLock);
CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d", CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d",
RelationGetRelationName(relation), hash); cache->cc_relname, hash);
heap_close(relation, NoLock);
#endif /* CACHEDEBUG */ #endif /* CACHEDEBUG */
return ct->ct_tup; return ct->ct_tup;
...@@ -1020,9 +1002,7 @@ SearchSysCache(struct catcache * cache, ...@@ -1020,9 +1002,7 @@ SearchSysCache(struct catcache * cache,
*/ */
if (cache->busy) if (cache->busy)
{
elog(ERROR, "SearchSysCache: recursive use of cache %d", cache->id); elog(ERROR, "SearchSysCache: recursive use of cache %d", cache->id);
}
cache->busy = true; cache->busy = true;
/* ---------------- /* ----------------
...@@ -1140,10 +1120,10 @@ SearchSysCache(struct catcache * cache, ...@@ -1140,10 +1120,10 @@ SearchSysCache(struct catcache * cache,
* it easier to remove something from both the cache bucket and * it easier to remove something from both the cache bucket and
* the lru list at the same time * the lru list at the same time
*/ */
nct = (CatCTup *) malloc(sizeof(CatCTup)); nct = (CatCTup *) palloc(sizeof(CatCTup));
nct->ct_tup = ntp; nct->ct_tup = ntp;
elt = DLNewElem(nct); elt = DLNewElem(nct);
nct2 = (CatCTup *) malloc(sizeof(CatCTup)); nct2 = (CatCTup *) palloc(sizeof(CatCTup));
nct2->ct_tup = ntp; nct2->ct_tup = ntp;
lru_elt = DLNewElem(nct2); lru_elt = DLNewElem(nct2);
nct2->ct_node = elt; nct2->ct_node = elt;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.33 2000/01/29 19:51:59 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.34 2000/01/31 04:35:52 tgl Exp $
* *
* Note - this code is real crufty... * Note - this code is real crufty...
* *
...@@ -557,7 +557,7 @@ static void ...@@ -557,7 +557,7 @@ static void
ResetSystemCaches() ResetSystemCaches()
{ {
ResetSystemCache(); ResetSystemCache();
RelationCacheInvalidate(true); RelationCacheInvalidate();
} }
/* -------------------------------- /* --------------------------------
......
...@@ -8,11 +8,10 @@ ...@@ -8,11 +8,10 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/rel.c,v 1.7 2000/01/26 05:57:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/rel.c,v 1.8 2000/01/31 04:35:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
/* #define RELREFDEBUG 1 */
#include "postgres.h" #include "postgres.h"
#include "access/istrat.h" #include "access/istrat.h"
...@@ -21,45 +20,22 @@ ...@@ -21,45 +20,22 @@
/* /*
* RelationIsValid is now a macro in rel.h -cim 4/27/91 * RelationIsValid is now a macro in rel.h -cim 4/27/91
* *
* Many of the RelationGet...() functions are now macros in rel.h * All of the RelationGet...() functions are now macros in rel.h
* -mer 3/2/92 * -mer 3/2/92
*/ */
/*
* RelationGetIndexStrategy
* Returns index strategy for a relation.
*
* Note:
* Assumes relation descriptor is valid.
* Assumes relation descriptor is for an index relation.
*/
IndexStrategy
RelationGetIndexStrategy(Relation relation)
{
return relation->rd_istrat;
}
/* /*
* RelationSetIndexSupport * RelationSetIndexSupport
* Sets index strategy and support info for a relation. * Sets index strategy and support info for a relation.
* *
* This routine saves two pointers -- one to the IndexStrategy, and
* one to the RegProcs that support the indexed access method.
*
* Note: * Note:
* Assumes relation descriptor is a valid pointer to sufficient space. * Assumes relation descriptor is valid.
* Assumes index strategy is valid. Assumes support is valid if non- * Assumes index strategy is valid. Assumes support is valid if non-
* NULL. * NULL.
*/ */
/* ----------------
* RelationSetIndexSupport
*
* This routine saves two pointers -- one to the IndexStrategy, and
* one to the RegProcs that support the indexed access method. These
* pointers are stored in the space following the attribute data in the
* reldesc.
*
* NEW: the index strategy and support are now stored in real fields
* at the end of the structure - jolly
* ----------------
*/
void void
RelationSetIndexSupport(Relation relation, RelationSetIndexSupport(Relation relation,
IndexStrategy strategy, IndexStrategy strategy,
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.23 2000/01/26 05:57:30 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.24 2000/01/31 04:35:53 tgl Exp $
* *
* NOTE: * NOTE:
* This is a new (Feb. 05, 1999) implementation of the allocation set * This is a new (Feb. 05, 1999) implementation of the allocation set
...@@ -389,6 +389,11 @@ AllocSetFree(AllocSet set, AllocPointer pointer) ...@@ -389,6 +389,11 @@ AllocSetFree(AllocSet set, AllocPointer pointer)
chunk = AllocPointerGetChunk(pointer); chunk = AllocPointerGetChunk(pointer);
#ifdef CLOBBER_FREED_MEMORY
/* Wipe freed memory for debugging purposes */
memset(pointer, 0x7F, chunk->size);
#endif
if (chunk->size >= ALLOC_BIGCHUNK_LIMIT) if (chunk->size >= ALLOC_BIGCHUNK_LIMIT)
{ {
/* Big chunks are certain to have been allocated as single-chunk /* Big chunks are certain to have been allocated as single-chunk
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.33 2000/01/26 05:57:31 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.34 2000/01/31 04:35:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -468,7 +468,7 @@ CollectNamedPortals(Portal *portalP, int destroy) ...@@ -468,7 +468,7 @@ CollectNamedPortals(Portal *portalP, int destroy)
void void
AtEOXact_portals() AtEOXact_portals()
{ {
HashTableWalk(PortalHashTable, CollectNamedPortals, 0); HashTableWalk(PortalHashTable, (HashtFunc) CollectNamedPortals, 0);
CollectNamedPortals(NULL, 1); CollectNamedPortals(NULL, 1);
} }
...@@ -478,7 +478,7 @@ AtEOXact_portals() ...@@ -478,7 +478,7 @@ AtEOXact_portals()
*/ */
#ifdef NOT_USED #ifdef NOT_USED
static void static void
PortalDump(Portal *thisP) PortalDump(Portal *thisP, int dummy)
{ {
/* XXX state/argument checking here */ /* XXX state/argument checking here */
...@@ -498,7 +498,7 @@ DumpPortals() ...@@ -498,7 +498,7 @@ DumpPortals()
{ {
/* XXX state checking here */ /* XXX state checking here */
HashTableWalk(PortalHashTable, PortalDump, 0); HashTableWalk(PortalHashTable, (HashtFunc) PortalDump, 0);
} }
#endif #endif
...@@ -556,7 +556,7 @@ EnablePortalManager(bool on) ...@@ -556,7 +556,7 @@ EnablePortalManager(bool on)
/* /*
* Each portal must free its non-memory resources specially. * Each portal must free its non-memory resources specially.
*/ */
HashTableWalk(PortalHashTable, PortalDrop, 0); HashTableWalk(PortalHashTable, (HashtFunc) PortalDrop, 0);
hash_destroy(PortalHashTable); hash_destroy(PortalHashTable);
PortalHashTable = NULL; PortalHashTable = NULL;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: tupdesc.h,v 1.26 2000/01/26 05:57:51 momjian Exp $ * $Id: tupdesc.h,v 1.27 2000/01/31 04:35:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -47,8 +47,7 @@ typedef struct tupleConstr ...@@ -47,8 +47,7 @@ typedef struct tupleConstr
*/ */
typedef struct tupleDesc typedef struct tupleDesc
{ {
int natts; int natts; /* Number of attributes in the tuple */
/* Number of attributes in the tuple */
Form_pg_attribute *attrs; Form_pg_attribute *attrs;
/* attrs[N] is a pointer to the description of Attribute Number N+1. */ /* attrs[N] is a pointer to the description of Attribute Number N+1. */
TupleConstr *constr; TupleConstr *constr;
...@@ -64,6 +63,8 @@ extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc); ...@@ -64,6 +63,8 @@ extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);
extern void FreeTupleDesc(TupleDesc tupdesc); extern void FreeTupleDesc(TupleDesc tupdesc);
extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
extern bool TupleDescInitEntry(TupleDesc desc, extern bool TupleDescInitEntry(TupleDesc desc,
AttrNumber attributeNumber, AttrNumber attributeNumber,
char *attributeName, char *attributeName,
......
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
* trigger.h * trigger.h
* prototypes for trigger.c. * prototypes for trigger.c.
* *
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: trigger.h,v 1.18 2000/01/31 04:35:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -70,6 +74,12 @@ extern void CreateTrigger(CreateTrigStmt *stmt); ...@@ -70,6 +74,12 @@ extern void CreateTrigger(CreateTrigStmt *stmt);
extern void DropTrigger(DropTrigStmt *stmt); extern void DropTrigger(DropTrigStmt *stmt);
extern void RelationRemoveTriggers(Relation rel); extern void RelationRemoveTriggers(Relation rel);
extern void RelationBuildTriggers(Relation relation);
extern void FreeTriggerDesc(TriggerDesc *trigdesc);
extern bool equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2);
extern HeapTuple ExecBRInsertTriggers(Relation rel, HeapTuple tuple); extern HeapTuple ExecBRInsertTriggers(Relation rel, HeapTuple tuple);
extern void ExecARInsertTriggers(Relation rel, HeapTuple tuple); extern void ExecARInsertTriggers(Relation rel, HeapTuple tuple);
extern bool ExecBRDeleteTriggers(EState *estate, ItemPointer tupleid); extern bool ExecBRDeleteTriggers(EState *estate, ItemPointer tupleid);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: hasht.h,v 1.9 2000/01/26 05:58:09 momjian Exp $ * $Id: hasht.h,v 1.10 2000/01/31 04:35:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "utils/hsearch.h" #include "utils/hsearch.h"
typedef void (*HashtFunc) (); typedef void (*HashtFunc) (void *hashitem, int arg);
extern void HashTableWalk(HTAB *hashtable, HashtFunc function, int arg); extern void HashTableWalk(HTAB *hashtable, HashtFunc function, int arg);
......
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* rel.h * rel.h
* POSTGRES relation descriptor definitions. * POSTGRES relation descriptor (a/k/a relcache entry) definitions.
* *
* *
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: rel.h,v 1.33 2000/01/26 05:58:38 momjian Exp $ * $Id: rel.h,v 1.34 2000/01/31 04:35:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#include "rewrite/prs2lock.h" #include "rewrite/prs2lock.h"
#include "storage/fd.h" #include "storage/fd.h"
/* added to prevent circular dependency. bjm 1999/11/15 */
extern char *get_temp_rel_by_physicalname(const char *relname);
/* /*
* LockRelId and LockInfo really belong to lmgr.h, but it's more convenient * LockRelId and LockInfo really belong to lmgr.h, but it's more convenient
* to declare them here so we can have a LockInfoData field in a Relation. * to declare them here so we can have a LockInfoData field in a Relation.
...@@ -39,6 +42,10 @@ typedef struct LockInfoData ...@@ -39,6 +42,10 @@ typedef struct LockInfoData
typedef LockInfoData *LockInfo; typedef LockInfoData *LockInfo;
/*
* Likewise, this struct really belongs to trigger.h, but for convenience
* we put it here.
*/
typedef struct Trigger typedef struct Trigger
{ {
...@@ -58,6 +65,7 @@ typedef struct Trigger ...@@ -58,6 +65,7 @@ typedef struct Trigger
typedef struct TriggerDesc typedef struct TriggerDesc
{ {
/* index data to identify which triggers are which */
uint16 n_before_statement[4]; uint16 n_before_statement[4];
uint16 n_before_row[4]; uint16 n_before_row[4];
uint16 n_after_row[4]; uint16 n_after_row[4];
...@@ -66,9 +74,14 @@ typedef struct TriggerDesc ...@@ -66,9 +74,14 @@ typedef struct TriggerDesc
Trigger **tg_before_row[4]; Trigger **tg_before_row[4];
Trigger **tg_after_row[4]; Trigger **tg_after_row[4];
Trigger **tg_after_statement[4]; Trigger **tg_after_statement[4];
/* the actual array of triggers is here */
Trigger *triggers; Trigger *triggers;
int numtriggers;
} TriggerDesc; } TriggerDesc;
/*
* Here are the contents of a relation cache entry.
*/
typedef struct RelationData typedef struct RelationData
{ {
...@@ -87,7 +100,7 @@ typedef struct RelationData ...@@ -87,7 +100,7 @@ typedef struct RelationData
RuleLock *rd_rules; /* rewrite rules */ RuleLock *rd_rules; /* rewrite rules */
IndexStrategy rd_istrat; IndexStrategy rd_istrat;
RegProcedure *rd_support; RegProcedure *rd_support;
TriggerDesc *trigdesc; TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */
} RelationData; } RelationData;
typedef RelationData *Relation; typedef RelationData *Relation;
...@@ -110,15 +123,6 @@ typedef Relation *RelationPtr; ...@@ -110,15 +123,6 @@ typedef Relation *RelationPtr;
#define InvalidRelation ((Relation) NULL) #define InvalidRelation ((Relation) NULL)
/*
* RelationGetSystemPort
* Returns system port of a relation.
*
* Note:
* Assumes relation descriptor is valid.
*/
#define RelationGetSystemPort(relation) ((relation)->rd_fd)
/* /*
* RelationHasReferenceCountZero * RelationHasReferenceCountZero
* True iff relation reference count is zero. * True iff relation reference count is zero.
...@@ -149,7 +153,7 @@ typedef Relation *RelationPtr; ...@@ -149,7 +153,7 @@ typedef Relation *RelationPtr;
/* /*
* RelationGetForm * RelationGetForm
* Returns relation attribute values for a relation. * Returns pg_class tuple for a relation.
* *
* Note: * Note:
* Assumes relation descriptor is valid. * Assumes relation descriptor is valid.
...@@ -159,15 +163,14 @@ typedef Relation *RelationPtr; ...@@ -159,15 +163,14 @@ typedef Relation *RelationPtr;
/* /*
* RelationGetRelid * RelationGetRelid
* *
* returns the object id of the relation * returns the OID of the relation
*
*/ */
#define RelationGetRelid(relation) ((relation)->rd_id) #define RelationGetRelid(relation) ((relation)->rd_id)
/* /*
* RelationGetFile * RelationGetFile
* *
* Returns the open File decscriptor * Returns the open file descriptor for the rel
*/ */
#define RelationGetFile(relation) ((relation)->rd_fd) #define RelationGetFile(relation) ((relation)->rd_fd)
...@@ -176,8 +179,6 @@ typedef Relation *RelationPtr; ...@@ -176,8 +179,6 @@ typedef Relation *RelationPtr;
* *
* Returns a Relation Name * Returns a Relation Name
*/ */
/* added to prevent circular dependency. bjm 1999/11/15 */
char *get_temp_rel_by_physicalname(const char *relname);
#define RelationGetRelationName(relation) \ #define RelationGetRelationName(relation) \
(\ (\
(strncmp(RelationGetPhysicalRelationName(relation), \ (strncmp(RelationGetPhysicalRelationName(relation), \
...@@ -210,10 +211,19 @@ char *get_temp_rel_by_physicalname(const char *relname); ...@@ -210,10 +211,19 @@ char *get_temp_rel_by_physicalname(const char *relname);
*/ */
#define RelationGetDescr(relation) ((relation)->rd_att) #define RelationGetDescr(relation) ((relation)->rd_att)
/*
* RelationGetIndexStrategy
* Returns index strategy for a relation.
*
* Note:
* Assumes relation descriptor is valid.
* Assumes relation descriptor is for an index relation.
*/
#define RelationGetIndexStrategy(relation) ((relation)->rd_istrat)
extern IndexStrategy RelationGetIndexStrategy(Relation relation);
extern void RelationSetIndexSupport(Relation relation, IndexStrategy strategy, extern void RelationSetIndexSupport(Relation relation,
IndexStrategy strategy,
RegProcedure *support); RegProcedure *support);
#endif /* REL_H */ #endif /* REL_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: relcache.h,v 1.18 2000/01/26 05:58:38 momjian Exp $ * $Id: relcache.h,v 1.19 2000/01/31 04:35:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,11 +29,9 @@ extern void RelationForgetRelation(Oid rid); ...@@ -29,11 +29,9 @@ extern void RelationForgetRelation(Oid rid);
/* /*
* Routines for flushing/rebuilding relcache entries in various scenarios * Routines for flushing/rebuilding relcache entries in various scenarios
*/ */
extern void RelationRebuildRelation(Relation relation);
extern void RelationIdInvalidateRelationCacheByRelationId(Oid relationId); extern void RelationIdInvalidateRelationCacheByRelationId(Oid relationId);
extern void RelationCacheInvalidate(bool onlyFlushReferenceCountZero); extern void RelationCacheInvalidate(void);
extern void RelationRegisterRelation(Relation relation); extern void RelationRegisterRelation(Relation relation);
extern void RelationPurgeLocalRelation(bool xactComitted); extern void RelationPurgeLocalRelation(bool xactComitted);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment