head	1.12;
access;
symbols
	Version_2_1:1.7
	C_Demo_1:1.3;
locks; strict;
comment	@ * @;


1.12
date	92.08.24.22.25.53;	author mao;	state Exp;
branches;
next	1.11;

1.11
date	92.07.31.00.45.23;	author mer;	state Exp;
branches;
next	1.10;

1.10
date	91.11.11.16.01.18;	author mer;	state Exp;
branches;
next	1.9;

1.9
date	91.08.30.06.42.40;	author kemnitz;	state Exp;
branches;
next	1.8;

1.8
date	91.08.30.06.38.28;	author kemnitz;	state Exp;
branches;
next	1.7;

1.7
date	91.03.01.10.25.59;	author mao;	state Exp;
branches;
next	1.6;

1.6
date	90.10.05.17.45.28;	author cimarron;	state Exp;
branches;
next	1.5;

1.5
date	90.09.25.16.50.45;	author kemnitz;	state Exp;
branches;
next	1.4;

1.4
date	90.06.07.18.21.10;	author cimarron;	state Exp;
branches;
next	1.3;

1.3
date	89.09.05.17.27.04;	author mao;	state C_Demo_1;
branches;
next	1.2;

1.2
date	89.02.02.17.08.25;	author aoki;	state Stab;
branches;
next	1.1;

1.1
date	89.01.17.05.58.47;	author cimarron;	state Exp;
branches;
next	;


desc
@@


1.12
log
@add bufpage.h to included files so that INVALIDDEBUG works again
@
text
@/* ----------------------------------------------------------------
 * inval.c --
 *	POSTGRES cache invalidation dispatcher code.
 *
 * Note - this code is real crufty...
 * ----------------------------------------------------------------
 */
#include "tmp/postgres.h"
#include "access/heapam.h"	/* XXX to support hacks below */
#include "access/htup.h"
#include "storage/bufpage.h"
#include "storage/buf.h"	/* XXX for InvalidBuffer */
#include "storage/ipci.h"
#include "storage/sinval.h"
#include "utils/catcache.h"
#include "utils/linval.h"
#include "utils/inval.h"
#include "utils/log.h"
#include "utils/rel.h"
#include "catalog/catname.h"	/* XXX to support hacks below */
#include "catalog/syscache.h"	/* XXX to support the hacks below */

RcsId("$Header: /private/mao/postgres/src/utils/cache/RCS/inval.c,v 1.11 1992/07/31 00:45:23 mer Exp $");
 
/* ----------------
 *	private invalidation structures
 * ----------------
 */
typedef struct CatalogInvalidationData {
	Index		cacheId;
	Index		hashIndex;
	ItemPointerData	pointerData;
} CatalogInvalidationData;
 
typedef struct RelationInvalidationData {
	ObjectId	relationId;
	ObjectId	objectId;
} RelationInvalidationData;
 
typedef union AnyInvalidation {
	CatalogInvalidationData		catalog;
	RelationInvalidationData	relation;
} AnyInvalidation;
 
typedef struct InvalidationMessageData {
	char		kind;
	AnyInvalidation	any;
} InvalidationMessageData;
 
typedef InvalidationMessageData	*InvalidationMessage;
 
/* ----------------
 *	variables and macros
 * ----------------
 */
static LocalInvalid Invalid = EmptyLocalInvalid;	/* XXX global */
static bool	RefreshWhenInvalidate = false;
 
ObjectId MyRelationRelationId = 	InvalidObjectId;
ObjectId MyAttributeRelationId = InvalidObjectId;
ObjectId MyAMRelationId = 	InvalidObjectId;
ObjectId MyAMOPRelationId = 	InvalidObjectId;
 
#define ValidateHacks() \
    if (!ObjectIdIsValid(MyRelationRelationId)) getmyrelids()

/* ----------------------------------------------------------------
 *		"local" invalidation support functions
 * ----------------------------------------------------------------
 */
 
/* --------------------------------
 *	InvalidationEntryAllocate
 * --------------------------------
 */
/**** xxref:
 *           CacheIdRegisterLocalInvalid
 *           RelationIdRegisterLocalInvalid
 ****/
InvalidationEntry
InvalidationEntryAllocate(size)
    uint16	size;
{
    InvalidationEntryData	*entryDataP;
    entryDataP = (InvalidationEntryData *)
	malloc(sizeof (char *) + size);	/* XXX alignment */
    entryDataP->nextP = NULL;
    return ((Pointer) &entryDataP->userData);
}
 
/* --------------------------------
 *	LocalInvalidRegister
 * --------------------------------
 */
/**** xxref:
 *           CacheIdRegisterLocalInvalid
 *           RelationIdRegisterLocalInvalid
 ****/
LocalInvalid
LocalInvalidRegister(invalid, entry)
    LocalInvalid	invalid;
    InvalidationEntry	entry;
{
    Assert(PointerIsValid(entry));
    
    ((InvalidationUserData *)entry)->dataP[-1] =
	(InvalidationUserData *)invalid;
    
    return (entry);
}
 
/* --------------------------------
 *	LocalInvalidInvalidate
 * --------------------------------
 */
/**** xxref:
 *           RegisterInvalid
 ****/
void
LocalInvalidInvalidate(invalid, function)
    LocalInvalid	invalid;
    void		(*function)();
{
    InvalidationEntryData	*entryDataP;
    
    while (PointerIsValid(invalid)) {
	entryDataP = (InvalidationEntryData *)
	    &((InvalidationUserData *)invalid)->dataP[-1];
	
	if (PointerIsValid(function)) {
	    (*function)((Pointer) &entryDataP->userData);
	}
	
	invalid = (Pointer) entryDataP->nextP;
	
	/* help catch errors */
	entryDataP->nextP = (InvalidationUserData *) NULL;
	
	free((Pointer)entryDataP);
    }
}
 
/* ----------------------------------------------------------------
 *		      private support functions
 * ----------------------------------------------------------------
 */
/* --------------------------------
 *	CacheIdRegisterLocalInvalid
 * --------------------------------
 */
#ifdef	INVALIDDEBUG
#define CacheIdRegisterLocalInvalid_DEBUG1 \
   elog(DEBUG, "CacheIdRegisterLocalInvalid(%d, %d, [%d, %d])", \
	cacheId, hashIndex, ItemPointerGetBlockNumber(pointer), \
	ItemPointerSimpleGetOffsetNumber(pointer))
#else
#define CacheIdRegisterLocalInvalid_DEBUG1
#endif	INVALIDDEBUG

/**** xxref:
 *           used as a pointer in RelationInvalidateHeapTuple
 ****/
static void
CacheIdRegisterLocalInvalid(cacheId, hashIndex, pointer)
    Index	cacheId;
    Index	hashIndex;
    ItemPointer	pointer;
{
    InvalidationMessage	message;
    
    /* ----------------
     *	debugging stuff
     * ----------------
     */
    CacheIdRegisterLocalInvalid_DEBUG1;
    
    /* ----------------
     *	create a message describing the system catalog tuple
     *  we wish to invalidate.
     * ----------------
     */
    message = (InvalidationMessage)
	InvalidationEntryAllocate(sizeof (InvalidationMessageData));
    
    message->kind = 'c';
    message->any.catalog.cacheId = cacheId;
    message->any.catalog.hashIndex = hashIndex;
    
    ItemPointerCopy(pointer, &message->any.catalog.pointerData);
    
    /* ----------------
     *	Note: Invalid is a global variable
     * ----------------
     */
    Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry)message);
}
 
/* --------------------------------
 *	RelationIdRegisterLocalInvalid
 * --------------------------------
 */
/**** xxref:
 *           used as a pointer in RelationInvalidateHeapTuple
 ****/
static void
RelationIdRegisterLocalInvalid(relationId, objectId)
    ObjectId	relationId;
    ObjectId	objectId;
{
    InvalidationMessage	message;
    
    /* ----------------
     *	debugging stuff
     * ----------------
     */
#ifdef	INVALIDDEBUG
    elog(DEBUG, "RelationRegisterLocalInvalid(%d, %d)", relationId,
	 objectId);
#endif	/* defined(INVALIDDEBUG) */
    
    /* ----------------
     *	create a message describing the relation descriptor
     *  we wish to invalidate.
     * ----------------
     */
    message = (InvalidationMessage)
	InvalidationEntryAllocate(sizeof (InvalidationMessageData));
    
    message->kind = 'r';
    message->any.relation.relationId = relationId;
    message->any.relation.objectId = objectId;
    
    /* ----------------
     *	Note: Invalid is a global variable
     * ----------------
     */
    Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry)message);
}
 
/* --------------------------------
 *	getmyrelids
 * --------------------------------
 */
void
getmyrelids()
{
    HeapTuple	tuple;
     
    tuple = SearchSysCacheTuple(RELNAME, RelationRelationName);
    Assert(HeapTupleIsValid(tuple));
    MyRelationRelationId = tuple->t_oid;
     
    tuple = SearchSysCacheTuple(RELNAME, AttributeRelationName);
    Assert(HeapTupleIsValid(tuple));
    MyAttributeRelationId = tuple->t_oid;
     
    tuple = SearchSysCacheTuple(RELNAME, AccessMethodRelationName);
    Assert(HeapTupleIsValid(tuple));
    MyAMRelationId = tuple->t_oid;
     
    tuple = SearchSysCacheTuple(RELNAME, AccessMethodOperatorRelationName);
    Assert(HeapTupleIsValid(tuple));
    MyAMOPRelationId = tuple->t_oid;
}
 
/* --------------------------------
 *	CacheIdInvalidate
 *
 *	This routine can invalidate an tuple in a system catalog cache
 *	or a cached relation descriptor.  You pay your money and you
 *	take your chances...
 * --------------------------------
 */
#ifdef	INVALIDDEBUG
#define CacheIdInvalidate_DEBUG1 \
   elog(DEBUG, "CacheIdInvalidate(%d, %d, 0x%x[%d])", cacheId, hashIndex,\
	pointer, ItemPointerIsValid(pointer))
#else
#define CacheIdInvalidate_DEBUG1
#endif	/* defined(INVALIDDEBUG) */
 
static void
CacheIdInvalidate(cacheId, hashIndex, pointer)
    Index	cacheId;
    Index	hashIndex;
    ItemPointer	pointer;
{
    InvalidationMessage	message;
     
    /* ----------------
     *	assume that if the item pointer is valid, then we are
     *  invalidating an item in the specified system catalog cache.
     * ----------------
     */
    if (ItemPointerIsValid(pointer)) {
	CatalogCacheIdInvalidate(cacheId, hashIndex, pointer);
	return;
    }
    
    CacheIdInvalidate_DEBUG1;
    
    ValidateHacks();	/* XXX */
     
    /* ----------------
     *	if the cacheId is the oid of any of the tuples in the
     *  following system relations, then assume we are invalidating
     *  a relation descriptor
     * ----------------
     */
    if (cacheId == MyRelationRelationId) {
	RelationIdInvalidateRelationCacheByRelationId(hashIndex);
	return;
    }
    
    if (cacheId == MyAttributeRelationId) {
	RelationIdInvalidateRelationCacheByRelationId(hashIndex);
	return;
    }
     
    if (cacheId == MyAMRelationId) {
	RelationIdInvalidateRelationCacheByAccessMethodId(hashIndex);
	return;
    }
    
    if (cacheId == MyAMOPRelationId) {
	RelationIdInvalidateRelationCacheByAccessMethodId(InvalidObjectId);
	return;
    }
     
    /* ----------------
     *	Yow! the caller asked us to invalidate something else.
     * ----------------
     */
    elog(FATAL, "CacheIdInvalidate: cacheId=%d relation id?", cacheId);
}
 
/* --------------------------------
 *	ResetSystemCaches
 *
 *	this blows away all tuples in the system catalog caches and
 *	all the cached relation descriptors (and closes the files too).
 * --------------------------------
 */
static void
ResetSystemCaches()
{
    ResetSystemCache();
    RelationCacheInvalidate(false); 
}
 
/* --------------------------------
 *	InvalidationMessageRegisterSharedInvalid
 * --------------------------------
 */
#ifdef	INVALIDDEBUG
#define InvalidationMessageRegisterSharedInvalid_DEBUG1 \
   elog(DEBUG,\
	"InvalidationMessageRegisterSharedInvalid(c, %d, %d, [%d, %d])",\
	message->any.catalog.cacheId,\
	message->any.catalog.hashIndex,\
	ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
	ItemPointerSimpleGetOffsetNumber(&message->any.catalog.pointerData))
#define InvalidationMessageRegisterSharedInvalid_DEBUG2 \
    elog(DEBUG, \
	 "InvalidationMessageRegisterSharedInvalid(r, %d, %d)", \
	 message->any.relation.relationId, \
	 message->any.relation.objectId)
#else    
#define InvalidationMessageRegisterSharedInvalid_DEBUG1
#define InvalidationMessageRegisterSharedInvalid_DEBUG2
#endif INVALIDDEBUG
 
/**** xxref:
 *           used as a pointer in RegisterInvalid
 ****/
static void
InvalidationMessageRegisterSharedInvalid(message)
    InvalidationMessage	message;
{
    Assert(PointerIsValid(message));
    
    switch (message->kind) {
    case 'c':	/* cached system catalog tuple */
	InvalidationMessageRegisterSharedInvalid_DEBUG1;
	
	RegisterSharedInvalid(message->any.catalog.cacheId,
			      message->any.catalog.hashIndex,
			      &message->any.catalog.pointerData);
	break;
	
    case 'r':   /* cached relation descriptor */
	InvalidationMessageRegisterSharedInvalid_DEBUG2;
	 
	RegisterSharedInvalid(message->any.relation.relationId,
			      message->any.relation.objectId,
			      (ItemPointer) NULL);
	break;
	
    default:
	elog(FATAL,
	     "InvalidationMessageRegisterSharedInvalid: `%c' kind",
	     message->kind);
    }
}
 
/* --------------------------------
 *	InvalidationMessageCacheInvalidate
 * --------------------------------
 */
#ifdef	INVALIDDEBUG
#define InvalidationMessageCacheInvalidate_DEBUG1 \
   elog(DEBUG, "InvalidationMessageCacheInvalidate(c, %d, %d, [%d, %d])",\
	message->any.catalog.cacheId,\
	message->any.catalog.hashIndex,\
	ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
	ItemPointerSimpleGetOffsetNumber(&message->any.catalog.pointerData))
#define InvalidationMessageCacheInvalidate_DEBUG2 \
   elog(DEBUG, "InvalidationMessageCacheInvalidate(r, %d, %d)", \
	message->any.relation.relationId, \
	message->any.relation.objectId)
#else
#define InvalidationMessageCacheInvalidate_DEBUG1
#define InvalidationMessageCacheInvalidate_DEBUG2
#endif	/* defined(INVALIDDEBUG) */
 
/**** xxref:
 *           used as a pointer in RegisterInvalid
 ****/
static void
InvalidationMessageCacheInvalidate(message)
    InvalidationMessage	message;
{
    Assert(PointerIsValid(message));
     
    switch (message->kind) {
    case 'c':  /* cached system catalog tuple */
	InvalidationMessageCacheInvalidate_DEBUG1;
	
	CatalogCacheIdInvalidate(message->any.catalog.cacheId,
				 message->any.catalog.hashIndex,
				 &message->any.catalog.pointerData);
	break;
	
    case 'r':  /* cached relation descriptor */
	InvalidationMessageCacheInvalidate_DEBUG2;
	
	/* XXX ignore this--is this correct ??? */
	break;
	
    default:
	elog(FATAL, "InvalidationMessageCacheInvalidate: `%c' kind",
	     message->kind);
    }
}
 
/* --------------------------------
 *	RelationInvalidateRelationCache
 * --------------------------------
 */
/**** xxref:
 *           RelationInvalidateHeapTuple
 ****/
static void
RelationInvalidateRelationCache(relation, tuple, function)
    Relation	relation;
    HeapTuple	tuple;
    void	(*function)();
{
    ObjectId	relationId;
    ObjectId	objectId;
     
    /* ----------------
     *	get the relation object id
     * ----------------
     */
    ValidateHacks();	/* XXX */
    relationId = RelationGetRelationId(relation);
     
    /* ----------------
     *	
     * ----------------
     */
    if (relationId == MyRelationRelationId) {
	objectId = tuple->t_oid;
    } else if (relationId == MyAttributeRelationId) {
	objectId = ((AttributeTupleForm)GETSTRUCT(tuple))->attrelid;
    } else if (relationId == MyAMRelationId) {
	objectId = tuple->t_oid;
    } else if (relationId == MyAMOPRelationId) {
	; /* objectId is unused */
    } else 
	return;
     
    /* ----------------
     *	  can't handle immediate relation descriptor invalidation
     * ----------------
     */
    Assert(PointerIsValid(function));
     
    (*function)(relationId, objectId);
}
 
/* --------------------------------
 *	DiscardInvalid
 * --------------------------------
 */
void
DiscardInvalid()
{
    /* ----------------
     *	debugging stuff
     * ----------------
     */
#ifdef	INVALIDDEBUG
    elog(DEBUG, "DiscardInvalid called");
#endif	/* defined(INVALIDDEBUG) */
     
    InvalidateSharedInvalid(CacheIdInvalidate, ResetSystemCaches);
}
 
/* --------------------------------
 *	RegisterInvalid
 * --------------------------------
 */
void
RegisterInvalid(send)
    bool	send;
{
    /* ----------------
     *	debugging stuff
     * ----------------
     */
#ifdef	INVALIDDEBUG
    elog(DEBUG, "RegisterInvalid(%d) called", send);
#endif	/* defined(INVALIDDEBUG) */
     
    /* ----------------
     *	Note: Invalid is a global variable
     * ----------------
     */
    if (send)
	LocalInvalidInvalidate(Invalid,
			       InvalidationMessageRegisterSharedInvalid);
    else
	LocalInvalidInvalidate(Invalid,
			       InvalidationMessageCacheInvalidate);
	
    Invalid = EmptyLocalInvalid;
}
 
/* --------------------------------
 *	SetRefreshWhenInvalidate
 * --------------------------------
 */
void
SetRefreshWhenInvalidate(on)
    bool	on;
{
#ifdef	INVALIDDEBUG
    elog(DEBUG, "RefreshWhenInvalidate(%d) called", on);
#endif	/* defined(INVALIDDEBUG) */
    
    RefreshWhenInvalidate = on;
}
 
/* --------------------------------
 *	RelationInvalidateHeapTuple
 * --------------------------------
 */
#ifdef	INVALIDDEBUG
#define RelationInvalidateHeapTuple_DEBUG1 \
    elog(DEBUG, "RelationInvalidateHeapTuple(%.16s, [%d,%d])", \
	 RelationGetRelationName(relation), \
	 ItemPointerGetBlockNumber(&tuple->t_ctid), \
	 ItemPointerSimpleGetOffsetNumber(&tuple->t_ctid))
#else
#define RelationInvalidateHeapTuple_DEBUG1
#endif	/* defined(INVALIDDEBUG) */
 
void
RelationInvalidateHeapTuple(relation, tuple)
    Relation	relation;
    HeapTuple	tuple;
{
    /* ----------------
     *	sanity checks
     * ----------------
     */
    Assert(RelationIsValid(relation));
    Assert(HeapTupleIsValid(tuple));

    if (IsBootstrapProcessingMode())
	return;
    /* ----------------
     *	this only works for system relations now
     * ----------------
     */
    if (! issystem(&RelationGetRelationTupleForm(relation)->relname))
	return;
     
    /* ----------------
     *	debugging stuff
     * ----------------
     */
    RelationInvalidateHeapTuple_DEBUG1;
     
    /* ----------------
     *	
     * ----------------
     */
    RelationInvalidateCatalogCacheTuple(relation,
					tuple,
					CacheIdRegisterLocalInvalid);
     
    RelationInvalidateRelationCache(relation,
				    tuple,
				    RelationIdRegisterLocalInvalid);
		
    if (RefreshWhenInvalidate)
	RelationInvalidateCatalogCacheTuple(relation,
					    tuple,
					    (void (*)()) NULL);
}

@


1.11
log
@don't invalidate during bootstrap
@
text
@d11 1
d23 1
a23 1
RcsId("$Header: /private/mer/pg/src/utils/cache/RCS/inval.c,v 1.10 1991/11/11 16:01:18 mer Exp mer $");
@


1.10
log
@prototying changes
@
text
@d22 1
a22 1
RcsId("$Header: /users/mer/postgres/src/utils/cache/RCS/inval.c,v 1.9 1991/08/30 06:42:40 kemnitz Exp $");
d590 3
a592 1
     
@


1.9
log
@oops - should be (char *) and not (* char)
@
text
@d15 1
a16 1
#include "utils/linval.h"
d22 1
a22 1
RcsId("$Header: RCS/inval.c,v 1.8 91/08/30 06:38:28 kemnitz Exp $");
d194 1
a194 1
    Invalid = LocalInvalidRegister(Invalid, message);
d236 1
a236 1
    Invalid = LocalInvalidRegister(Invalid, message);
@


1.8
log
@replaced "sizeof foo->next" when foo is nil with sizeof(pointer).
@
text
@d22 1
a22 1
RcsId("$Header: RCS/inval.c,v 1.7 91/03/01 10:25:59 mao Exp Locker: kemnitz $");
d85 1
a85 1
	malloc(sizeof (*char) + size);	/* XXX alignment */
@


1.7
log
@missing backslash in debugging delc
@
text
@d4 2
d22 1
a22 1
RcsId("$Header: RCS/inval.c,v 1.6 90/10/05 17:45:28 cimarron Exp Locker: mao $");
d85 1
a85 1
	malloc(sizeof entryDataP->nextP + size);	/* XXX alignment */
@


1.6
log
@cleaned up things so that index scans may be used with
system caches.
@
text
@d20 1
a20 1
RcsId("$Header: RCS/inval.c,v 1.5 90/09/25 16:50:45 kemnitz Exp Locker: cimarron $");
d360 1
a360 1
#define InvalidationMessageRegisterSharedInvalid_DEBUG2
@


1.5
log
@Updating from revision 1.4 to revision 1.6
@
text
@d1 1
a1 1
/*
d4 1
a5 1

a6 1

a16 1

d20 6
a25 2
RcsId("$Header: RCS/inval.c,v 1.6 90/08/15 08:35:40 cimarron Exp $");

d31 1
a31 1

d36 1
a36 1

d41 1
a41 1

d46 1
a46 1

d48 6
a53 3

static LocalInvalid	Invalid = EmptyLocalInvalid;	/* XXX global */

d55 6
a60 17

/* XXX hack */
ObjectId	MyRelationRelationId = InvalidObjectId;
ObjectId	MyAttributeRelationId = InvalidObjectId;
/* ObjectId	MyIndexRelationId = InvalidObjectId;	/* unneeded */
ObjectId	MyAMRelationId = InvalidObjectId;
ObjectId	MyAMOPRelationId = InvalidObjectId;

/*
 * getmyrelids -- XXX hack
 */
extern
void
getmyrelids ARGS((
	void
));

d62 1
a62 1
	if (!ObjectIdIsValid(MyRelationRelationId)) getmyrelids()
d64 3
a66 2
/*
 * CacheIdRegisterLocalInvalid --
d68 4
a71 10
static
void
CacheIdRegisterLocalInvalid ARGS((
	Index		cacheId,
	Index		hashIndex,
	ItemPointer	pointer
));

/*
 * CacheIdInvalidate --
d73 18
a90 10
static
void
CacheIdInvalidate ARGS((
	Index		cacheId,
	Index		hashIndex,
	ItemPointer	pointer
));

/*
 * ResetSystemCaches --
d92 20
a111 8
static
void
ResetSystemCaches ARGS((
	void
));

/*
 * InvalidationMessageRegisterSharedInvalid --
d113 3
a115 1
static
d117 26
a142 6
InvalidationMessageRegisterSharedInvalid ARGS((
	InvalidationMessage	message
));

/*
 * InvalidationMessageRegisterCacheInvalidate --
d144 3
a146 8
static
void
InvalidationMessageCacheInvalidate ARGS((
	InvalidationMessage	message
));

/*
 * RelationInvalidateRelationCache --
d148 8
a155 7
static
void
RelationInvalidateRelationCache ARGS((
	Relation	relation,
	HeapTuple	tuple,
	void		(*function)()
));
d157 41
a197 2
/*
 * RelationIdRegisterLocalInvalid --
d199 7
a205 9
static
void
RelationIdRegisterLocalInvalid ARGS((
	ObjectId	relationId,
	ObjectId	objectId
));

void
DiscardInvalid()
d207 6
d214 2
a215 1
	elog(DEBUG, "DiscardInvalid called");
d217 18
a234 2

	InvalidateSharedInvalid(CacheIdInvalidate, ResetSystemCaches);
d236 5
a240 1

d242 1
a242 2
RegisterInvalid(send)
	bool	send;
d244 27
d272 5
a276 1
	elog(DEBUG, "RegisterInvalid(%d) called", send);
d278 54
a331 9

	if (send) {
		LocalInvalidInvalidate(Invalid,
			InvalidationMessageRegisterSharedInvalid);
	} else {
		LocalInvalidInvalidate(Invalid,
			InvalidationMessageCacheInvalidate);
	}
	Invalid = EmptyLocalInvalid;
d333 10
a342 4

void
SetRefreshWhenInvalidate(on)
	bool	on;
d344 8
d353 48
a400 4
	elog(DEBUG, "RefreshWhenInvalidate(%d) called", on);
#endif	/* defined(INVALIDDEBUG) */

	RefreshWhenInvalidate = on;
d402 5
a406 10

void
RelationInvalidateHeapTuple(relation, tuple)
	Relation	relation;
	HeapTuple	tuple;
{
	Assert(RelationIsValid(relation));
	Assert(HeapTupleIsValid(tuple));

	if (issystem(&RelationGetRelationTupleForm(relation)->relname)) {
d408 13
a420 4
		elog(DEBUG, "RelationInvalidateHeapTuple(%.16s, [%d,%d])",
			RelationGetRelationName(relation),
			ItemPointerGetBlockNumber(&tuple->t_ctid),
			ItemPointerSimpleGetOffsetNumber(&tuple->t_ctid));
d422 29
a450 17

		RelationInvalidateCatalogCacheTuple(relation, tuple,
			CacheIdRegisterLocalInvalid);

		RelationInvalidateRelationCache(relation, tuple,
			RelationIdRegisterLocalInvalid);
		
		if (RefreshWhenInvalidate) {

			RelationInvalidateCatalogCacheTuple(relation, tuple,
				(void (*)())NULL);
/*
			RelationInvalidateRelationCache(relation, tuple,
				(void (*)())NULL);
*/
		}
	}
d452 13
a464 7

static
void
CacheIdRegisterLocalInvalid(cacheId, hashIndex, pointer)
	Index		cacheId;
	Index		hashIndex;
	ItemPointer	pointer;
d466 32
a497 17
	InvalidationMessage	message;

#ifdef	INVALIDDEBUG
	elog(DEBUG, "CacheIdRegisterLocalInvalid(%d, %d, [%d, %d])",
		cacheId, hashIndex, ItemPointerGetBlockNumber(pointer),
		ItemPointerSimpleGetOffsetNumber(pointer));
#endif	/* defined(INVALIDDEBUG) */

	message = (InvalidationMessage)
		InvalidationEntryAllocate(sizeof (InvalidationMessageData));

	message->kind = 'c';
	message->any.catalog.cacheId = cacheId;
	message->any.catalog.hashIndex = hashIndex;
	ItemPointerCopy(pointer, &message->any.catalog.pointerData);

	Invalid = LocalInvalidRegister(Invalid, message);
d499 5
a503 2

static
d505 1
a505 4
CacheIdInvalidate(cacheId, hashIndex, pointer)
	Index		cacheId;
	Index		hashIndex;
	ItemPointer	pointer;
d507 4
a510 2
	InvalidationMessage	message;

d512 1
a512 2
	elog(DEBUG, "CacheIdInvalidate(%d, %d, 0x%x[%d])", cacheId, hashIndex,
		pointer, ItemPointerIsValid(pointer));
d514 2
a515 23

	if (ItemPointerIsValid(pointer)) {
		CatalogCacheIdInvalidate(cacheId, hashIndex, pointer);
	} else {
		ValidateHacks();	/* XXX */

		if (cacheId == MyRelationRelationId) {
			RelationIdInvalidateRelationCacheByRelationId(
				hashIndex);
		} else if (cacheId == MyAttributeRelationId) {
			RelationIdInvalidateRelationCacheByRelationId(
				hashIndex);
		} else if (cacheId == MyAMRelationId) {
			RelationIdInvalidateRelationCacheByAccessMethodId(
				hashIndex);
		} else if (cacheId == MyAMOPRelationId) {
			RelationIdInvalidateRelationCacheByAccessMethodId(
				InvalidObjectId);
		} else {
			elog(FATAL, "CacheIdInvalidate: %d relation id?",
				cacheId);
		}
	}
d517 5
a521 2

static
d523 2
a524 1
ResetSystemCaches()
d526 4
a529 14
	ResetSystemCache();

	RelationCacheInvalidate(false);
}

static
void
InvalidationMessageRegisterSharedInvalid(message)
	InvalidationMessage	message;
{
	Assert(PointerIsValid(message));

	switch (message->kind) {
	case 'c':
d531 1
a531 7
		elog(DEBUG, "InvalidationMessageRegisterSharedInvalid(c, %d, %d, [%d, %d])",
			message->any.catalog.cacheId,
			message->any.catalog.hashIndex,
			ItemPointerGetBlockNumber(
				&message->any.catalog.pointerData),
			ItemPointerSimpleGetOffsetNumber(
				&message->any.catalog.pointerData));
d533 13
a545 21

		RegisterSharedInvalid(message->any.catalog.cacheId,
			message->any.catalog.hashIndex,
			&message->any.catalog.pointerData);
		break;
	case 'r':
#ifdef	INVALIDDEBUG
		elog(DEBUG,
			"InvalidationMessageRegisterSharedInvalid(r, %d, %d)",
			message->any.relation.relationId,
			message->any.relation.objectId);
#endif	/* defined(INVALIDDEBUG) */

		RegisterSharedInvalid(message->any.relation.relationId,
			message->any.relation.objectId, (ItemPointer)NULL);
		break;
	default:
		elog(FATAL,
			"InvalidationMessageRegisterSharedInvalid: `%c' kind",
			message->kind);
	}
d547 5
a551 2

static
d553 2
a554 2
InvalidationMessageCacheInvalidate(message)
	InvalidationMessage	message;
a555 4
	Assert(PointerIsValid(message));

	switch (message->kind) {
	case 'c':
d557 1
a557 7
		elog(DEBUG, "InvalidationMessageCacheInvalidate(c, %d, %d, [%d, %d])",
			message->any.catalog.cacheId,
			message->any.catalog.hashIndex,
			ItemPointerGetBlockNumber(
				&message->any.catalog.pointerData),
			ItemPointerSimpleGetOffsetNumber(
				&message->any.catalog.pointerData));
d559 8
a566 6

		CatalogCacheIdInvalidate(message->any.catalog.cacheId,
			message->any.catalog.hashIndex,
			&message->any.catalog.pointerData);
		break;
	case 'r':
d568 7
a574 3
		elog(DEBUG, "InvalidationMessageCacheInvalidate(r, %d, %d)",
			message->any.relation.relationId,
			message->any.relation.objectId);
d576 1
a576 9

		/* XXX ignore this--is this correct ??? */
		break;
	default:
		elog(FATAL, "InvalidationMessageCacheInvalidate: `%c' kind",
			message->kind);
	}
}

d578 3
a580 1
getmyrelids()
d582 36
a617 17
	HeapTuple	tuple;

	tuple = SearchSysCacheTuple(RELNAME, RelationRelationName);
	Assert(HeapTupleIsValid(tuple));
	MyRelationRelationId = tuple->t_oid;

	tuple = SearchSysCacheTuple(RELNAME, AttributeRelationName);
	Assert(HeapTupleIsValid(tuple));
	MyAttributeRelationId = tuple->t_oid;

	tuple = SearchSysCacheTuple(RELNAME, AccessMethodRelationName);
	Assert(HeapTupleIsValid(tuple));
	MyAMRelationId = tuple->t_oid;

	tuple = SearchSysCacheTuple(RELNAME, AccessMethodOperatorRelationName);
	Assert(HeapTupleIsValid(tuple));
	MyAMOPRelationId = tuple->t_oid;
a619 54
static
void
RelationInvalidateRelationCache(relation, tuple, function)
	Relation	relation;
	HeapTuple	tuple;
	void		(*function)();
{
	ObjectId	relationId;
	ObjectId	objectId;

	ValidateHacks();	/* XXX */

	relationId = RelationGetRelationId(relation);

	if (relationId == MyRelationRelationId) {
		objectId = tuple->t_oid;
	} else if (relationId == MyAttributeRelationId) {
		objectId = ((AttributeTupleForm)GETSTRUCT(tuple))->attrelid;
	} else if (relationId == MyAMRelationId) {
		objectId = tuple->t_oid;
	} else if (relationId == MyAMOPRelationId) {
		;	/* objectId is unused */
	} else {
		return;
	}

	/* can't handle immediate relation descriptor invalidation */
	Assert(PointerIsValid(function));

	(*function)(relationId, objectId);
}

static
void
RelationIdRegisterLocalInvalid(relationId, objectId)
	ObjectId	relationId;
	ObjectId	objectId;
{
	InvalidationMessage	message;

#ifdef	INVALIDDEBUG
	elog(DEBUG, "RelationRegisterLocalInvalid(%d, %d)", relationId,
		objectId);
#endif	/* defined(INVALIDDEBUG) */

	message = (InvalidationMessage)
		InvalidationEntryAllocate(sizeof (InvalidationMessageData));

	message->kind = 'r';
	message->any.relation.relationId = relationId;
	message->any.relation.objectId = objectId;

	Invalid = LocalInvalidRegister(Invalid, message);
}
@


1.4
log
@made changes to simplify header include files
@
text
@d6 1
a6 1
#include "c.h"
d8 10
a17 13
#include "buf.h"	/* XXX for InvalidBuffer */
#include "cat.h"	/* XXX to support hacks below */
#include "catcache.h"
#include "catname.h"	/* XXX to support hacks below */
#include "heapam.h"	/* XXX to support hacks below */
#include "htup.h"
#include "ipci.h"
#include "linval.h"
#include "log.h"
#include "oid.h"
#include "rel.h"
#include "sinval.h"
#include "syscache.h"	/* XXX to support the hacks below */
d19 2
a20 1
#include "inval.h"
d22 1
a22 1
RcsId("$Header: RCS/inval.c,v 1.3 89/09/05 17:27:04 mao C_Demo_1 $");
@


1.3
log
@Working version of C-only demo
@
text
@a18 1
#include "tuple.h"	/* XXX for GETSTRUCT */
d24 1
a24 1
RcsId("$Header: /usr6/postgres/mao/postgres/src/utils/cache/RCS/inval.c,v 1.2 89/02/02 17:08:25 aoki Stab $");
@


1.2
log
@MERGE WITH OLD TREE
@
text
@d25 1
a25 1
RcsId("$Header: inval.c,v 1.5 88/08/30 20:30:12 aoki Locked $");
@


1.1
log
@Initial revision
@
text
@a0 1

a1 26
 * 
 * POSTGRES Data Base Management System
 * 
 * Copyright (c) 1988 Regents of the University of California
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for educational, research, and non-profit purposes and
 * without fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation, and that
 * the name of the University of California not be used in advertising
 * or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Permission to incorporate this
 * software into commercial products can be obtained from the Campus
 * Software Office, 295 Evans Hall, University of California, Berkeley,
 * Ca., 94720 provided only that the the requestor give the University
 * of California a free licence to any derived software for educational
 * and research purposes.  The University of California makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 * 
 */



/*
d25 1
a25 1
RcsId("$Header: inval.c,v 1.1 88/11/11 16:42:18 postgres Exp $");
@
