aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r--src/backend/utils/cache/catcache.c1786
-rw-r--r--src/backend/utils/cache/fcache.c481
-rw-r--r--src/backend/utils/cache/inval.c840
-rw-r--r--src/backend/utils/cache/lsyscache.c618
-rw-r--r--src/backend/utils/cache/rel.c57
-rw-r--r--src/backend/utils/cache/relcache.c3493
-rw-r--r--src/backend/utils/cache/syscache.c1057
7 files changed, 4279 insertions, 4053 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index aee835943e3..3edddd3c1aa 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* catcache.c--
- * System catalog cache for tuples matching a key.
+ * System catalog cache for tuples matching a key.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.10 1997/08/26 19:24:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.11 1997/09/07 04:52:56 momjian Exp $
*
* Notes:
- * XXX This needs to use exception.h to handle recovery when
- * an abort occurs during DisableCache.
- *
+ * XXX This needs to use exception.h to handle recovery when
+ * an abort occurs during DisableCache.
+ *
*-------------------------------------------------------------------------
*/
#include <string.h>
@@ -26,7 +26,7 @@
#include "miscadmin.h"
#include "utils/portal.h"
#include "utils/catcache.h"
-#include "fmgr.h" /* for F_BOOLEQ, etc. DANGER */
+#include "fmgr.h" /* for F_BOOLEQ, etc. DANGER */
#include "utils/elog.h"
#include "utils/palloc.h"
#include "utils/mcxt.h"
@@ -34,29 +34,31 @@
#include "catalog/pg_type.h" /* for OID of int28 type */
#include "lib/dllist.h"
-static void CatCacheRemoveCTup(CatCache *cache, Dlelem *e);
-static Index CatalogCacheComputeHashIndex(struct catcache *cacheInP);
-static Index CatalogCacheComputeTupleHashIndex(struct catcache *cacheInOutP,
- Relation relation, HeapTuple tuple);
-static void CatalogCacheInitializeCache(struct catcache *cache,
- Relation relation);
-static long comphash(long l, char *v);
+static void CatCacheRemoveCTup(CatCache * cache, Dlelem * e);
+static Index CatalogCacheComputeHashIndex(struct catcache * cacheInP);
+static Index
+CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
+ Relation relation, HeapTuple tuple);
+static void
+CatalogCacheInitializeCache(struct catcache * cache,
+ Relation relation);
+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.
+ * note CCSIZE allocates 51 buckets .. one was already allocated in
+ * the catcache structure.
* ----------------
*/
#ifdef CACHEDEBUG
-#define CACHE1_elog(a,b) elog(a,b)
-#define CACHE2_elog(a,b,c) elog(a,b,c)
-#define CACHE3_elog(a,b,c,d) elog(a,b,c,d)
-#define CACHE4_elog(a,b,c,d,e) elog(a,b,c,d,e)
-#define CACHE5_elog(a,b,c,d,e,f) elog(a,b,c,d,e,f)
-#define CACHE6_elog(a,b,c,d,e,f,g) elog(a,b,c,d,e,f,g)
+#define CACHE1_elog(a,b) elog(a,b)
+#define CACHE2_elog(a,b,c) elog(a,b,c)
+#define CACHE3_elog(a,b,c,d) elog(a,b,c,d)
+#define CACHE4_elog(a,b,c,d,e) elog(a,b,c,d,e)
+#define CACHE5_elog(a,b,c,d,e,f) elog(a,b,c,d,e,f)
+#define CACHE6_elog(a,b,c,d,e,f,g) elog(a,b,c,d,e,f,g)
#else
#define CACHE1_elog(a,b)
#define CACHE2_elog(a,b,c)
@@ -66,209 +68,217 @@ static long comphash(long l, char *v);
#define CACHE6_elog(a,b,c,d,e,f,g)
#endif
-CatCache *Caches = NULL;
+CatCache *Caches = NULL;
GlobalMemory CacheCxt;
-static int DisableCache;
+static int DisableCache;
/* ----------------
- * EQPROC is used in CatalogCacheInitializeCache
- * XXX this should be replaced by catalog lookups soon
+ * EQPROC is used in CatalogCacheInitializeCache
+ * XXX this should be replaced by catalog lookups soon
* ----------------
*/
-static long eqproc[] = {
- F_BOOLEQ, 0l, F_CHAREQ, F_CHAR16EQ, 0l,
- F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, 0l, F_TEXTEQ,
- F_OIDEQ, 0l, 0l, 0l, F_OID8EQ
+static long eqproc[] = {
+ F_BOOLEQ, 0l, F_CHAREQ, F_CHAR16EQ, 0l,
+ F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, 0l, F_TEXTEQ,
+ F_OIDEQ, 0l, 0l, 0l, F_OID8EQ
};
-#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-16]
+#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-16]
/* ----------------------------------------------------------------
- * internal support functions
+ * internal support functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * CatalogCacheInitializeCache
+ * CatalogCacheInitializeCache
* --------------------------------
*/
#ifdef CACHEDEBUG
#define CatalogCacheInitializeCache_DEBUG1 \
- elog(DEBUG, "CatalogCacheInitializeCache: cache @%08lx", cache); \
- if (relation) \
- elog(DEBUG, "CatalogCacheInitializeCache: called w/relation(inval)"); \
- else \
- elog(DEBUG, "CatalogCacheInitializeCache: called w/relname %s", \
- cache->cc_relname)
+ elog(DEBUG, "CatalogCacheInitializeCache: cache @%08lx", cache); \
+ if (relation) \
+ elog(DEBUG, "CatalogCacheInitializeCache: called w/relation(inval)"); \
+ else \
+ elog(DEBUG, "CatalogCacheInitializeCache: called w/relname %s", \
+ cache->cc_relname)
#define CatalogCacheInitializeCache_DEBUG2 \
- if (cache->cc_key[i] > 0) { \
- elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d, %d", \
- i+1, cache->cc_nkeys, cache->cc_key[i], \
- relation->rd_att->attrs[cache->cc_key[i] - 1]->attlen); \
- } else { \
- elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d", \
- i+1, cache->cc_nkeys, cache->cc_key[i]); \
- }
+ if (cache->cc_key[i] > 0) { \
+ elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d, %d", \
+ i+1, cache->cc_nkeys, cache->cc_key[i], \
+ relation->rd_att->attrs[cache->cc_key[i] - 1]->attlen); \
+ } else { \
+ elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d", \
+ i+1, cache->cc_nkeys, cache->cc_key[i]); \
+ }
#else
#define CatalogCacheInitializeCache_DEBUG1
#define CatalogCacheInitializeCache_DEBUG2
#endif
static void
-CatalogCacheInitializeCache(struct catcache *cache,
- Relation relation)
+CatalogCacheInitializeCache(struct catcache * cache,
+ Relation relation)
{
- MemoryContext oldcxt;
- short didopen = 0;
- short i;
- TupleDesc tupdesc;
-
- CatalogCacheInitializeCache_DEBUG1;
-
- /* ----------------
- * first switch to the cache context so our allocations
- * do not vanish at the end of a transaction
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * If no relation was passed we must open it to get access to
- * its fields. If one of the other caches has already opened
- * it we use heap_open() instead of heap_openr()
- * ----------------
- */
- if (! RelationIsValid(relation)) {
- struct catcache *cp;
+ MemoryContext oldcxt;
+ short didopen = 0;
+ short i;
+ TupleDesc tupdesc;
+
+ CatalogCacheInitializeCache_DEBUG1;
+
/* ----------------
- * scan the caches to see if any other cache has opened the relation
+ * first switch to the cache context so our allocations
+ * do not vanish at the end of a transaction
* ----------------
*/
- for (cp = Caches; cp; cp = cp->cc_next) {
- if (strncmp(cp->cc_relname, cache->cc_relname, NAMEDATALEN) == 0) {
- if (cp->relationId != InvalidOid)
- break;
- }
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * If no relation was passed we must open it to get access to
+ * its fields. If one of the other caches has already opened
+ * it we use heap_open() instead of heap_openr()
+ * ----------------
+ */
+ if (!RelationIsValid(relation))
+ {
+ struct catcache *cp;
+
+ /* ----------------
+ * scan the caches to see if any other cache has opened the relation
+ * ----------------
+ */
+ for (cp = Caches; cp; cp = cp->cc_next)
+ {
+ if (strncmp(cp->cc_relname, cache->cc_relname, NAMEDATALEN) == 0)
+ {
+ if (cp->relationId != InvalidOid)
+ break;
+ }
+ }
+
+ /* ----------------
+ * open the relation by name or by id
+ * ----------------
+ */
+ if (cp)
+ relation = heap_open(cp->relationId);
+ else
+ {
+ relation = heap_openr(cache->cc_relname);
+ }
+
+ didopen = 1;
}
-
+
/* ----------------
- * open the relation by name or by id
+ * initialize the cache's relation id
* ----------------
*/
- if (cp)
- relation = heap_open(cp->relationId);
- else
- {
- relation = heap_openr(cache->cc_relname);
- }
-
- didopen = 1;
- }
-
- /* ----------------
- * initialize the cache's relation id
- * ----------------
- */
- Assert(RelationIsValid(relation));
- cache->relationId = RelationGetRelationId(relation);
- tupdesc = cache->cc_tupdesc = RelationGetTupleDescriptor(relation);
-
- CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %d, %d keys",
- cache->relationId, cache->cc_nkeys);
-
- /* ----------------
- * initialize cache's key information
- * ----------------
- */
- for (i = 0; i < cache->cc_nkeys; ++i) {
- CatalogCacheInitializeCache_DEBUG2;
-
- if (cache->cc_key[i] > 0) {
-
- /*
- * Yoiks. The implementation of the hashing code and the
- * implementation of int28's are at loggerheads. The right
- * thing to do is to throw out the implementation of int28's
- * altogether; until that happens, we do the right thing here
- * to guarantee that the hash key generator doesn't try to
- * dereference an int2 by mistake.
- */
-
- if (tupdesc->attrs[cache->cc_key[i]-1]->atttypid == INT28OID)
- cache->cc_klen[i] = sizeof (short);
- else
- cache->cc_klen[i] = tupdesc->attrs[cache->cc_key[i]-1]->attlen;
-
- cache->cc_skey[i].sk_procedure =
- EQPROC(tupdesc->attrs[cache->cc_key[i]-1]->atttypid);
-
- fmgr_info(cache->cc_skey[i].sk_procedure,
- (func_ptr *) &cache->cc_skey[i].sk_func,
- (int *) &cache->cc_skey[i].sk_nargs);
-
- CACHE5_elog(DEBUG, "CatalogCacheInit %16s %d %d %x",
- &relation->rd_rel->relname,
- i,
- tupdesc->attrs[ cache->cc_key[i]-1 ]->attlen,
- cache);
+ Assert(RelationIsValid(relation));
+ cache->relationId = RelationGetRelationId(relation);
+ tupdesc = cache->cc_tupdesc = RelationGetTupleDescriptor(relation);
+
+ CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %d, %d keys",
+ cache->relationId, cache->cc_nkeys);
+
+ /* ----------------
+ * initialize cache's key information
+ * ----------------
+ */
+ for (i = 0; i < cache->cc_nkeys; ++i)
+ {
+ CatalogCacheInitializeCache_DEBUG2;
+
+ if (cache->cc_key[i] > 0)
+ {
+
+ /*
+ * Yoiks. The implementation of the hashing code and the
+ * implementation of int28's are at loggerheads. The right
+ * thing to do is to throw out the implementation of int28's
+ * altogether; until that happens, we do the right thing here
+ * to guarantee that the hash key generator doesn't try to
+ * dereference an int2 by mistake.
+ */
+
+ if (tupdesc->attrs[cache->cc_key[i] - 1]->atttypid == INT28OID)
+ cache->cc_klen[i] = sizeof(short);
+ else
+ cache->cc_klen[i] = tupdesc->attrs[cache->cc_key[i] - 1]->attlen;
+
+ cache->cc_skey[i].sk_procedure =
+ EQPROC(tupdesc->attrs[cache->cc_key[i] - 1]->atttypid);
+
+ fmgr_info(cache->cc_skey[i].sk_procedure,
+ (func_ptr *) & cache->cc_skey[i].sk_func,
+ (int *) &cache->cc_skey[i].sk_nargs);
+
+ CACHE5_elog(DEBUG, "CatalogCacheInit %16s %d %d %x",
+ &relation->rd_rel->relname,
+ i,
+ tupdesc->attrs[cache->cc_key[i] - 1]->attlen,
+ cache);
+ }
}
- }
-
- /* ----------------
- * close the relation if we opened it
- * ----------------
- */
- if (didopen)
- heap_close(relation);
-
- /* ----------------
- * initialize index information for the cache. this
- * should only be done once per cache.
- * ----------------
- */
- if (cache->cc_indname != NULL && cache->indexId == InvalidOid)
+
+ /* ----------------
+ * close the relation if we opened it
+ * ----------------
+ */
+ if (didopen)
+ heap_close(relation);
+
+ /* ----------------
+ * initialize index information for the cache. this
+ * should only be done once per cache.
+ * ----------------
+ */
+ if (cache->cc_indname != NULL && cache->indexId == InvalidOid)
{
- if (RelationGetRelationTupleForm(relation)->relhasindex)
+ if (RelationGetRelationTupleForm(relation)->relhasindex)
{
- /*
- * If the index doesn't exist we are in trouble.
- */
- relation = index_openr( cache->cc_indname);
- Assert(relation);
- cache->indexId = RelationGetRelationId(relation);
- index_close(relation);
+
+ /*
+ * If the index doesn't exist we are in trouble.
+ */
+ relation = index_openr(cache->cc_indname);
+ Assert(relation);
+ cache->indexId = RelationGetRelationId(relation);
+ index_close(relation);
}
- else
- cache->cc_indname = NULL;
+ else
+ cache->cc_indname = NULL;
}
-
- /* ----------------
- * return to the proper memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
+
+ /* ----------------
+ * return to the proper memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
}
/* --------------------------------
- * CatalogCacheSetId
+ * CatalogCacheSetId
*
- * XXX temporary function
+ * XXX temporary function
* --------------------------------
*/
#ifdef NOT_USED
void
-CatalogCacheSetId(CatCache *cacheInOutP, int id)
+CatalogCacheSetId(CatCache * cacheInOutP, int id)
{
- Assert(id == InvalidCatalogCacheId || id >= 0);
- cacheInOutP->id = id;
+ Assert(id == InvalidCatalogCacheId || id >= 0);
+ cacheInOutP->id = id;
}
+
#endif
/* ----------------
* comphash --
- * Compute a hash value, somehow.
+ * Compute a hash value, somehow.
*
* XXX explain algorithm here.
*
@@ -279,798 +289,846 @@ CatalogCacheSetId(CatCache *cacheInOutP, int id)
static long
comphash(long l, register char *v)
{
- long i;
- NameData n;
-
- CACHE3_elog(DEBUG, "comphash (%d,%x)", l, v);
-
- switch (l) {
- case 1:
- case 2:
- case 4:
- return((long) v);
- }
-
- if (l == NAMEDATALEN) {
- /* if it's a name, make sure that the values
- are null-padded.
-
- Note that this other fixed-length types can also have
- the same typelen so this may break them - XXX
- */
- namestrcpy(&n,v);
- v = n.data;
- } else
- if (l < 0)
- l = VARSIZE(v);
-
- i = 0;
- while (l--) {
- i += *v++;
- }
- return(i);
+ long i;
+ NameData n;
+
+ CACHE3_elog(DEBUG, "comphash (%d,%x)", l, v);
+
+ switch (l)
+ {
+ case 1:
+ case 2:
+ case 4:
+ return ((long) v);
+ }
+
+ if (l == NAMEDATALEN)
+ {
+
+ /*
+ * if it's a name, make sure that the values are null-padded.
+ *
+ * Note that this other fixed-length types can also have the same
+ * typelen so this may break them - XXX
+ */
+ namestrcpy(&n, v);
+ v = n.data;
+ }
+ else if (l < 0)
+ l = VARSIZE(v);
+
+ i = 0;
+ while (l--)
+ {
+ i += *v++;
+ }
+ return (i);
}
/* --------------------------------
- * CatalogCacheComputeHashIndex
+ * CatalogCacheComputeHashIndex
* --------------------------------
*/
-static Index
-CatalogCacheComputeHashIndex(struct catcache *cacheInP)
+static Index
+CatalogCacheComputeHashIndex(struct catcache * cacheInP)
{
- Index hashIndex;
- hashIndex = 0x0;
- CACHE6_elog(DEBUG,"CatalogCacheComputeHashIndex %s %d %d %d %x",
- cacheInP->cc_relname,
- cacheInP->cc_nkeys,
- cacheInP->cc_klen[0],
- cacheInP->cc_klen[1],
- cacheInP);
-
- switch (cacheInP->cc_nkeys) {
- case 4:
- hashIndex ^= comphash(cacheInP->cc_klen[3],
- (char*)cacheInP->cc_skey[3].sk_argument) << 9;
- /* FALLTHROUGH */
- case 3:
- hashIndex ^= comphash(cacheInP->cc_klen[2],
- (char*)cacheInP->cc_skey[2].sk_argument) << 6;
- /* FALLTHROUGH */
- case 2:
- hashIndex ^= comphash(cacheInP->cc_klen[1],
- (char*)cacheInP->cc_skey[1].sk_argument) << 3;
- /* FALLTHROUGH */
- case 1:
- hashIndex ^= comphash(cacheInP->cc_klen[0],
- (char*)cacheInP->cc_skey[0].sk_argument);
- break;
- default:
- elog(FATAL, "CCComputeHashIndex: %d cc_nkeys", cacheInP->cc_nkeys);
- break;
- }
- hashIndex %= cacheInP->cc_size;
- return (hashIndex);
+ Index hashIndex;
+
+ hashIndex = 0x0;
+ CACHE6_elog(DEBUG, "CatalogCacheComputeHashIndex %s %d %d %d %x",
+ cacheInP->cc_relname,
+ cacheInP->cc_nkeys,
+ cacheInP->cc_klen[0],
+ cacheInP->cc_klen[1],
+ cacheInP);
+
+ switch (cacheInP->cc_nkeys)
+ {
+ case 4:
+ hashIndex ^= comphash(cacheInP->cc_klen[3],
+ (char *) cacheInP->cc_skey[3].sk_argument) << 9;
+ /* FALLTHROUGH */
+ case 3:
+ hashIndex ^= comphash(cacheInP->cc_klen[2],
+ (char *) cacheInP->cc_skey[2].sk_argument) << 6;
+ /* FALLTHROUGH */
+ case 2:
+ hashIndex ^= comphash(cacheInP->cc_klen[1],
+ (char *) cacheInP->cc_skey[1].sk_argument) << 3;
+ /* FALLTHROUGH */
+ case 1:
+ hashIndex ^= comphash(cacheInP->cc_klen[0],
+ (char *) cacheInP->cc_skey[0].sk_argument);
+ break;
+ default:
+ elog(FATAL, "CCComputeHashIndex: %d cc_nkeys", cacheInP->cc_nkeys);
+ break;
+ }
+ hashIndex %= cacheInP->cc_size;
+ return (hashIndex);
}
/* --------------------------------
- * CatalogCacheComputeTupleHashIndex
+ * CatalogCacheComputeTupleHashIndex
* --------------------------------
*/
-static Index
-CatalogCacheComputeTupleHashIndex(struct catcache *cacheInOutP,
- Relation relation,
- HeapTuple tuple)
+static Index
+CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
+ Relation relation,
+ HeapTuple tuple)
{
- bool isNull = '\0';
- if (cacheInOutP->relationId == InvalidOid)
- CatalogCacheInitializeCache(cacheInOutP, relation);
- switch (cacheInOutP->cc_nkeys) {
- case 4:
- cacheInOutP->cc_skey[3].sk_argument =
- (cacheInOutP->cc_key[3] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[3],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- /* FALLTHROUGH */
- case 3:
- cacheInOutP->cc_skey[2].sk_argument =
- (cacheInOutP->cc_key[2] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[2],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- /* FALLTHROUGH */
- case 2:
- cacheInOutP->cc_skey[1].sk_argument =
- (cacheInOutP->cc_key[1] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[1],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- /* FALLTHROUGH */
- case 1:
- cacheInOutP->cc_skey[0].sk_argument =
- (cacheInOutP->cc_key[0] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[0],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- break;
- default:
- elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys",
- cacheInOutP->cc_nkeys
- );
- break;
- }
-
- return
- CatalogCacheComputeHashIndex(cacheInOutP);
+ bool isNull = '\0';
+
+ if (cacheInOutP->relationId == InvalidOid)
+ CatalogCacheInitializeCache(cacheInOutP, relation);
+ switch (cacheInOutP->cc_nkeys)
+ {
+ case 4:
+ cacheInOutP->cc_skey[3].sk_argument =
+ (cacheInOutP->cc_key[3] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[3],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ /* FALLTHROUGH */
+ case 3:
+ cacheInOutP->cc_skey[2].sk_argument =
+ (cacheInOutP->cc_key[2] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[2],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ /* FALLTHROUGH */
+ case 2:
+ cacheInOutP->cc_skey[1].sk_argument =
+ (cacheInOutP->cc_key[1] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[1],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ /* FALLTHROUGH */
+ case 1:
+ cacheInOutP->cc_skey[0].sk_argument =
+ (cacheInOutP->cc_key[0] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[0],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ break;
+ default:
+ elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys",
+ cacheInOutP->cc_nkeys
+ );
+ break;
+ }
+
+ return
+ CatalogCacheComputeHashIndex(cacheInOutP);
}
/* --------------------------------
- * CatCacheRemoveCTup
+ * CatCacheRemoveCTup
* --------------------------------
*/
static void
-CatCacheRemoveCTup(CatCache *cache, Dlelem *elt)
+CatCacheRemoveCTup(CatCache * cache, Dlelem * elt)
{
- CatCTup *ct;
- CatCTup *other_ct;
- Dlelem *other_elt;
-
- if (elt)
- ct = (CatCTup*) DLE_VAL(elt);
- else
- return;
-
- other_elt = ct->ct_node;
- other_ct = (CatCTup*)DLE_VAL(other_elt);
- DLRemove(other_elt);
- DLFreeElem(other_elt);
- free(other_ct);
- DLRemove(elt);
- DLFreeElem(elt);
- free(ct);
- --cache->cc_ntup;
+ CatCTup *ct;
+ CatCTup *other_ct;
+ Dlelem *other_elt;
+
+ if (elt)
+ ct = (CatCTup *) DLE_VAL(elt);
+ else
+ return;
+
+ other_elt = ct->ct_node;
+ other_ct = (CatCTup *) DLE_VAL(other_elt);
+ DLRemove(other_elt);
+ DLFreeElem(other_elt);
+ free(other_ct);
+ DLRemove(elt);
+ DLFreeElem(elt);
+ free(ct);
+ --cache->cc_ntup;
}
/* --------------------------------
- * CatalogCacheIdInvalidate()
+ * CatalogCacheIdInvalidate()
*
- * Invalidate a tuple given a cache id. In this case the id should always
- * be found (whether the cache has opened its relation or not). Of course,
- * if the cache has yet to open its relation, there will be no tuples so
- * no problem.
+ * Invalidate a tuple given a cache id. In this case the id should always
+ * be found (whether the cache has opened its relation or not). Of course,
+ * if the cache has yet to open its relation, there will be no tuples so
+ * no problem.
* --------------------------------
*/
void
-CatalogCacheIdInvalidate(int cacheId, /* XXX */
- Index hashIndex,
- ItemPointer pointer)
+CatalogCacheIdInvalidate(int cacheId, /* XXX */
+ Index hashIndex,
+ ItemPointer pointer)
{
- CatCache *ccp;
- CatCTup *ct;
- Dlelem *elt;
- MemoryContext oldcxt;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(hashIndex < NCCBUCK);
- Assert(ItemPointerIsValid(pointer));
- CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
-
- /* ----------------
- * switch to the cache context for our memory allocations
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * inspect every cache that could contain the tuple
- * ----------------
- */
- for (ccp = Caches; ccp; ccp = ccp->cc_next) {
- if (cacheId != ccp->id)
- continue;
+ CatCache *ccp;
+ CatCTup *ct;
+ Dlelem *elt;
+ MemoryContext oldcxt;
+
/* ----------------
- * inspect the hash bucket until we find a match or exhaust
+ * sanity checks
* ----------------
*/
- for (elt = DLGetHead(ccp->cc_cache[hashIndex]);
- elt;
- elt = DLGetSucc(elt))
- {
- ct = (CatCTup*) DLE_VAL(elt);
- if (ItemPointerEquals(pointer, &ct->ct_tup->t_ctid))
- break;
- }
-
+ Assert(hashIndex < NCCBUCK);
+ Assert(ItemPointerIsValid(pointer));
+ CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
+
/* ----------------
- * if we found a matching tuple, invalidate it.
+ * switch to the cache context for our memory allocations
* ----------------
*/
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * inspect every cache that could contain the tuple
+ * ----------------
+ */
+ for (ccp = Caches; ccp; ccp = ccp->cc_next)
+ {
+ if (cacheId != ccp->id)
+ continue;
+ /* ----------------
+ * inspect the hash bucket until we find a match or exhaust
+ * ----------------
+ */
+ for (elt = DLGetHead(ccp->cc_cache[hashIndex]);
+ elt;
+ elt = DLGetSucc(elt))
+ {
+ ct = (CatCTup *) DLE_VAL(elt);
+ if (ItemPointerEquals(pointer, &ct->ct_tup->t_ctid))
+ break;
+ }
- if (elt) {
- CatCacheRemoveCTup(ccp, elt);
+ /* ----------------
+ * if we found a matching tuple, invalidate it.
+ * ----------------
+ */
- CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
+ if (elt)
+ {
+ CatCacheRemoveCTup(ccp, elt);
+
+ CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
+ }
+
+ if (cacheId != InvalidCatalogCacheId)
+ break;
}
-
- if (cacheId != InvalidCatalogCacheId)
- break;
- }
-
- /* ----------------
- * return to the proper memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
- /* sendpm('I', "Invalidated tuple"); */
+
+ /* ----------------
+ * return to the proper memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
+ /* sendpm('I', "Invalidated tuple"); */
}
/* ----------------------------------------------------------------
- * public functions
+ * public functions
*
- * ResetSystemCache
- * InitIndexedSysCache
- * InitSysCache
- * SearchSysCache
- * RelationInvalidateCatalogCacheTuple
+ * ResetSystemCache
+ * InitIndexedSysCache
+ * InitSysCache
+ * SearchSysCache
+ * RelationInvalidateCatalogCacheTuple
* ----------------------------------------------------------------
*/
/* --------------------------------
- * ResetSystemCache
+ * ResetSystemCache
* --------------------------------
*/
void
ResetSystemCache()
{
- MemoryContext oldcxt;
- struct catcache *cache;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- CACHE1_elog(DEBUG, "ResetSystemCache called");
- if (DisableCache) {
- elog(WARN, "ResetSystemCache: Called while cache disabled");
- return;
- }
-
- /* ----------------
- * first switch to the cache context so our allocations
- * do not vanish at the end of a transaction
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * here we purge the contents of all the caches
- *
- * for each system cache
- * for each hash bucket
- * for each tuple in hash bucket
- * remove the tuple
- * ----------------
- */
- for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next) {
- int hash;
- for (hash = 0; hash < NCCBUCK; hash += 1) {
- Dlelem *elt, *nextelt;
- for (elt = DLGetHead(cache->cc_cache[hash]); elt; elt = nextelt) {
- nextelt = DLGetSucc(elt);
- CatCacheRemoveCTup(cache, elt);
- if (cache->cc_ntup == -1)
- elog(WARN, "ResetSystemCache: cc_ntup<0 (software error)");
- }
+ MemoryContext oldcxt;
+ struct catcache *cache;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ CACHE1_elog(DEBUG, "ResetSystemCache called");
+ if (DisableCache)
+ {
+ elog(WARN, "ResetSystemCache: Called while cache disabled");
+ return;
+ }
+
+ /* ----------------
+ * first switch to the cache context so our allocations
+ * do not vanish at the end of a transaction
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * here we purge the contents of all the caches
+ *
+ * for each system cache
+ * for each hash bucket
+ * for each tuple in hash bucket
+ * remove the tuple
+ * ----------------
+ */
+ for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next)
+ {
+ int hash;
+
+ for (hash = 0; hash < NCCBUCK; hash += 1)
+ {
+ Dlelem *elt,
+ *nextelt;
+
+ for (elt = DLGetHead(cache->cc_cache[hash]); elt; elt = nextelt)
+ {
+ nextelt = DLGetSucc(elt);
+ CatCacheRemoveCTup(cache, elt);
+ if (cache->cc_ntup == -1)
+ elog(WARN, "ResetSystemCache: cc_ntup<0 (software error)");
+ }
+ }
+ cache->cc_ntup = 0; /* in case of WARN error above */
}
- cache->cc_ntup = 0; /* in case of WARN error above */
- }
-
- CACHE1_elog(DEBUG, "end of ResetSystemCache call");
-
- /* ----------------
- * back to the old context before we return...
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
+
+ CACHE1_elog(DEBUG, "end of ResetSystemCache call");
+
+ /* ----------------
+ * back to the old context before we return...
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
}
/* --------------------------------
- * InitIndexedSysCache
+ * InitIndexedSysCache
*
- * This allocates and initializes a cache for a system catalog relation.
- * Actually, the cache is only partially initialized to avoid opening the
- * relation. The relation will be opened and the rest of the cache
- * structure initialized on the first access.
+ * This allocates and initializes a cache for a system catalog relation.
+ * Actually, the cache is only partially initialized to avoid opening the
+ * relation. The relation will be opened and the rest of the cache
+ * structure initialized on the first access.
* --------------------------------
*/
#ifdef CACHEDEBUG
#define InitSysCache_DEBUG1 \
elog(DEBUG, "InitSysCache: rid=%d id=%d nkeys=%d size=%d\n", \
- cp->relationId, cp->id, cp->cc_nkeys, cp->cc_size); \
- for (i = 0; i < nkeys; i += 1) { \
- elog(DEBUG, "InitSysCache: key=%d len=%d skey=[%d %d %d %d]\n", \
- cp->cc_key[i], cp->cc_klen[i], \
- cp->cc_skey[i].sk_flags, \
- cp->cc_skey[i].sk_attno, \
- cp->cc_skey[i].sk_procedure, \
- cp->cc_skey[i].sk_argument); \
- }
+ cp->relationId, cp->id, cp->cc_nkeys, cp->cc_size); \
+ for (i = 0; i < nkeys; i += 1) { \
+ elog(DEBUG, "InitSysCache: key=%d len=%d skey=[%d %d %d %d]\n", \
+ cp->cc_key[i], cp->cc_klen[i], \
+ cp->cc_skey[i].sk_flags, \
+ cp->cc_skey[i].sk_attno, \
+ cp->cc_skey[i].sk_procedure, \
+ cp->cc_skey[i].sk_argument); \
+ }
#else
#define InitSysCache_DEBUG1
#endif
-CatCache*
+CatCache *
InitSysCache(char *relname,
- char *iname,
- int id,
- int nkeys,
- int key[],
- HeapTuple (*iScanfuncP)())
+ char *iname,
+ int id,
+ int nkeys,
+ int key[],
+ HeapTuple(*iScanfuncP) ())
{
- CatCache *cp;
- register int i;
- MemoryContext oldcxt;
-
- char *indname;
-
- indname = (iname) ? iname : NULL;
-
- /* ----------------
- * first switch to the cache context so our allocations
- * do not vanish at the end of a transaction
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * allocate a new cache structure
- * ----------------
- */
- cp = (CatCache *)palloc(sizeof(CatCache));
- memset((char*)cp, 0, sizeof(CatCache));
-
- /* ----------------
- * initialize the cache buckets (each bucket is a list header)
- * and the LRU tuple list
- * ----------------
- */
- {
- /*
- * We can only do this optimization because the number of hash
- * buckets never changes. Without it, we call malloc() too much.
- * 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.
- */
- Dllist *cache_begin = malloc((NCCBUCK+1)*sizeof(Dllist));
- for (i = 0; i <= NCCBUCK; ++i) {
- cp->cc_cache[i] = &cache_begin[i];
- cp->cc_cache[i]->dll_head = 0;
- cp->cc_cache[i]->dll_tail = 0;
- }
- }
-
- cp->cc_lrulist = DLNewList();
-
- /* ----------------
- * Caches is the pointer to the head of the list of all the
- * system caches. here we add the new cache to the top of the list.
- * ----------------
- */
- cp->cc_next = Caches; /* list of caches (single link) */
- Caches = cp;
-
- /* ----------------
- * initialize the cache's relation information for the relation
- * corresponding to this cache and initialize some of the the new
- * cache's other internal fields.
- * ----------------
- */
- cp->relationId = InvalidOid;
- cp->indexId = InvalidOid;
- cp->cc_relname = relname;
- cp->cc_indname = indname;
- cp->cc_tupdesc = (TupleDesc) NULL;
- cp->id = id;
- cp->cc_maxtup = MAXTUP;
- cp->cc_size = NCCBUCK;
- cp->cc_nkeys = nkeys;
- cp->cc_iscanfunc = iScanfuncP;
-
- /* ----------------
- * initialize the cache's key information
- * ----------------
- */
- for (i = 0; i < nkeys; ++i) {
- cp->cc_key[i] = key[i];
- if (!key[i]) {
- elog(FATAL, "InitSysCache: called with 0 key[%d]", i);
- }
- if (key[i] < 0) {
- if (key[i] != ObjectIdAttributeNumber) {
- elog(FATAL, "InitSysCache: called with %d key[%d]", key[i], i);
- } else {
- cp->cc_klen[i] = sizeof(Oid);
+ CatCache *cp;
+ register int i;
+ MemoryContext oldcxt;
+
+ char *indname;
+
+ indname = (iname) ? iname : NULL;
+
+ /* ----------------
+ * first switch to the cache context so our allocations
+ * do not vanish at the end of a transaction
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * allocate a new cache structure
+ * ----------------
+ */
+ cp = (CatCache *) palloc(sizeof(CatCache));
+ memset((char *) cp, 0, sizeof(CatCache));
+
+ /* ----------------
+ * initialize the cache buckets (each bucket is a list header)
+ * and the LRU tuple list
+ * ----------------
+ */
+ {
+
/*
- * ScanKeyEntryData and struct skey are equivalent. It looks
- * like a move was made to obsolete struct skey, but it
- * didn't reach this file. Someday we should clean up this
- * code and consolidate to ScanKeyEntry - mer 10 Nov 1991
+ * We can only do this optimization because the number of hash
+ * buckets never changes. Without it, we call malloc() too much.
+ * 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.
*/
- ScanKeyEntryInitialize(&cp->cc_skey[i],
- (bits16)0,
- (AttrNumber)key[i],
- (RegProcedure)F_OIDEQ,
- (Datum)0);
- continue;
- }
+ Dllist *cache_begin = malloc((NCCBUCK + 1) * sizeof(Dllist));
+
+ for (i = 0; i <= NCCBUCK; ++i)
+ {
+ cp->cc_cache[i] = &cache_begin[i];
+ cp->cc_cache[i]->dll_head = 0;
+ cp->cc_cache[i]->dll_tail = 0;
+ }
+ }
+
+ cp->cc_lrulist = DLNewList();
+
+ /* ----------------
+ * Caches is the pointer to the head of the list of all the
+ * system caches. here we add the new cache to the top of the list.
+ * ----------------
+ */
+ cp->cc_next = Caches; /* list of caches (single link) */
+ Caches = cp;
+
+ /* ----------------
+ * initialize the cache's relation information for the relation
+ * corresponding to this cache and initialize some of the the new
+ * cache's other internal fields.
+ * ----------------
+ */
+ cp->relationId = InvalidOid;
+ cp->indexId = InvalidOid;
+ cp->cc_relname = relname;
+ cp->cc_indname = indname;
+ cp->cc_tupdesc = (TupleDesc) NULL;
+ cp->id = id;
+ cp->cc_maxtup = MAXTUP;
+ cp->cc_size = NCCBUCK;
+ cp->cc_nkeys = nkeys;
+ cp->cc_iscanfunc = iScanfuncP;
+
+ /* ----------------
+ * initialize the cache's key information
+ * ----------------
+ */
+ for (i = 0; i < nkeys; ++i)
+ {
+ cp->cc_key[i] = key[i];
+ if (!key[i])
+ {
+ elog(FATAL, "InitSysCache: called with 0 key[%d]", i);
+ }
+ if (key[i] < 0)
+ {
+ if (key[i] != ObjectIdAttributeNumber)
+ {
+ elog(FATAL, "InitSysCache: called with %d key[%d]", key[i], i);
+ }
+ else
+ {
+ cp->cc_klen[i] = sizeof(Oid);
+
+ /*
+ * ScanKeyEntryData and struct skey are equivalent. It
+ * looks like a move was made to obsolete struct skey, but
+ * it didn't reach this file. Someday we should clean up
+ * this code and consolidate to ScanKeyEntry - mer 10 Nov
+ * 1991
+ */
+ ScanKeyEntryInitialize(&cp->cc_skey[i],
+ (bits16) 0,
+ (AttrNumber) key[i],
+ (RegProcedure) F_OIDEQ,
+ (Datum) 0);
+ continue;
+ }
+ }
+
+ cp->cc_skey[i].sk_attno = key[i];
}
-
- cp->cc_skey[i].sk_attno = key[i];
- }
-
- /* ----------------
- * all done. new cache is initialized. print some debugging
- * information, if appropriate.
- * ----------------
- */
- InitSysCache_DEBUG1;
-
- /* ----------------
- * back to the old context before we return...
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
- return(cp);
+
+ /* ----------------
+ * all done. new cache is initialized. print some debugging
+ * information, if appropriate.
+ * ----------------
+ */
+ InitSysCache_DEBUG1;
+
+ /* ----------------
+ * back to the old context before we return...
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
+ return (cp);
}
/* --------------------------------
- * SearchSysCache
+ * SearchSysCache
*
- * This call searches a system cache for a tuple, opening the relation
- * if necessary (the first access to a particular cache).
+ * This call searches a system cache for a tuple, opening the relation
+ * if necessary (the first access to a particular cache).
* --------------------------------
*/
HeapTuple
-SearchSysCache(struct catcache *cache,
- Datum v1,
- Datum v2,
- Datum v3,
- Datum v4)
+SearchSysCache(struct catcache * cache,
+ Datum v1,
+ Datum v2,
+ Datum v3,
+ Datum v4)
{
- unsigned hash;
- CatCTup *ct = NULL;
- CatCTup *nct;
- CatCTup *nct2;
- Dlelem *elt;
- HeapTuple ntp = 0;
- Buffer buffer;
-
- Relation relation;
- MemoryContext oldcxt;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- if (cache->relationId == InvalidOid)
- CatalogCacheInitializeCache(cache, NULL);
-
- /* ----------------
- * initialize the search key information
- * ----------------
- */
- cache->cc_skey[0].sk_argument = v1;
- cache->cc_skey[1].sk_argument = v2;
- cache->cc_skey[2].sk_argument = v3;
- cache->cc_skey[3].sk_argument = v4;
-
- /* ----------------
- * find the hash bucket in which to look for the tuple
- * ----------------
- */
- hash = CatalogCacheComputeHashIndex(cache);
-
- /* ----------------
- * scan the hash bucket until we find a match or exhaust our tuples
- * ----------------
- */
- for (elt = DLGetHead(cache->cc_cache[hash]);
- elt;
- elt = DLGetSucc(elt))
+ unsigned hash;
+ CatCTup *ct = NULL;
+ CatCTup *nct;
+ CatCTup *nct2;
+ Dlelem *elt;
+ HeapTuple ntp = 0;
+ Buffer buffer;
+
+ Relation relation;
+ MemoryContext oldcxt;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ if (cache->relationId == InvalidOid)
+ CatalogCacheInitializeCache(cache, NULL);
+
+ /* ----------------
+ * initialize the search key information
+ * ----------------
+ */
+ cache->cc_skey[0].sk_argument = v1;
+ cache->cc_skey[1].sk_argument = v2;
+ cache->cc_skey[2].sk_argument = v3;
+ cache->cc_skey[3].sk_argument = v4;
+
+ /* ----------------
+ * find the hash bucket in which to look for the tuple
+ * ----------------
+ */
+ hash = CatalogCacheComputeHashIndex(cache);
+
+ /* ----------------
+ * scan the hash bucket until we find a match or exhaust our tuples
+ * ----------------
+ */
+ for (elt = DLGetHead(cache->cc_cache[hash]);
+ elt;
+ elt = DLGetSucc(elt))
{
- ct = (CatCTup*)DLE_VAL(elt);
- /* ----------------
- * see if the cached tuple matches our key.
- * (should we be worried about time ranges? -cim 10/2/90)
- * ----------------
- */
- if (heap_keytest(ct->ct_tup,
- cache->cc_tupdesc,
- cache->cc_nkeys,
- cache->cc_skey))
- break;
+ ct = (CatCTup *) DLE_VAL(elt);
+ /* ----------------
+ * see if the cached tuple matches our key.
+ * (should we be worried about time ranges? -cim 10/2/90)
+ * ----------------
+ */
+ if (heap_keytest(ct->ct_tup,
+ cache->cc_tupdesc,
+ cache->cc_nkeys,
+ cache->cc_skey))
+ break;
}
-
- /* ----------------
- * if we found a tuple in the cache, move it to the top of the
- * lru list, and return it.
- * ----------------
- */
- if (elt) {
- Dlelem* old_lru_elt;
- old_lru_elt = ((CatCTup*)DLE_VAL(elt))->ct_node;
- DLRemove(old_lru_elt);
- DLAddHead(cache->cc_lrulist, old_lru_elt);
+
+ /* ----------------
+ * if we found a tuple in the cache, move it to the top of the
+ * lru list, and return it.
+ * ----------------
+ */
+ if (elt)
+ {
+ Dlelem *old_lru_elt;
+
+ old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
+ DLRemove(old_lru_elt);
+ DLAddHead(cache->cc_lrulist, old_lru_elt);
#ifdef CACHEDEBUG
+ relation = heap_open(cache->relationId);
+ CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d",
+ RelationGetRelationName(relation), hash);
+ heap_close(relation);
+#endif /* CACHEDEBUG */
+
+ return (ct->ct_tup);
+ }
+
+ /* ----------------
+ * Tuple was not found in cache, so we have to try and
+ * retrieve it directly from the relation. If it's found,
+ * we add it to the cache. We must avoid recursion here,
+ * so we disable cache operations. If operations are
+ * currently disabled and we couldn't find the requested item
+ * in the cache, then this may be a recursive request, and we
+ * abort with an error.
+ * ----------------
+ */
+
+ if (DisableCache)
+ {
+ elog(WARN, "SearchSysCache: Called while cache disabled");
+ return ((HeapTuple) NULL);
+ }
+
+ /* ----------------
+ * open the relation associated with the cache
+ * ----------------
+ */
relation = heap_open(cache->relationId);
- CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d",
- RelationGetRelationName(relation), hash);
- heap_close(relation);
-#endif /* CACHEDEBUG */
-
- return (ct->ct_tup);
- }
-
- /* ----------------
- * Tuple was not found in cache, so we have to try and
- * retrieve it directly from the relation. If it's found,
- * we add it to the cache. We must avoid recursion here,
- * so we disable cache operations. If operations are
- * currently disabled and we couldn't find the requested item
- * in the cache, then this may be a recursive request, and we
- * abort with an error.
- * ----------------
- */
-
- if (DisableCache) {
- elog(WARN, "SearchSysCache: Called while cache disabled");
- return((HeapTuple) NULL);
- }
-
- /* ----------------
- * open the relation associated with the cache
- * ----------------
- */
- relation = heap_open(cache->relationId);
- CACHE2_elog(DEBUG, "SearchSysCache(%s)",
- RelationGetRelationName(relation));
-
- /* ----------------
- * DisableCache and then switch to the cache memory context.
- * ----------------
- */
- DisableCache = 1;
-
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * Scan the relation to find the tuple. If there's an index, and
- * if this isn't bootstrap (initdb) time, use the index.
- * ----------------
- */
- CACHE2_elog(DEBUG, "SearchSysCache: performing scan (override==%d)",
- heapisoverride());
-
- if ((RelationGetRelationTupleForm(relation))->relhasindex
- && !IsBootstrapProcessingMode())
+ CACHE2_elog(DEBUG, "SearchSysCache(%s)",
+ RelationGetRelationName(relation));
+
+ /* ----------------
+ * DisableCache and then switch to the cache memory context.
+ * ----------------
+ */
+ DisableCache = 1;
+
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * Scan the relation to find the tuple. If there's an index, and
+ * if this isn't bootstrap (initdb) time, use the index.
+ * ----------------
+ */
+ CACHE2_elog(DEBUG, "SearchSysCache: performing scan (override==%d)",
+ heapisoverride());
+
+ if ((RelationGetRelationTupleForm(relation))->relhasindex
+ && !IsBootstrapProcessingMode())
{
- /* ----------
- * Switch back to old memory context so memory not freed
- * in the scan function will go away at transaction end.
- * wieck - 10/18/1996
- * ----------
- */
- MemoryContextSwitchTo(oldcxt);
- Assert(cache->cc_iscanfunc);
- switch(cache->cc_nkeys)
+ /* ----------
+ * Switch back to old memory context so memory not freed
+ * in the scan function will go away at transaction end.
+ * wieck - 10/18/1996
+ * ----------
+ */
+ MemoryContextSwitchTo(oldcxt);
+ Assert(cache->cc_iscanfunc);
+ switch (cache->cc_nkeys)
+ {
+ case 4:
+ ntp = cache->cc_iscanfunc(relation, v1, v2, v3, v4);
+ break;
+ case 3:
+ ntp = cache->cc_iscanfunc(relation, v1, v2, v3);
+ break;
+ case 2:
+ ntp = cache->cc_iscanfunc(relation, v1, v2);
+ break;
+ case 1:
+ ntp = cache->cc_iscanfunc(relation, v1);
+ break;
+ }
+ /* ----------
+ * Back to Cache context. If we got a tuple copy it
+ * into our context.
+ * wieck - 10/18/1996
+ * ----------
+ */
+ MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ if (HeapTupleIsValid(ntp))
{
- case 4: ntp = cache->cc_iscanfunc(relation,v1,v2,v3,v4); break;
- case 3: ntp = cache->cc_iscanfunc(relation,v1,v2,v3); break;
- case 2: ntp = cache->cc_iscanfunc(relation,v1,v2); break;
- case 1: ntp = cache->cc_iscanfunc(relation,v1); break;
+ ntp = heap_copytuple(ntp);
}
- /* ----------
- * Back to Cache context. If we got a tuple copy it
- * into our context.
- * wieck - 10/18/1996
- * ----------
- */
- MemoryContextSwitchTo((MemoryContext)CacheCxt);
- if(HeapTupleIsValid(ntp)) {
- ntp = heap_copytuple(ntp);
- }
}
- else
+ else
{
- HeapScanDesc sd;
-
- /* ----------
- * As above do the lookup in the callers memory
- * context.
- * wieck - 10/18/1996
- * ----------
- */
- MemoryContextSwitchTo(oldcxt);
-
- sd = heap_beginscan(relation, 0, NowTimeQual,
- cache->cc_nkeys, cache->cc_skey);
-
- /* should this buffer be ReleaseBuffer'd? --djm 8/20/96 */
- ntp = heap_getnext(sd, 0, &buffer);
-
- MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- if (HeapTupleIsValid(ntp)) {
- CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
- ntp = heap_copytuple(ntp);
- }
-
- MemoryContextSwitchTo(oldcxt);
-
- heap_endscan(sd);
-
- MemoryContextSwitchTo((MemoryContext)CacheCxt);
+ HeapScanDesc sd;
+
+ /* ----------
+ * As above do the lookup in the callers memory
+ * context.
+ * wieck - 10/18/1996
+ * ----------
+ */
+ MemoryContextSwitchTo(oldcxt);
+
+ sd = heap_beginscan(relation, 0, NowTimeQual,
+ cache->cc_nkeys, cache->cc_skey);
+
+ /* should this buffer be ReleaseBuffer'd? --djm 8/20/96 */
+ ntp = heap_getnext(sd, 0, &buffer);
+
+ MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ if (HeapTupleIsValid(ntp))
+ {
+ CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
+ ntp = heap_copytuple(ntp);
+ }
+
+ MemoryContextSwitchTo(oldcxt);
+
+ heap_endscan(sd);
+
+ MemoryContextSwitchTo((MemoryContext) CacheCxt);
}
-
- DisableCache = 0;
-
- /* ----------------
- * scan is complete. if tup is valid, we copy it and add the copy to
- * the cache.
- * ----------------
- */
- if (HeapTupleIsValid(ntp)) {
+
+ DisableCache = 0;
+
/* ----------------
- * allocate a new cache tuple holder, store the pointer
- * to the heap tuple there and initialize the list pointers.
+ * scan is complete. if tup is valid, we copy it and add the copy to
+ * the cache.
* ----------------
*/
- Dlelem *lru_elt;
-
- /* this is a little cumbersome here because we want the Dlelem's
- in both doubly linked lists to point to one another.
- That makes it easier to remove something from both the cache bucket
- and the lru list at the same time */
- nct = (CatCTup*) malloc(sizeof(CatCTup));
- nct->ct_tup = ntp;
- elt = DLNewElem(nct);
- nct2 = (CatCTup*) malloc(sizeof(CatCTup));
- nct2->ct_tup = ntp;
- lru_elt = DLNewElem(nct2);
- nct2->ct_node = elt;
- nct->ct_node = lru_elt;
-
- DLAddHead(cache->cc_lrulist, lru_elt);
- DLAddHead(cache->cc_cache[hash], elt);
+ if (HeapTupleIsValid(ntp))
+ {
+ /* ----------------
+ * allocate a new cache tuple holder, store the pointer
+ * to the heap tuple there and initialize the list pointers.
+ * ----------------
+ */
+ Dlelem *lru_elt;
+
+ /*
+ * this is a little cumbersome here because we want the Dlelem's
+ * in both doubly linked lists to point to one another. That makes
+ * it easier to remove something from both the cache bucket and
+ * the lru list at the same time
+ */
+ nct = (CatCTup *) malloc(sizeof(CatCTup));
+ nct->ct_tup = ntp;
+ elt = DLNewElem(nct);
+ nct2 = (CatCTup *) malloc(sizeof(CatCTup));
+ nct2->ct_tup = ntp;
+ lru_elt = DLNewElem(nct2);
+ nct2->ct_node = elt;
+ nct->ct_node = lru_elt;
+
+ DLAddHead(cache->cc_lrulist, lru_elt);
+ DLAddHead(cache->cc_cache[hash], elt);
+
+ /* ----------------
+ * deal with hash bucket overflow
+ * ----------------
+ */
+ if (++cache->cc_ntup > cache->cc_maxtup)
+ {
+ CatCTup *ct;
+
+ elt = DLGetTail(cache->cc_lrulist);
+ ct = (CatCTup *) DLE_VAL(elt);
+
+ if (ct != nct)
+ {
+ CACHE2_elog(DEBUG, "SearchSysCache(%s): Overflow, LRU removal",
+ RelationGetRelationName(relation));
+
+ CatCacheRemoveCTup(cache, elt);
+
+ }
+ }
+
+ CACHE4_elog(DEBUG, "SearchSysCache(%s): Contains %d/%d tuples",
+ RelationGetRelationName(relation),
+ cache->cc_ntup, cache->cc_maxtup);
+ CACHE3_elog(DEBUG, "SearchSysCache(%s): put in bucket %d",
+ RelationGetRelationName(relation), hash);
+ }
/* ----------------
- * deal with hash bucket overflow
+ * close the relation, switch back to the original memory context
+ * and return the tuple we found (or NULL)
* ----------------
*/
- if (++cache->cc_ntup > cache->cc_maxtup) {
- CatCTup *ct;
- elt = DLGetTail(cache->cc_lrulist);
- ct = (CatCTup *) DLE_VAL(elt);
-
- if (ct != nct) {
- CACHE2_elog(DEBUG, "SearchSysCache(%s): Overflow, LRU removal",
- RelationGetRelationName(relation));
-
- CatCacheRemoveCTup(cache, elt);
-
- }
- }
-
- CACHE4_elog(DEBUG, "SearchSysCache(%s): Contains %d/%d tuples",
- RelationGetRelationName(relation),
- cache->cc_ntup, cache->cc_maxtup);
- CACHE3_elog(DEBUG, "SearchSysCache(%s): put in bucket %d",
- RelationGetRelationName(relation), hash);
- }
-
- /* ----------------
- * close the relation, switch back to the original memory context
- * and return the tuple we found (or NULL)
- * ----------------
- */
- heap_close(relation);
-
- MemoryContextSwitchTo(oldcxt);
- return ntp;
+ heap_close(relation);
+
+ MemoryContextSwitchTo(oldcxt);
+ return ntp;
}
/* --------------------------------
- * RelationInvalidateCatalogCacheTuple()
+ * RelationInvalidateCatalogCacheTuple()
*
- * Invalidate a tuple from a specific relation. This call determines the
- * cache in question and calls CatalogCacheIdInvalidate(). It is -ok-
- * if the relation cannot be found, it simply means this backend has yet
- * to open it.
+ * Invalidate a tuple from a specific relation. This call determines the
+ * cache in question and calls CatalogCacheIdInvalidate(). It is -ok-
+ * if the relation cannot be found, it simply means this backend has yet
+ * to open it.
* --------------------------------
*/
void
RelationInvalidateCatalogCacheTuple(Relation relation,
- HeapTuple tuple,
- void (*function)(int, Index, ItemPointer))
+ HeapTuple tuple,
+ void (*function) (int, Index, ItemPointer))
{
- struct catcache *ccp;
- MemoryContext oldcxt;
- Oid relationId;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
- CACHE1_elog(DEBUG, "RelationInvalidateCatalogCacheTuple: called");
-
- /* ----------------
- * switch to the cache memory context
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * for each cache
- * if the cache contains tuples from the specified relation
- * call the invalidation function on the tuples
- * in the proper hash bucket
- * ----------------
- */
- relationId = RelationGetRelationId(relation);
-
- for (ccp = Caches; ccp; ccp = ccp->cc_next) {
- if (relationId != ccp->relationId)
- continue;
-
- /* OPT inline simplification of CatalogCacheIdInvalidate */
- if (!PointerIsValid(function)) {
- function = CatalogCacheIdInvalidate;
+ struct catcache *ccp;
+ MemoryContext oldcxt;
+ Oid relationId;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ Assert(HeapTupleIsValid(tuple));
+ CACHE1_elog(DEBUG, "RelationInvalidateCatalogCacheTuple: called");
+
+ /* ----------------
+ * switch to the cache memory context
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * for each cache
+ * if the cache contains tuples from the specified relation
+ * call the invalidation function on the tuples
+ * in the proper hash bucket
+ * ----------------
+ */
+ relationId = RelationGetRelationId(relation);
+
+ for (ccp = Caches; ccp; ccp = ccp->cc_next)
+ {
+ if (relationId != ccp->relationId)
+ continue;
+
+ /* OPT inline simplification of CatalogCacheIdInvalidate */
+ if (!PointerIsValid(function))
+ {
+ function = CatalogCacheIdInvalidate;
+ }
+
+ (*function) (ccp->id,
+ CatalogCacheComputeTupleHashIndex(ccp, relation, tuple),
+ &tuple->t_ctid);
+
+ heap_close(relation);
}
-
- (*function)(ccp->id,
- CatalogCacheComputeTupleHashIndex(ccp, relation, tuple),
- &tuple->t_ctid);
-
- heap_close(relation);
- }
-
- /* ----------------
- * return to the proper memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
-
- /* sendpm('I', "Invalidated tuple"); */
-}
+ /* ----------------
+ * return to the proper memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
+
+ /* sendpm('I', "Invalidated tuple"); */
+}
diff --git a/src/backend/utils/cache/fcache.c b/src/backend/utils/cache/fcache.c
index 1d86364abda..ad174c6fdf5 100644
--- a/src/backend/utils/cache/fcache.c
+++ b/src/backend/utils/cache/fcache.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fcache.c--
- * Code for the 'function cache' used in Oper and Func nodes....
+ * Code for the 'function cache' used in Oper and Func nodes....
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.4 1996/11/10 03:03:22 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.5 1997/09/07 04:52:59 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,23 +23,24 @@
#include "catalog/pg_proc.h"
#include "catalog/pg_language.h"
#include "catalog/pg_class.h"
-#include "parser/parsetree.h" /* for getrelname() */
+#include "parser/parsetree.h" /* for getrelname() */
#include "utils/builtins.h"
#include "utils/fcache.h"
#include "utils/fcache2.h"
#include "nodes/primnodes.h"
#include "nodes/execnodes.h"
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static Oid GetDynamicFuncArgType(Var *arg, ExprContext *econtext);
-static FunctionCachePtr init_fcache(Oid foid,
- bool use_syscache,
- List *argList,
- ExprContext *econtext);
+static Oid GetDynamicFuncArgType(Var * arg, ExprContext * econtext);
+static FunctionCachePtr
+init_fcache(Oid foid,
+ bool use_syscache,
+ List * argList,
+ ExprContext * econtext);
/*-----------------------------------------------------------------
*
@@ -47,259 +48,269 @@ static FunctionCachePtr init_fcache(Oid foid,
*
*
* NOTE: This function can be called when the system cache is being
- * initialized. Therefore, use_syscache should ONLY be true
- * when the function return type is interesting (ie: set_fcache).
+ * initialized. Therefore, use_syscache should ONLY be true
+ * when the function return type is interesting (ie: set_fcache).
*-----------------------------------------------------------------
*/
#define FuncArgTypeIsDynamic(arg) \
- (IsA(arg,Var) && ((Var*)arg)->varattno == InvalidAttrNumber)
+ (IsA(arg,Var) && ((Var*)arg)->varattno == InvalidAttrNumber)
-static Oid
-GetDynamicFuncArgType(Var *arg, ExprContext *econtext)
+static Oid
+GetDynamicFuncArgType(Var * arg, ExprContext * econtext)
{
- char *relname;
- int rtid;
- HeapTuple tup;
-
- Assert(IsA(arg,Var));
-
- rtid = ((Var*)arg)->varno;
- relname = (char*)getrelname(rtid, econtext->ecxt_range_table);
-
-
- tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(relname),
- 0,0,0);
- if (!tup)
- elog(WARN, "Lookup failed on type tuple for class %s",
- relname);
-
- return tup->t_oid;
+ char *relname;
+ int rtid;
+ HeapTuple tup;
+
+ Assert(IsA(arg, Var));
+
+ rtid = ((Var *) arg)->varno;
+ relname = (char *) getrelname(rtid, econtext->ecxt_range_table);
+
+
+ tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(relname),
+ 0, 0, 0);
+ if (!tup)
+ elog(WARN, "Lookup failed on type tuple for class %s",
+ relname);
+
+ return tup->t_oid;
}
-static FunctionCachePtr
+static FunctionCachePtr
init_fcache(Oid foid,
- bool use_syscache,
- List *argList,
- ExprContext *econtext)
+ bool use_syscache,
+ List * argList,
+ ExprContext * econtext)
{
- HeapTuple procedureTuple;
- HeapTuple typeTuple;
- Form_pg_proc procedureStruct;
- TypeTupleForm typeStruct;
- FunctionCachePtr retval;
- text *tmp;
- int nargs;
-
- /* ----------------
- * get the procedure tuple corresponding to the given
- * functionOid. If this fails, returnValue has been
- * pre-initialized to "null" so we just return it.
- * ----------------
- */
- retval = (FunctionCachePtr) palloc(sizeof(FunctionCache));
-
- if (!use_syscache)
- elog(WARN, "what the ????, init the fcache without the catalogs?");
-
- procedureTuple = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(foid),
- 0,0,0);
-
- if (!HeapTupleIsValid(procedureTuple))
- elog(WARN,
- "init_fcache: %s %d",
- "Cache lookup failed for procedure", foid);
-
- /* ----------------
- * get the return type from the procedure tuple
- * ----------------
- */
- procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
-
- /* ----------------
- * get the type tuple corresponding to the return type
- * If this fails, returnValue has been pre-initialized
- * to "null" so we just return it.
- * ----------------
- */
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(procedureStruct->prorettype),
- 0,0,0);
-
- if (!HeapTupleIsValid(typeTuple))
- elog(WARN,
- "init_fcache: %s %d",
- "Cache lookup failed for type",
- (procedureStruct)->prorettype);
-
- /* ----------------
- * get the type length and by-value from the type tuple and
- * save the information in our one element cache.
- * ----------------
- */
- typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
-
- retval->typlen = (typeStruct)->typlen;
- if ((typeStruct)->typrelid == InvalidOid) {
- /* The return type is not a relation, so just use byval */
- retval->typbyval = (typeStruct)->typbyval ? true : false ;
- } else {
- /* This is a hack. We assume here that any function returning
- * a relation returns it by reference. This needs to be
- * fixed.
+ HeapTuple procedureTuple;
+ HeapTuple typeTuple;
+ Form_pg_proc procedureStruct;
+ TypeTupleForm typeStruct;
+ FunctionCachePtr retval;
+ text *tmp;
+ int nargs;
+
+ /* ----------------
+ * get the procedure tuple corresponding to the given
+ * functionOid. If this fails, returnValue has been
+ * pre-initialized to "null" so we just return it.
+ * ----------------
+ */
+ retval = (FunctionCachePtr) palloc(sizeof(FunctionCache));
+
+ if (!use_syscache)
+ elog(WARN, "what the ????, init the fcache without the catalogs?");
+
+ procedureTuple = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(foid),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(procedureTuple))
+ elog(WARN,
+ "init_fcache: %s %d",
+ "Cache lookup failed for procedure", foid);
+
+ /* ----------------
+ * get the return type from the procedure tuple
+ * ----------------
+ */
+ procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+
+ /* ----------------
+ * get the type tuple corresponding to the return type
+ * If this fails, returnValue has been pre-initialized
+ * to "null" so we just return it.
+ * ----------------
+ */
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(procedureStruct->prorettype),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(typeTuple))
+ elog(WARN,
+ "init_fcache: %s %d",
+ "Cache lookup failed for type",
+ (procedureStruct)->prorettype);
+
+ /* ----------------
+ * get the type length and by-value from the type tuple and
+ * save the information in our one element cache.
+ * ----------------
*/
- retval->typbyval = false;
- }
- retval->foid = foid;
- retval->language = procedureStruct->prolang;
- retval->func_state = (char *)NULL;
- retval->setArg = NULL;
- retval->hasSetArg = false;
- retval->oneResult = ! procedureStruct->proretset;
- retval->istrusted = procedureStruct->proistrusted;
-
- /*
- * If we are returning exactly one result then we have to copy
- * tuples and by reference results because we have to end the execution
- * before we return the results. When you do this everything allocated
- * by the executor (i.e. slots and tuples) is freed.
- */
- if ((retval->language == SQLlanguageId) &&
- (retval->oneResult) &&
- !(retval->typbyval))
+ typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
+
+ retval->typlen = (typeStruct)->typlen;
+ if ((typeStruct)->typrelid == InvalidOid)
+ {
+ /* The return type is not a relation, so just use byval */
+ retval->typbyval = (typeStruct)->typbyval ? true : false;
+ }
+ else
{
- Form_pg_class relationStruct;
- HeapTuple relationTuple;
- TupleDesc td;
- TupleTableSlot *slot;
-
- slot = makeNode(TupleTableSlot);
- slot->ttc_shouldFree = true;
- slot->ttc_descIsNew = true;
- slot->ttc_tupleDescriptor = (TupleDesc) NULL;
- slot->ttc_buffer = InvalidBuffer;
- slot->ttc_whichplan = -1;
- retval->funcSlot = (Pointer)slot;
-
- relationTuple = (HeapTuple)
- SearchSysCacheTuple(RELNAME,
- PointerGetDatum(&typeStruct->typname),
- 0,0,0);
-
- if (relationTuple)
+
+ /*
+ * This is a hack. We assume here that any function returning a
+ * relation returns it by reference. This needs to be fixed.
+ */
+ retval->typbyval = false;
+ }
+ retval->foid = foid;
+ retval->language = procedureStruct->prolang;
+ retval->func_state = (char *) NULL;
+ retval->setArg = NULL;
+ retval->hasSetArg = false;
+ retval->oneResult = !procedureStruct->proretset;
+ retval->istrusted = procedureStruct->proistrusted;
+
+ /*
+ * If we are returning exactly one result then we have to copy tuples
+ * and by reference results because we have to end the execution
+ * before we return the results. When you do this everything
+ * allocated by the executor (i.e. slots and tuples) is freed.
+ */
+ if ((retval->language == SQLlanguageId) &&
+ (retval->oneResult) &&
+ !(retval->typbyval))
+ {
+ Form_pg_class relationStruct;
+ HeapTuple relationTuple;
+ TupleDesc td;
+ TupleTableSlot *slot;
+
+ slot = makeNode(TupleTableSlot);
+ slot->ttc_shouldFree = true;
+ slot->ttc_descIsNew = true;
+ slot->ttc_tupleDescriptor = (TupleDesc) NULL;
+ slot->ttc_buffer = InvalidBuffer;
+ slot->ttc_whichplan = -1;
+ retval->funcSlot = (Pointer) slot;
+
+ relationTuple = (HeapTuple)
+ SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(&typeStruct->typname),
+ 0, 0, 0);
+
+ if (relationTuple)
{
- relationStruct = (Form_pg_class)GETSTRUCT(relationTuple);
- td = CreateTemplateTupleDesc(relationStruct->relnatts);
+ relationStruct = (Form_pg_class) GETSTRUCT(relationTuple);
+ td = CreateTemplateTupleDesc(relationStruct->relnatts);
}
- else
- td = CreateTemplateTupleDesc(1);
-
- ((TupleTableSlot*)retval->funcSlot)->ttc_tupleDescriptor = td;
+ else
+ td = CreateTemplateTupleDesc(1);
+
+ ((TupleTableSlot *) retval->funcSlot)->ttc_tupleDescriptor = td;
}
- else
- retval->funcSlot = (char *)NULL;
-
- nargs = procedureStruct->pronargs;
- retval->nargs = nargs;
-
- if (nargs > 0)
+ else
+ retval->funcSlot = (char *) NULL;
+
+ nargs = procedureStruct->pronargs;
+ retval->nargs = nargs;
+
+ if (nargs > 0)
{
- Oid *argTypes;
-
- retval->nullVect = (bool *)palloc((retval->nargs)*sizeof(bool));
-
- if (retval->language == SQLlanguageId)
+ Oid *argTypes;
+
+ retval->nullVect = (bool *) palloc((retval->nargs) * sizeof(bool));
+
+ if (retval->language == SQLlanguageId)
{
- int i;
- List *oneArg;
-
- retval->argOidVect =
- (Oid *)palloc(retval->nargs*sizeof(Oid));
- argTypes = procedureStruct->proargtypes;
- memmove(retval->argOidVect,
- argTypes,
- (retval->nargs)*sizeof(Oid));
-
- for (i=0;
- argList;
- i++, argList = lnext(argList))
+ int i;
+ List *oneArg;
+
+ retval->argOidVect =
+ (Oid *) palloc(retval->nargs * sizeof(Oid));
+ argTypes = procedureStruct->proargtypes;
+ memmove(retval->argOidVect,
+ argTypes,
+ (retval->nargs) * sizeof(Oid));
+
+ for (i = 0;
+ argList;
+ i++, argList = lnext(argList))
{
- oneArg = lfirst(argList);
- if (FuncArgTypeIsDynamic(oneArg))
- retval->argOidVect[i] = GetDynamicFuncArgType((Var*)oneArg,
- econtext);
+ oneArg = lfirst(argList);
+ if (FuncArgTypeIsDynamic(oneArg))
+ retval->argOidVect[i] = GetDynamicFuncArgType((Var *) oneArg,
+ econtext);
}
}
- else
- retval->argOidVect = (Oid *)NULL;
+ else
+ retval->argOidVect = (Oid *) NULL;
}
- else
+ else
{
- retval->argOidVect = (Oid *)NULL;
- retval->nullVect = (BoolPtr)NULL;
+ retval->argOidVect = (Oid *) NULL;
+ retval->nullVect = (BoolPtr) NULL;
}
-
- /*
- * XXX this is the first varlena in the struct. If the order
- * changes for some reason this will fail.
- */
- if (procedureStruct->prolang == SQLlanguageId)
+
+ /*
+ * XXX this is the first varlena in the struct. If the order changes
+ * for some reason this will fail.
+ */
+ if (procedureStruct->prolang == SQLlanguageId)
{
- retval->src = textout(&(procedureStruct->prosrc));
- retval->bin = (char *) NULL;
+ retval->src = textout(&(procedureStruct->prosrc));
+ retval->bin = (char *) NULL;
}
- else
+ else
{
-
- /*
- * I'm not sure that we even need to do this at all.
- */
-
- /*
- * We do for untrusted functions.
- */
-
- if (procedureStruct->proistrusted)
- retval->bin = (char *) NULL;
- else {
- tmp = (text *)
- SearchSysCacheGetAttribute(PROOID,
- Anum_pg_proc_probin,
- ObjectIdGetDatum(foid),
- 0,0,0);
- retval->bin = textout(tmp);
- }
- retval->src = (char *) NULL;
+
+ /*
+ * I'm not sure that we even need to do this at all.
+ */
+
+ /*
+ * We do for untrusted functions.
+ */
+
+ if (procedureStruct->proistrusted)
+ retval->bin = (char *) NULL;
+ else
+ {
+ tmp = (text *)
+ SearchSysCacheGetAttribute(PROOID,
+ Anum_pg_proc_probin,
+ ObjectIdGetDatum(foid),
+ 0, 0, 0);
+ retval->bin = textout(tmp);
+ }
+ retval->src = (char *) NULL;
}
-
-
-
-
- if (retval->language != SQLlanguageId)
- fmgr_info(foid, &(retval->func), &(retval->nargs));
- else
- retval->func = (func_ptr)NULL;
-
-
- return(retval);
+
+
+
+
+ if (retval->language != SQLlanguageId)
+ fmgr_info(foid, &(retval->func), &(retval->nargs));
+ else
+ retval->func = (func_ptr) NULL;
+
+
+ return (retval);
}
void
-setFcache(Node *node, Oid foid, List *argList, ExprContext *econtext)
+setFcache(Node * node, Oid foid, List * argList, ExprContext * econtext)
{
- Func *fnode;
- Oper *onode;
- FunctionCachePtr fcache;
-
- fcache = init_fcache(foid, true, argList, econtext);
-
- if (IsA(node,Oper)) {
- onode = (Oper*) node;
- onode->op_fcache = fcache;
- }else if (IsA(node,Func)) {
- fnode = (Func*) node;
- fnode->func_fcache = fcache;
- }else {
- elog(WARN, "init_fcache: node must be Oper or Func!");
- }
+ Func *fnode;
+ Oper *onode;
+ FunctionCachePtr fcache;
+
+ fcache = init_fcache(foid, true, argList, econtext);
+
+ if (IsA(node, Oper))
+ {
+ onode = (Oper *) node;
+ onode->op_fcache = fcache;
+ }
+ else if (IsA(node, Func))
+ {
+ fnode = (Func *) node;
+ fnode->func_fcache = fcache;
+ }
+ else
+ {
+ elog(WARN, "init_fcache: node must be Oper or Func!");
+ }
}
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 4f52e4e5f4c..4fb8a5eb6ed 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* inval.c--
- * POSTGRES cache invalidation dispatcher code.
+ * POSTGRES cache invalidation dispatcher code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.4 1997/08/19 21:35:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.5 1997/09/07 04:53:01 momjian Exp $
*
* Note - this code is real crufty...
*
@@ -17,11 +17,11 @@
#include <miscadmin.h>
-#include "access/heapam.h" /* XXX to support hacks below */
+#include "access/heapam.h" /* XXX to support hacks below */
#include "access/htup.h"
#include "catalog/catalog.h"
#include "storage/bufpage.h"
-#include "storage/buf.h" /* XXX for InvalidBuffer */
+#include "storage/buf.h" /* XXX for InvalidBuffer */
#include "storage/ipc.h"
#include "storage/sinval.h"
#include "utils/catcache.h"
@@ -29,593 +29,615 @@
#include "utils/rel.h"
#include "utils/relcache.h"
#include "catalog/catname.h" /* XXX to support hacks below */
-#include "utils/syscache.h" /* XXX to support the hacks below */
+#include "utils/syscache.h" /* XXX to support the hacks below */
static InvalidationEntry InvalidationEntryAllocate(uint16 size);
-static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function)());
-static LocalInvalid LocalInvalidRegister(LocalInvalid invalid,
+static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function) ());
+static LocalInvalid
+LocalInvalidRegister(LocalInvalid invalid,
InvalidationEntry entry);
-static void getmyrelids(void);
+static void getmyrelids(void);
/* ----------------
- * private invalidation structures
+ * private invalidation structures
* ----------------
*/
-typedef struct CatalogInvalidationData {
- Index cacheId;
- Index hashIndex;
- ItemPointerData pointerData;
-} CatalogInvalidationData;
+typedef struct CatalogInvalidationData
+{
+ Index cacheId;
+ Index hashIndex;
+ ItemPointerData pointerData;
+} CatalogInvalidationData;
-typedef struct RelationInvalidationData {
- Oid relationId;
- Oid objectId;
-} RelationInvalidationData;
+typedef struct RelationInvalidationData
+{
+ Oid relationId;
+ Oid objectId;
+} RelationInvalidationData;
-typedef union AnyInvalidation {
- CatalogInvalidationData catalog;
- RelationInvalidationData relation;
-} AnyInvalidation;
+typedef union AnyInvalidation
+{
+ CatalogInvalidationData catalog;
+ RelationInvalidationData relation;
+} AnyInvalidation;
-typedef struct InvalidationMessageData {
- char kind;
- AnyInvalidation any;
-} InvalidationMessageData;
+typedef struct InvalidationMessageData
+{
+ char kind;
+ AnyInvalidation any;
+} InvalidationMessageData;
-typedef InvalidationMessageData *InvalidationMessage;
+typedef InvalidationMessageData *InvalidationMessage;
/* ----------------
- * variables and macros
+ * variables and macros
* ----------------
*/
-static LocalInvalid Invalid = EmptyLocalInvalid; /* XXX global */
-static bool RefreshWhenInvalidate = false;
+static LocalInvalid Invalid = EmptyLocalInvalid; /* XXX global */
+static bool RefreshWhenInvalidate = false;
-Oid MyRelationRelationId = InvalidOid;
-Oid MyAttributeRelationId = InvalidOid;
-Oid MyAMRelationId = InvalidOid;
-Oid MyAMOPRelationId = InvalidOid;
+Oid MyRelationRelationId = InvalidOid;
+Oid MyAttributeRelationId = InvalidOid;
+Oid MyAMRelationId = InvalidOid;
+Oid MyAMOPRelationId = InvalidOid;
#define ValidateHacks() \
- if (!OidIsValid(MyRelationRelationId)) getmyrelids()
+ if (!OidIsValid(MyRelationRelationId)) getmyrelids()
/* ----------------------------------------------------------------
- * "local" invalidation support functions
+ * "local" invalidation support functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * InvalidationEntryAllocate--
- * Allocates an invalidation entry.
+ * InvalidationEntryAllocate--
+ * Allocates an invalidation entry.
* --------------------------------
*/
-static InvalidationEntry
+static InvalidationEntry
InvalidationEntryAllocate(uint16 size)
{
- InvalidationEntryData *entryDataP;
- entryDataP = (InvalidationEntryData *)
- malloc(sizeof (char *) + size); /* XXX alignment */
- entryDataP->nextP = NULL;
- return ((Pointer) &entryDataP->userData);
+ InvalidationEntryData *entryDataP;
+
+ entryDataP = (InvalidationEntryData *)
+ malloc(sizeof(char *) + size); /* XXX alignment */
+ entryDataP->nextP = NULL;
+ return ((Pointer) & entryDataP->userData);
}
/* --------------------------------
- * LocalInvalidRegister --
- * Returns a new local cache invalidation state containing a new entry.
+ * LocalInvalidRegister --
+ * Returns a new local cache invalidation state containing a new entry.
* --------------------------------
*/
-static LocalInvalid
+static LocalInvalid
LocalInvalidRegister(LocalInvalid invalid,
- InvalidationEntry entry)
+ InvalidationEntry entry)
{
- Assert(PointerIsValid(entry));
-
- ((InvalidationUserData *)entry)->dataP[-1] =
- (InvalidationUserData *)invalid;
-
- return (entry);
+ Assert(PointerIsValid(entry));
+
+ ((InvalidationUserData *) entry)->dataP[-1] =
+ (InvalidationUserData *) invalid;
+
+ return (entry);
}
/* --------------------------------
- * LocalInvalidInvalidate--
- * Processes, then frees all entries in a local cache
- * invalidation state.
+ * LocalInvalidInvalidate--
+ * Processes, then frees all entries in a local cache
+ * invalidation state.
* --------------------------------
*/
static void
-LocalInvalidInvalidate(LocalInvalid invalid, void (*function)())
+LocalInvalidInvalidate(LocalInvalid invalid, void (*function) ())
{
- InvalidationEntryData *entryDataP;
-
- while (PointerIsValid(invalid)) {
- entryDataP = (InvalidationEntryData *)
- &((InvalidationUserData *)invalid)->dataP[-1];
-
- if (PointerIsValid(function)) {
- (*function)((Pointer) &entryDataP->userData);
+ 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);
}
-
- invalid = (Pointer) entryDataP->nextP;
-
- /* help catch errors */
- entryDataP->nextP = (InvalidationUserData *) NULL;
-
- free((Pointer)entryDataP);
- }
}
/* ----------------------------------------------------------------
- * private support functions
+ * private support functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * CacheIdRegisterLocalInvalid
+ * CacheIdRegisterLocalInvalid
* --------------------------------
*/
#ifdef INVALIDDEBUG
#define CacheIdRegisterLocalInvalid_DEBUG1 \
elog(DEBUG, "CacheIdRegisterLocalInvalid(%d, %d, [%d, %d])", \
- cacheId, hashIndex, ItemPointerGetBlockNumber(pointer), \
- ItemPointerGetOffsetNumber(pointer))
+ cacheId, hashIndex, ItemPointerGetBlockNumber(pointer), \
+ ItemPointerGetOffsetNumber(pointer))
#else
#define CacheIdRegisterLocalInvalid_DEBUG1
-#endif /* INVALIDDEBUG */
-
+#endif /* INVALIDDEBUG */
+
static void
CacheIdRegisterLocalInvalid(Index cacheId,
- Index hashIndex,
- ItemPointer pointer)
+ 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);
+ 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
+ * RelationIdRegisterLocalInvalid
* --------------------------------
*/
static void
RelationIdRegisterLocalInvalid(Oid relationId, Oid objectId)
{
- InvalidationMessage message;
-
- /* ----------------
- * debugging stuff
- * ----------------
- */
+ 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);
+ 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
+ * getmyrelids
* --------------------------------
*/
static void
getmyrelids()
{
- HeapTuple tuple;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(RelationRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyRelationRelationId = tuple->t_oid;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(AttributeRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyAttributeRelationId = tuple->t_oid;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(AccessMethodRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyAMRelationId = tuple->t_oid;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(AccessMethodOperatorRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyAMOPRelationId = tuple->t_oid;
+ HeapTuple tuple;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(RelationRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyRelationRelationId = tuple->t_oid;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(AttributeRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyAttributeRelationId = tuple->t_oid;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(AccessMethodRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyAMRelationId = tuple->t_oid;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(AccessMethodOperatorRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyAMOPRelationId = tuple->t_oid;
}
/* --------------------------------
- * CacheIdInvalidate
+ * 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...
+ * 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))
+ pointer, ItemPointerIsValid(pointer))
#else
#define CacheIdInvalidate_DEBUG1
-#endif /* defined(INVALIDDEBUG) */
-
+#endif /* defined(INVALIDDEBUG) */
+
static void
CacheIdInvalidate(Index cacheId,
- Index hashIndex,
- ItemPointer pointer)
+ Index hashIndex,
+ ItemPointer pointer)
{
- /* ----------------
- * 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(InvalidOid);
- return;
- }
-
- /* ----------------
- * Yow! the caller asked us to invalidate something else.
- * ----------------
- */
- elog(FATAL, "CacheIdInvalidate: cacheId=%d relation id?", cacheId);
+ /* ----------------
+ * 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(InvalidOid);
+ return;
+ }
+
+ /* ----------------
+ * Yow! the caller asked us to invalidate something else.
+ * ----------------
+ */
+ elog(FATAL, "CacheIdInvalidate: cacheId=%d relation id?", cacheId);
}
/* --------------------------------
- * ResetSystemCaches
+ * ResetSystemCaches
*
- * this blows away all tuples in the system catalog caches and
- * all the cached relation descriptors (and closes the files too).
+ * 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);
+ ResetSystemCache();
+ RelationCacheInvalidate(false);
}
/* --------------------------------
- * InvalidationMessageRegisterSharedInvalid
+ * 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),\
- ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
+ "InvalidationMessageRegisterSharedInvalid(c, %d, %d, [%d, %d])",\
+ message->any.catalog.cacheId,\
+ message->any.catalog.hashIndex,\
+ ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
+ ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
#define InvalidationMessageRegisterSharedInvalid_DEBUG2 \
- elog(DEBUG, \
- "InvalidationMessageRegisterSharedInvalid(r, %d, %d)", \
- message->any.relation.relationId, \
- message->any.relation.objectId)
-#else
+ elog(DEBUG, \
+ "InvalidationMessageRegisterSharedInvalid(r, %d, %d)", \
+ message->any.relation.relationId, \
+ message->any.relation.objectId)
+#else
#define InvalidationMessageRegisterSharedInvalid_DEBUG1
#define InvalidationMessageRegisterSharedInvalid_DEBUG2
-#endif /* INVALIDDEBUG */
-
+#endif /* INVALIDDEBUG */
+
static void
InvalidationMessageRegisterSharedInvalid(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);
- }
+ 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
+ * 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),\
- ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
+ message->any.catalog.cacheId,\
+ message->any.catalog.hashIndex,\
+ ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
+ ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
#define InvalidationMessageCacheInvalidate_DEBUG2 \
- elog(DEBUG, "InvalidationMessageCacheInvalidate(r, %d, %d)", \
- message->any.relation.relationId, \
- message->any.relation.objectId)
+ elog(DEBUG, "InvalidationMessageCacheInvalidate(r, %d, %d)", \
+ message->any.relation.relationId, \
+ message->any.relation.objectId)
#else
#define InvalidationMessageCacheInvalidate_DEBUG1
#define InvalidationMessageCacheInvalidate_DEBUG2
-#endif /* defined(INVALIDDEBUG) */
-
+#endif /* defined(INVALIDDEBUG) */
+
static void
InvalidationMessageCacheInvalidate(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);
- }
+ 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
+ * RelationInvalidateRelationCache
* --------------------------------
*/
static void
RelationInvalidateRelationCache(Relation relation,
- HeapTuple tuple,
- void (*function)())
+ HeapTuple tuple,
+ void (*function) ())
{
- Oid relationId;
- Oid objectId = (Oid)0;
-
- /* ----------------
- * 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);
+ Oid relationId;
+ Oid objectId = (Oid) 0;
+
+ /* ----------------
+ * 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 --
- * Causes the invalidated cache state to be discarded.
+ * Causes the invalidated cache state to be discarded.
*
* Note:
- * This should be called as the first step in processing a transaction.
- * This should be called while waiting for a query from the front end
- * when other backends are active.
+ * This should be called as the first step in processing a transaction.
+ * This should be called while waiting for a query from the front end
+ * when other backends are active.
*/
void
DiscardInvalid()
{
- /* ----------------
- * debugging stuff
- * ----------------
- */
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
#ifdef INVALIDDEBUG
- elog(DEBUG, "DiscardInvalid called");
-#endif /* defined(INVALIDDEBUG) */
-
- InvalidateSharedInvalid(CacheIdInvalidate, ResetSystemCaches);
+ elog(DEBUG, "DiscardInvalid called");
+#endif /* defined(INVALIDDEBUG) */
+
+ InvalidateSharedInvalid(CacheIdInvalidate, ResetSystemCaches);
}
/*
* RegisterInvalid --
- * Causes registration of invalidated state with other backends iff true.
+ * Causes registration of invalidated state with other backends iff true.
*
* Note:
- * This should be called as the last step in processing a transaction.
+ * This should be called as the last step in processing a transaction.
*/
void
RegisterInvalid(bool send)
{
- /* ----------------
- * debugging stuff
- * ----------------
- */
+ /* ----------------
+ * 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;
+ 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 --
- * Causes the local caches to be immediately refreshed iff true.
+ * Causes the local caches to be immediately refreshed iff true.
*/
void
SetRefreshWhenInvalidate(bool on)
{
#ifdef INVALIDDEBUG
- elog(DEBUG, "RefreshWhenInvalidate(%d) called", on);
-#endif /* defined(INVALIDDEBUG) */
-
- RefreshWhenInvalidate = on;
+ elog(DEBUG, "RefreshWhenInvalidate(%d) called", on);
+#endif /* defined(INVALIDDEBUG) */
+
+ RefreshWhenInvalidate = on;
}
/*
* RelationIdInvalidateHeapTuple --
- * Causes the given tuple in a relation to be invalidated.
+ * Causes the given tuple in a relation to be invalidated.
*
* Note:
- * Assumes object id is valid.
- * Assumes tuple is valid.
+ * Assumes object id is valid.
+ * Assumes tuple is valid.
*/
#ifdef INVALIDDEBUG
#define RelationInvalidateHeapTuple_DEBUG1 \
elog(DEBUG, "RelationInvalidateHeapTuple(%.16s, [%d,%d])", \
- RelationGetRelationName(relation), \
- ItemPointerGetBlockNumber(&tuple->t_ctid), \
- ItemPointerGetOffsetNumber(&tuple->t_ctid))
+ RelationGetRelationName(relation), \
+ ItemPointerGetBlockNumber(&tuple->t_ctid), \
+ ItemPointerGetOffsetNumber(&tuple->t_ctid))
#else
#define RelationInvalidateHeapTuple_DEBUG1
-#endif /* defined(INVALIDDEBUG) */
-
+#endif /* defined(INVALIDDEBUG) */
+
void
RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple)
{
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
-
- if (IsBootstrapProcessingMode())
- return;
- /* ----------------
- * this only works for system relations now
- * ----------------
- */
- if (! IsSystemRelationName(RelationGetRelationTupleForm(relation)->relname.data))
- return;
-
- /* ----------------
- * debugging stuff
- * ----------------
- */
- RelationInvalidateHeapTuple_DEBUG1;
-
- /* ----------------
- *
- * ----------------
- */
- RelationInvalidateCatalogCacheTuple(relation,
- tuple,
- CacheIdRegisterLocalInvalid);
-
- RelationInvalidateRelationCache(relation,
- tuple,
- RelationIdRegisterLocalInvalid);
-
- if (RefreshWhenInvalidate)
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ Assert(HeapTupleIsValid(tuple));
+
+ if (IsBootstrapProcessingMode())
+ return;
+ /* ----------------
+ * this only works for system relations now
+ * ----------------
+ */
+ if (!IsSystemRelationName(RelationGetRelationTupleForm(relation)->relname.data))
+ return;
+
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
+ RelationInvalidateHeapTuple_DEBUG1;
+
+ /* ----------------
+ *
+ * ----------------
+ */
RelationInvalidateCatalogCacheTuple(relation,
- tuple,
- (void (*)()) NULL);
-}
+ tuple,
+ CacheIdRegisterLocalInvalid);
+ RelationInvalidateRelationCache(relation,
+ tuple,
+ RelationIdRegisterLocalInvalid);
+
+ if (RefreshWhenInvalidate)
+ RelationInvalidateCatalogCacheTuple(relation,
+ tuple,
+ (void (*) ()) NULL);
+}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 9de0c3fb89b..37280036970 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* lsyscache.c--
- * Routines to access information within system caches
+ * Routines to access information within system caches
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.3 1997/08/19 21:35:11 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.4 1997/09/07 04:53:04 momjian Exp $
*
* NOTES
- * Eventually, the index information should go through here, too.
- *
- * Most of these routines call SearchSysCacheStruct() and thus simply
- * (1) allocate some space for the return struct and (2) call it.
- *
+ * Eventually, the index information should go through here, too.
+ *
+ * Most of these routines call SearchSysCacheStruct() and thus simply
+ * (1) allocate some space for the return struct and (2) call it.
+ *
*-------------------------------------------------------------------------
*/
#include <string.h>
@@ -34,99 +34,100 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
-/* ---------- AMOP CACHES ---------- */
+/* ---------- AMOP CACHES ---------- */
-/*
+/*
* op_class -
- *
- * Return t iff operator 'opno' is in operator class 'opclass'.
- *
+ *
+ * Return t iff operator 'opno' is in operator class 'opclass'.
+ *
*/
bool
op_class(Oid opno, int32 opclass, Oid amopid)
{
- FormData_pg_amop amoptup;
-
- if (SearchSysCacheStruct(AMOPOPID,
- (char *) &amoptup,
- ObjectIdGetDatum(opclass),
- ObjectIdGetDatum(opno),
- ObjectIdGetDatum(amopid),
- 0))
- return(true);
- else
- return(false);
+ FormData_pg_amop amoptup;
+
+ if (SearchSysCacheStruct(AMOPOPID,
+ (char *) &amoptup,
+ ObjectIdGetDatum(opclass),
+ ObjectIdGetDatum(opno),
+ ObjectIdGetDatum(amopid),
+ 0))
+ return (true);
+ else
+ return (false);
}
-/* ---------- ATTRIBUTE CACHES ---------- */
+/* ---------- ATTRIBUTE CACHES ---------- */
-/*
+/*
* get_attname -
- *
- * Given the relation id and the attribute number,
- * return the "attname" field from the attribute relation.
- *
+ *
+ * Given the relation id and the attribute number,
+ * return the "attname" field from the attribute relation.
+ *
*/
-char*
+char *
get_attname(Oid relid, AttrNumber attnum)
{
- FormData_pg_attribute att_tup;
- char *retval;
-
- if (SearchSysCacheStruct(ATTNUM,
- (char*)&att_tup,
- ObjectIdGetDatum(relid),
- UInt16GetDatum(attnum),
- 0,0)) {
- retval = pstrdup(att_tup.attname.data);
-
- return(retval);
- }
- else
- return(NULL);
+ FormData_pg_attribute att_tup;
+ char *retval;
+
+ if (SearchSysCacheStruct(ATTNUM,
+ (char *) &att_tup,
+ ObjectIdGetDatum(relid),
+ UInt16GetDatum(attnum),
+ 0, 0))
+ {
+ retval = pstrdup(att_tup.attname.data);
+
+ return (retval);
+ }
+ else
+ return (NULL);
}
-/*
+/*
* get_attnum -
- *
- * Given the relation id and the attribute name,
- * return the "attnum" field from the attribute relation.
- *
+ *
+ * Given the relation id and the attribute name,
+ * return the "attnum" field from the attribute relation.
+ *
*/
AttrNumber
get_attnum(Oid relid, char *attname)
{
- FormData_pg_attribute att_tup;
-
- if (SearchSysCacheStruct(ATTNAME, (char *) &att_tup,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0,0))
- return(att_tup.attnum);
- else
- return(InvalidAttrNumber);
+ FormData_pg_attribute att_tup;
+
+ if (SearchSysCacheStruct(ATTNAME, (char *) &att_tup,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(attname),
+ 0, 0))
+ return (att_tup.attnum);
+ else
+ return (InvalidAttrNumber);
}
-/*
+/*
* get_atttype -
- *
- * Given the relation OID and the attribute number with the relation,
- * return the attribute type OID.
- *
+ *
+ * Given the relation OID and the attribute number with the relation,
+ * return the attribute type OID.
+ *
*/
Oid
get_atttype(Oid relid, AttrNumber attnum)
{
- AttributeTupleForm att_tup = (AttributeTupleForm)palloc(sizeof(*att_tup));
-
- if (SearchSysCacheStruct(ATTNUM,
- (char *) att_tup,
- ObjectIdGetDatum(relid),
- UInt16GetDatum(attnum),
- 0,0))
- return(att_tup->atttypid);
- else
- return((Oid)NULL);
+ AttributeTupleForm att_tup = (AttributeTupleForm) palloc(sizeof(*att_tup));
+
+ if (SearchSysCacheStruct(ATTNUM,
+ (char *) att_tup,
+ ObjectIdGetDatum(relid),
+ UInt16GetDatum(attnum),
+ 0, 0))
+ return (att_tup->atttypid);
+ else
+ return ((Oid) NULL);
}
/* This routine uses the attname instead of the attnum because it
@@ -136,353 +137,366 @@ get_atttype(Oid relid, AttrNumber attnum)
bool
get_attisset(Oid relid, char *attname)
{
- HeapTuple htup;
- AttrNumber attno;
- AttributeTupleForm att_tup;
-
- attno = get_attnum(relid, attname);
-
- htup = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0,0);
- if (!HeapTupleIsValid(htup))
- elog(WARN, "get_attisset: no attribute %.16s in relation %d",
- attname, relid);
- if (heap_attisnull(htup, attno))
- return(false);
- else {
- att_tup = (AttributeTupleForm)GETSTRUCT(htup);
- return(att_tup->attisset);
- }
+ HeapTuple htup;
+ AttrNumber attno;
+ AttributeTupleForm att_tup;
+
+ attno = get_attnum(relid, attname);
+
+ htup = SearchSysCacheTuple(ATTNAME,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(attname),
+ 0, 0);
+ if (!HeapTupleIsValid(htup))
+ elog(WARN, "get_attisset: no attribute %.16s in relation %d",
+ attname, relid);
+ if (heap_attisnull(htup, attno))
+ return (false);
+ else
+ {
+ att_tup = (AttributeTupleForm) GETSTRUCT(htup);
+ return (att_tup->attisset);
+ }
}
-/* ---------- INDEX CACHE ---------- */
+/* ---------- INDEX CACHE ---------- */
-/* watch this space...
+/* watch this space...
*/
-/* ---------- OPERATOR CACHE ---------- */
+/* ---------- OPERATOR CACHE ---------- */
-/*
+/*
* get_opcode -
- *
- * Returns the regproc id of the routine used to implement an
- * operator given the operator uid.
- *
+ *
+ * Returns the regproc id of the routine used to implement an
+ * operator given the operator uid.
+ *
*/
RegProcedure
get_opcode(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprcode);
- else
- return((RegProcedure)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprcode);
+ else
+ return ((RegProcedure) NULL);
}
/*
* get_opname -
- * returns the name of the operator with the given opno
+ * returns the name of the operator with the given opno
*
* Note: return the struct so that it gets copied.
*/
-char*
+char *
get_opname(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return (pstrdup(optup.oprname.data));
- else {
- elog(WARN, "can't look up operator %d\n", opno);
- return NULL;
- }
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (pstrdup(optup.oprname.data));
+ else
+ {
+ elog(WARN, "can't look up operator %d\n", opno);
+ return NULL;
+ }
}
-/*
+/*
* op_mergesortable -
- *
- * Returns the left and right sort operators and types corresponding to a
- * mergesortable operator, or nil if the operator is not mergesortable.
- *
+ *
+ * Returns the left and right sort operators and types corresponding to a
+ * mergesortable operator, or nil if the operator is not mergesortable.
+ *
*/
bool
-op_mergesortable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
+op_mergesortable(Oid opno, Oid ltype, Oid rtype, Oid * leftOp, Oid * rightOp)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0) &&
- optup.oprlsortop &&
- optup.oprrsortop &&
- optup.oprleft == ltype &&
- optup.oprright == rtype) {
-
- *leftOp = ObjectIdGetDatum(optup.oprlsortop);
- *rightOp = ObjectIdGetDatum(optup.oprrsortop);
- return TRUE;
- } else {
- return FALSE;
- }
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0) &&
+ optup.oprlsortop &&
+ optup.oprrsortop &&
+ optup.oprleft == ltype &&
+ optup.oprright == rtype)
+ {
+
+ *leftOp = ObjectIdGetDatum(optup.oprlsortop);
+ *rightOp = ObjectIdGetDatum(optup.oprrsortop);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
-/*
+/*
* op_hashjoinable--
- *
- * Returns the hash operator corresponding to a hashjoinable operator,
+ *
+ * Returns the hash operator corresponding to a hashjoinable operator,
* or nil if the operator is not hashjoinable.
- *
+ *
*/
Oid
op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0) &&
- optup.oprcanhash &&
- optup.oprleft == ltype &&
- optup.oprright == rtype)
- return(opno);
- else
- return(InvalidOid);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0) &&
+ optup.oprcanhash &&
+ optup.oprleft == ltype &&
+ optup.oprright == rtype)
+ return (opno);
+ else
+ return (InvalidOid);
}
-/*
+/*
* get_commutator -
- *
- * Returns the corresponding commutator of an operator.
- *
+ *
+ * Returns the corresponding commutator of an operator.
+ *
*/
Oid
get_commutator(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprcom);
- else
- return((Oid)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprcom);
+ else
+ return ((Oid) NULL);
}
HeapTuple
get_operator_tuple(Oid opno)
{
- HeapTuple optup;
-
- if ((optup = SearchSysCacheTuple(OPROID,
- ObjectIdGetDatum(opno),
- 0,0,0)))
- return(optup);
- else
- return((HeapTuple)NULL);
+ HeapTuple optup;
+
+ if ((optup = SearchSysCacheTuple(OPROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0)))
+ return (optup);
+ else
+ return ((HeapTuple) NULL);
}
-/*
+/*
* get_negator -
- *
- * Returns the corresponding negator of an operator.
- *
+ *
+ * Returns the corresponding negator of an operator.
+ *
*/
Oid
get_negator(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprnegate);
- else
- return((Oid)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprnegate);
+ else
+ return ((Oid) NULL);
}
-/*
+/*
* get_oprrest -
- *
- * Returns procedure id for computing selectivity of an operator.
- *
+ *
+ * Returns procedure id for computing selectivity of an operator.
+ *
*/
RegProcedure
get_oprrest(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprrest );
- else
- return((RegProcedure) NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprrest);
+ else
+ return ((RegProcedure) NULL);
}
-/*
+/*
* get_oprjoin -
- *
- * Returns procedure id for computing selectivity of a join.
- *
+ *
+ * Returns procedure id for computing selectivity of a join.
+ *
*/
RegProcedure
get_oprjoin(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprjoin);
- else
- return((RegProcedure)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprjoin);
+ else
+ return ((RegProcedure) NULL);
}
-/* ---------- RELATION CACHE ---------- */
+/* ---------- RELATION CACHE ---------- */
-/*
+/*
* get_relnatts -
- *
- * Returns the number of attributes for a given relation.
- *
+ *
+ * Returns the number of attributes for a given relation.
+ *
*/
int
get_relnatts(Oid relid)
{
- FormData_pg_class reltup;
-
- if (SearchSysCacheStruct(RELOID, (char *) &reltup,
- ObjectIdGetDatum(relid),
- 0,0,0))
- return(reltup.relnatts);
- else
- return(InvalidAttrNumber);
+ FormData_pg_class reltup;
+
+ if (SearchSysCacheStruct(RELOID, (char *) &reltup,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0))
+ return (reltup.relnatts);
+ else
+ return (InvalidAttrNumber);
}
-/*
+/*
* get_rel_name -
- *
- * Returns the name of a given relation.
- *
+ *
+ * Returns the name of a given relation.
+ *
*/
-char*
+char *
get_rel_name(Oid relid)
{
- FormData_pg_class reltup;
-
- if ((SearchSysCacheStruct(RELOID,
- (char*)&reltup,
- ObjectIdGetDatum(relid),
- 0,0,0))) {
- return (pstrdup(reltup.relname.data));
- } else
- return(NULL);
+ FormData_pg_class reltup;
+
+ if ((SearchSysCacheStruct(RELOID,
+ (char *) &reltup,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0)))
+ {
+ return (pstrdup(reltup.relname.data));
+ }
+ else
+ return (NULL);
}
-/* ---------- TYPE CACHE ---------- */
+/* ---------- TYPE CACHE ---------- */
-/*
+/*
* get_typlen -
- *
- * Given the type OID, return the length of the type.
- *
+ *
+ * Given the type OID, return the length of the type.
+ *
*/
int16
get_typlen(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0))
- return(typtup.typlen);
- else
- return((int16)NULL);
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ return (typtup.typlen);
+ else
+ return ((int16) NULL);
}
-/*
+/*
* get_typbyval -
- *
- * Given the type OID, determine whether the type is returned by value or
- * not. Returns 1 if by value, 0 if by reference.
- *
+ *
+ * Given the type OID, determine whether the type is returned by value or
+ * not. Returns 1 if by value, 0 if by reference.
+ *
*/
bool
get_typbyval(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0))
- return((bool)typtup.typbyval);
- else
- return(false);
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ return ((bool) typtup.typbyval);
+ else
+ return (false);
}
-/*
+/*
* get_typbyval -
- *
- * Given the type OID, determine whether the type is returned by value or
- * not. Returns 1 if by value, 0 if by reference.
- *
+ *
+ * Given the type OID, determine whether the type is returned by value or
+ * not. Returns 1 if by value, 0 if by reference.
+ *
*/
#ifdef NOT_USED
char
get_typalign(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0))
- return(typtup.typalign);
- else
- return ('i');
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ return (typtup.typalign);
+ else
+ return ('i');
}
+
#endif
-/*
- * get_typdefault -
- *
- * Given the type OID, return the default value of the ADT.
- *
+/*
+ * get_typdefault -
+ *
+ * Given the type OID, return the default value of the ADT.
+ *
*/
struct varlena *
get_typdefault(Oid typid)
{
- struct varlena *typdefault =
- (struct varlena *)TypeDefaultRetrieve (typid);
- return(typdefault);
+ struct varlena *typdefault =
+ (struct varlena *) TypeDefaultRetrieve(typid);
+
+ return (typdefault);
}
-/*
+/*
* get_typtype -
- *
- * Given the type OID, find if it is a basic type, a named relation
- * or the generic type 'relation'.
- * It returns the null char if the cache lookup fails...
- *
+ *
+ * Given the type OID, find if it is a basic type, a named relation
+ * or the generic type 'relation'.
+ * It returns the null char if the cache lookup fails...
+ *
*/
#ifdef NOT_USED
char
get_typtype(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0)) {
- return(typtup.typtype);
- } else {
- return('\0');
- }
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ {
+ return (typtup.typtype);
+ }
+ else
+ {
+ return ('\0');
+ }
}
+
#endif
diff --git a/src/backend/utils/cache/rel.c b/src/backend/utils/cache/rel.c
index 33eabad1a85..4e45138037c 100644
--- a/src/backend/utils/cache/rel.c
+++ b/src/backend/utils/cache/rel.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rel.c--
- * POSTGRES relation descriptor code.
+ * POSTGRES relation descriptor code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/rel.c,v 1.1.1.1 1996/07/09 06:22:06 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/rel.c,v 1.2 1997/09/07 04:53:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,57 +21,56 @@
#include "storage/fd.h"
-/*
- * 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
- * -mer 3/2/92
+ * Many of the RelationGet...() functions are now macros in rel.h
+ * -mer 3/2/92
*/
/*
* RelationGetIndexStrategy --
- * Returns index strategy for a relation.
+ * Returns index strategy for a relation.
*
* Note:
- * Assumes relation descriptor is valid.
- * Assumes relation descriptor is for an index relation.
+ * Assumes relation descriptor is valid.
+ * Assumes relation descriptor is for an index relation.
*/
IndexStrategy
RelationGetIndexStrategy(Relation relation)
{
- return relation->rd_istrat;
+ return relation->rd_istrat;
}
/*
* RelationSetIndexSupport --
- * Sets index strategy and support info for a relation.
+ * Sets index strategy and support info for a relation.
*
* Note:
- * Assumes relation descriptor is a valid pointer to sufficient space.
- * Assumes index strategy is valid. Assumes support is valid if non-
- * NULL.
+ * Assumes relation descriptor is a valid pointer to sufficient space.
+ * Assumes index strategy is valid. Assumes support is valid if non-
+ * NULL.
*/
/* ----------------
- * RelationSetIndexSupport
+ * 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.
+ * 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
+ * NEW: the index strategy and support are now stored in real fields
+ * at the end of the structure - jolly
* ----------------
*/
void
RelationSetIndexSupport(Relation relation,
- IndexStrategy strategy,
- RegProcedure *support)
+ IndexStrategy strategy,
+ RegProcedure * support)
{
- Assert(PointerIsValid(relation));
- Assert(IndexStrategyIsValid(strategy));
-
- relation->rd_istrat = strategy;
- relation->rd_support = support;
-}
+ Assert(PointerIsValid(relation));
+ Assert(IndexStrategyIsValid(strategy));
+ relation->rd_istrat = strategy;
+ relation->rd_support = support;
+}
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index a54f1d81387..704d673279b 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1,41 +1,41 @@
/*-------------------------------------------------------------------------
*
* relcache.c--
- * POSTGRES relation descriptor cache code
+ * POSTGRES relation descriptor cache code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.20 1997/09/01 08:04:38 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.21 1997/09/07 04:53:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * RelationInitialize - initialize relcache
- * RelationIdCacheGetRelation - get a reldesc from the cache (id)
- * RelationNameCacheGetRelation - get a reldesc from the cache (name)
- * RelationIdGetRelation - get a reldesc by relation id
- * RelationNameGetRelation - get a reldesc by relation name
- * RelationClose - close an open relation
- * RelationFlushRelation - flush relation information
+ * RelationInitialize - initialize relcache
+ * RelationIdCacheGetRelation - get a reldesc from the cache (id)
+ * RelationNameCacheGetRelation - get a reldesc from the cache (name)
+ * RelationIdGetRelation - get a reldesc by relation id
+ * RelationNameGetRelation - get a reldesc by relation name
+ * RelationClose - close an open relation
+ * RelationFlushRelation - flush relation information
*
* NOTES
- * This file is in the process of being cleaned up
- * before I add system attribute indexing. -cim 1/13/91
+ * This file is in the process of being cleaned up
+ * before I add system attribute indexing. -cim 1/13/91
*
- * The following code contains many undocumented hacks. Please be
- * careful....
+ * The following code contains many undocumented hacks. Please be
+ * careful....
*
*/
#include <sys/types.h>
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <errno.h>
#include <sys/file.h>
#include <fcntl.h>
#include <string.h>
-
+
#include "postgres.h"
#include "miscadmin.h"
@@ -51,21 +51,21 @@
#include "access/tupdesc.h"
#include "access/tupmacs.h"
#include "access/xact.h"
-
+
#include "storage/buf.h"
-#include "storage/fd.h" /* for SEEK_ */
+#include "storage/fd.h" /* for SEEK_ */
#include "storage/lmgr.h"
#include "storage/bufmgr.h"
-
+
#include "lib/hasht.h"
-
+
#include "utils/memutils.h"
#include "utils/mcxt.h"
#include "utils/rel.h"
#include "utils/relcache.h"
#include "utils/hsearch.h"
#include "utils/relcache.h"
-
+
#include "catalog/catname.h"
#include "catalog/catalog.h"
#include "utils/syscache.h"
@@ -87,1744 +87,1813 @@
#include "catalog/index.h"
#include "fmgr.h"
-static void RelationFlushRelation(Relation *relationPtr,
- bool onlyFlushReferenceCountZero);
+static void
+RelationFlushRelation(Relation * relationPtr,
+ bool onlyFlushReferenceCountZero);
static Relation RelationNameCacheGetRelation(char *relationName);
-static void init_irels(void);
-static void write_irels(void);
+static void init_irels(void);
+static void write_irels(void);
/* ----------------
- * defines
+ * defines
* ----------------
*/
#define private static
#define INIT_FILENAME "pg_internal.init"
/* ----------------
- * externs
+ * externs
* ----------------
*/
-extern bool AMI_OVERRIDE; /* XXX style */
+extern bool AMI_OVERRIDE; /* XXX style */
extern GlobalMemory CacheCxt; /* from utils/cache/catcache.c */
/* ----------------
- * hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
+ * hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
* ----------------
*/
-FormData_pg_attribute Desc_pg_class[Natts_pg_class] = { Schema_pg_class };
-FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = { Schema_pg_attribute };
-FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = { Schema_pg_proc };
-FormData_pg_attribute Desc_pg_type[Natts_pg_type] = { Schema_pg_type };
-FormData_pg_attribute Desc_pg_variable[Natts_pg_variable] = { Schema_pg_variable };
-FormData_pg_attribute Desc_pg_log[Natts_pg_log] = { Schema_pg_log };
-FormData_pg_attribute Desc_pg_time[Natts_pg_time] = { Schema_pg_time };
+FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
+FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
+FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
+FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
+FormData_pg_attribute Desc_pg_variable[Natts_pg_variable] = {Schema_pg_variable};
+FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log};
+FormData_pg_attribute Desc_pg_time[Natts_pg_time] = {Schema_pg_time};
/* ----------------
- * global variables
+ * global variables
*
- * Relations are cached two ways, by name and by id,
- * thus there are two hash tables for referencing them.
+ * Relations are cached two ways, by name and by id,
+ * thus there are two hash tables for referencing them.
* ----------------
*/
-HTAB *RelationNameCache;
-HTAB *RelationIdCache;
+HTAB *RelationNameCache;
+HTAB *RelationIdCache;
/* ----------------
- * RelationBuildDescInfo exists so code can be shared
- * between RelationIdGetRelation() and RelationNameGetRelation()
+ * RelationBuildDescInfo exists so code can be shared
+ * between RelationIdGetRelation() and RelationNameGetRelation()
* ----------------
*/
-typedef struct RelationBuildDescInfo {
- int infotype; /* lookup by id or by name */
+typedef struct RelationBuildDescInfo
+{
+ int infotype; /* lookup by id or by name */
#define INFO_RELID 1
#define INFO_RELNAME 2
- union {
- Oid info_id; /* relation object id */
- char *info_name; /* relation name */
- } i;
-} RelationBuildDescInfo;
-
-typedef struct relidcacheent {
- Oid reloid;
- Relation reldesc;
-} RelIdCacheEnt;
-
-typedef struct relnamecacheent {
- NameData relname;
- Relation reldesc;
-} RelNameCacheEnt;
+ union
+ {
+ Oid info_id;/* relation object id */
+ char *info_name; /* relation name */
+ } i;
+} RelationBuildDescInfo;
+
+typedef struct relidcacheent
+{
+ Oid reloid;
+ Relation reldesc;
+} RelIdCacheEnt;
+
+typedef struct relnamecacheent
+{
+ NameData relname;
+ Relation reldesc;
+} RelNameCacheEnt;
/* -----------------
- * macros to manipulate name cache and id cache
+ * macros to manipulate name cache and id cache
* -----------------
*/
#define RelationCacheInsert(RELATION) \
- { RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \
- char *relname; Oid reloid; bool found; \
- relname = (RELATION->rd_rel->relname).data; \
- namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- relname, \
- HASH_ENTER, \
- &found); \
- if (namehentry == NULL) { \
- elog(FATAL, "can't insert into relation descriptor cache"); \
- } \
- if (found && !IsBootstrapProcessingMode()) { \
- /* used to give notice -- now just keep quiet */ ; \
- } \
- namehentry->reldesc = RELATION; \
- reloid = RELATION->rd_id; \
- idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&reloid, \
- HASH_ENTER, \
- &found); \
- if (idhentry == NULL) { \
- elog(FATAL, "can't insert into relation descriptor cache"); \
- } \
- if (found && !IsBootstrapProcessingMode()) { \
- /* used to give notice -- now just keep quiet */ ; \
- } \
- idhentry->reldesc = RELATION; \
- }
-#define RelationNameCacheLookup(NAME, RELATION) \
- { RelNameCacheEnt *hentry; bool found; \
- hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- (char *)NAME,HASH_FIND,&found); \
- if (hentry == NULL) { \
- elog(FATAL, "error in CACHE"); \
- } \
- if (found) { \
- RELATION = hentry->reldesc; \
- } \
- else { \
- RELATION = NULL; \
- } \
- }
-#define RelationIdCacheLookup(ID, RELATION) \
- { RelIdCacheEnt *hentry; bool found; \
- hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&(ID),HASH_FIND, &found); \
- if (hentry == NULL) { \
- elog(FATAL, "error in CACHE"); \
- } \
- if (found) { \
- RELATION = hentry->reldesc; \
- } \
- else { \
- RELATION = NULL; \
- } \
- }
+ { RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \
+ char *relname; Oid reloid; bool found; \
+ relname = (RELATION->rd_rel->relname).data; \
+ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
+ relname, \
+ HASH_ENTER, \
+ &found); \
+ if (namehentry == NULL) { \
+ elog(FATAL, "can't insert into relation descriptor cache"); \
+ } \
+ if (found && !IsBootstrapProcessingMode()) { \
+ /* used to give notice -- now just keep quiet */ ; \
+ } \
+ namehentry->reldesc = RELATION; \
+ reloid = RELATION->rd_id; \
+ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
+ (char *)&reloid, \
+ HASH_ENTER, \
+ &found); \
+ if (idhentry == NULL) { \
+ elog(FATAL, "can't insert into relation descriptor cache"); \
+ } \
+ if (found && !IsBootstrapProcessingMode()) { \
+ /* used to give notice -- now just keep quiet */ ; \
+ } \
+ idhentry->reldesc = RELATION; \
+ }
+#define RelationNameCacheLookup(NAME, RELATION) \
+ { RelNameCacheEnt *hentry; bool found; \
+ hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
+ (char *)NAME,HASH_FIND,&found); \
+ if (hentry == NULL) { \
+ elog(FATAL, "error in CACHE"); \
+ } \
+ if (found) { \
+ RELATION = hentry->reldesc; \
+ } \
+ else { \
+ RELATION = NULL; \
+ } \
+ }
+#define RelationIdCacheLookup(ID, RELATION) \
+ { RelIdCacheEnt *hentry; bool found; \
+ hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
+ (char *)&(ID),HASH_FIND, &found); \
+ if (hentry == NULL) { \
+ elog(FATAL, "error in CACHE"); \
+ } \
+ if (found) { \
+ RELATION = hentry->reldesc; \
+ } \
+ else { \
+ RELATION = NULL; \
+ } \
+ }
#define RelationCacheDelete(RELATION) \
- { RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \
- char *relname; Oid reloid; bool found; \
- relname = (RELATION->rd_rel->relname).data; \
- namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- relname, \
- HASH_REMOVE, \
- &found); \
- if (namehentry == NULL) { \
- elog(FATAL, "can't delete from relation descriptor cache"); \
- } \
- if (!found) { \
- elog(NOTICE, "trying to delete a reldesc that does not exist."); \
- } \
- reloid = RELATION->rd_id; \
- idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&reloid, \
- HASH_REMOVE, &found); \
- if (idhentry == NULL) { \
- elog(FATAL, "can't delete from relation descriptor cache"); \
- } \
- if (!found) { \
- elog(NOTICE, "trying to delete a reldesc that does not exist."); \
- } \
- }
+ { RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \
+ char *relname; Oid reloid; bool found; \
+ relname = (RELATION->rd_rel->relname).data; \
+ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
+ relname, \
+ HASH_REMOVE, \
+ &found); \
+ if (namehentry == NULL) { \
+ elog(FATAL, "can't delete from relation descriptor cache"); \
+ } \
+ if (!found) { \
+ elog(NOTICE, "trying to delete a reldesc that does not exist."); \
+ } \
+ reloid = RELATION->rd_id; \
+ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
+ (char *)&reloid, \
+ HASH_REMOVE, &found); \
+ if (idhentry == NULL) { \
+ elog(FATAL, "can't delete from relation descriptor cache"); \
+ } \
+ if (!found) { \
+ elog(NOTICE, "trying to delete a reldesc that does not exist."); \
+ } \
+ }
/* non-export function prototypes */
-static void formrdesc(char *relationName, u_int natts,
- FormData_pg_attribute att[]);
+static void
+formrdesc(char *relationName, u_int natts,
+ FormData_pg_attribute att[]);
+
+#if 0 /* See comments at line 1304 */
+static void RelationFlushIndexes(Relation * r, Oid accessMethodId);
-#if 0 /* See comments at line 1304 */
-static void RelationFlushIndexes(Relation *r, Oid accessMethodId);
#endif
static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo);
static HeapTuple scan_pg_rel_seq(RelationBuildDescInfo buildinfo);
static HeapTuple scan_pg_rel_ind(RelationBuildDescInfo buildinfo);
static Relation AllocateRelationDesc(u_int natts, Form_pg_class relp);
-static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
- Relation relation, u_int natts);
-static void build_tupdesc_seq(RelationBuildDescInfo buildinfo,
- Relation relation, u_int natts);
-static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
- Relation relation, u_int natts);
+static void
+RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
+ Relation relation, u_int natts);
+static void
+build_tupdesc_seq(RelationBuildDescInfo buildinfo,
+ Relation relation, u_int natts);
+static void
+build_tupdesc_ind(RelationBuildDescInfo buildinfo,
+ Relation relation, u_int natts);
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
-static void IndexedAccessMethodInitialize(Relation relation);
-static void AttrDefaultFetch (Relation relation);
-static void RelCheckFetch (Relation relation);
+static void IndexedAccessMethodInitialize(Relation relation);
+static void AttrDefaultFetch(Relation relation);
+static void RelCheckFetch(Relation relation);
-extern void RelationBuildTriggers (Relation relation);
-extern void FreeTriggerDesc (Relation relation);
+extern void RelationBuildTriggers(Relation relation);
+extern void FreeTriggerDesc(Relation relation);
/*
* newlyCreatedRelns -
- * relations created during this transaction. We need to keep track of
- * these.
+ * relations created during this transaction. We need to keep track of
+ * these.
*/
-static List *newlyCreatedRelns = NULL;
+static List *newlyCreatedRelns = NULL;
/* ----------------------------------------------------------------
- * RelationIdGetRelation() and RelationNameGetRelation()
- * support functions
+ * RelationIdGetRelation() and RelationNameGetRelation()
+ * support functions
* ----------------------------------------------------------------
*/
-
-#if NOT_USED /* XXX This doesn't seem to be used anywhere */
+
+#if NOT_USED /* XXX This doesn't seem to be used
+ * anywhere */
/* --------------------------------
- * BuildDescInfoError returns a string appropriate to
- * the buildinfo passed to it
+ * BuildDescInfoError returns a string appropriate to
+ * the buildinfo passed to it
* --------------------------------
*/
-static char *
+static char *
BuildDescInfoError(RelationBuildDescInfo buildinfo)
{
- static char errBuf[64];
-
- memset(errBuf, 0, (int) sizeof(errBuf));
- switch(buildinfo.infotype) {
- case INFO_RELID:
- sprintf(errBuf, "(relation id %d)", buildinfo.i.info_id);
- break;
- case INFO_RELNAME:
- sprintf(errBuf, "(relation name %s)", buildinfo.i.info_name);
- break;
- }
-
- return errBuf;
+ static char errBuf[64];
+
+ memset(errBuf, 0, (int) sizeof(errBuf));
+ switch (buildinfo.infotype)
+ {
+ case INFO_RELID:
+ sprintf(errBuf, "(relation id %d)", buildinfo.i.info_id);
+ break;
+ case INFO_RELNAME:
+ sprintf(errBuf, "(relation name %s)", buildinfo.i.info_name);
+ break;
+ }
+
+ return errBuf;
}
+
#endif
/* --------------------------------
- * ScanPgRelation
+ * ScanPgRelation
*
- * this is used by RelationBuildDesc to find a pg_class
- * tuple matching either a relation name or a relation id
- * as specified in buildinfo.
+ * this is used by RelationBuildDesc to find a pg_class
+ * tuple matching either a relation name or a relation id
+ * as specified in buildinfo.
* --------------------------------
*/
-static HeapTuple
+static HeapTuple
ScanPgRelation(RelationBuildDescInfo buildinfo)
{
- /*
- * If this is bootstrap time (initdb), then we can't use the system
- * catalog indices, because they may not exist yet. Otherwise, we
- * can, and do.
- */
-
- if (IsBootstrapProcessingMode())
- return (scan_pg_rel_seq(buildinfo));
- else
- return (scan_pg_rel_ind(buildinfo));
+
+ /*
+ * If this is bootstrap time (initdb), then we can't use the system
+ * catalog indices, because they may not exist yet. Otherwise, we
+ * can, and do.
+ */
+
+ if (IsBootstrapProcessingMode())
+ return (scan_pg_rel_seq(buildinfo));
+ else
+ return (scan_pg_rel_ind(buildinfo));
}
-static HeapTuple
+static HeapTuple
scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
{
- HeapTuple pg_class_tuple;
- HeapTuple return_tuple;
- Relation pg_class_desc;
- HeapScanDesc pg_class_scan;
- ScanKeyData key;
- Buffer buf;
-
- /* ----------------
- * form a scan key
- * ----------------
- */
- switch (buildinfo.infotype) {
- case INFO_RELID:
- ScanKeyEntryInitialize(&key, 0,
- ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(buildinfo.i.info_id));
- break;
-
- case INFO_RELNAME:
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_class_relname,
- Character16EqualRegProcedure,
- NameGetDatum(buildinfo.i.info_name));
- break;
-
- default:
- elog(WARN, "ScanPgRelation: bad buildinfo");
- return NULL;
- }
-
- /* ----------------
- * open pg_class and fetch a tuple
- * ----------------
- */
- pg_class_desc = heap_openr(RelationRelationName);
- if (!IsInitProcessingMode())
- RelationSetLockForRead(pg_class_desc);
- pg_class_scan =
- heap_beginscan(pg_class_desc, 0, NowTimeQual, 1, &key);
- pg_class_tuple = heap_getnext(pg_class_scan, 0, &buf);
-
- /* ----------------
- * get set to return tuple
- * ----------------
- */
- if (! HeapTupleIsValid(pg_class_tuple)) {
- return_tuple = pg_class_tuple;
- } else {
- /* ------------------
- * a satanic bug used to live here: pg_class_tuple used to be
- * returned here without having the corresponding buffer pinned.
- * so when the buffer gets replaced, all hell breaks loose.
- * this bug is discovered and killed by wei on 9/27/91.
- * -------------------
+ HeapTuple pg_class_tuple;
+ HeapTuple return_tuple;
+ Relation pg_class_desc;
+ HeapScanDesc pg_class_scan;
+ ScanKeyData key;
+ Buffer buf;
+
+ /* ----------------
+ * form a scan key
+ * ----------------
*/
- return_tuple = (HeapTuple) palloc((Size) pg_class_tuple->t_len);
- memmove((char *) return_tuple,
- (char *) pg_class_tuple,
- (int) pg_class_tuple->t_len);
- ReleaseBuffer(buf);
- }
-
- /* all done */
- heap_endscan(pg_class_scan);
- if (!IsInitProcessingMode())
- RelationUnsetLockForRead(pg_class_desc);
- heap_close(pg_class_desc);
-
- return return_tuple;
+ switch (buildinfo.infotype)
+ {
+ case INFO_RELID:
+ ScanKeyEntryInitialize(&key, 0,
+ ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(buildinfo.i.info_id));
+ break;
+
+ case INFO_RELNAME:
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_class_relname,
+ Character16EqualRegProcedure,
+ NameGetDatum(buildinfo.i.info_name));
+ break;
+
+ default:
+ elog(WARN, "ScanPgRelation: bad buildinfo");
+ return NULL;
+ }
+
+ /* ----------------
+ * open pg_class and fetch a tuple
+ * ----------------
+ */
+ pg_class_desc = heap_openr(RelationRelationName);
+ if (!IsInitProcessingMode())
+ RelationSetLockForRead(pg_class_desc);
+ pg_class_scan =
+ heap_beginscan(pg_class_desc, 0, NowTimeQual, 1, &key);
+ pg_class_tuple = heap_getnext(pg_class_scan, 0, &buf);
+
+ /* ----------------
+ * get set to return tuple
+ * ----------------
+ */
+ if (!HeapTupleIsValid(pg_class_tuple))
+ {
+ return_tuple = pg_class_tuple;
+ }
+ else
+ {
+ /* ------------------
+ * a satanic bug used to live here: pg_class_tuple used to be
+ * returned here without having the corresponding buffer pinned.
+ * so when the buffer gets replaced, all hell breaks loose.
+ * this bug is discovered and killed by wei on 9/27/91.
+ * -------------------
+ */
+ return_tuple = (HeapTuple) palloc((Size) pg_class_tuple->t_len);
+ memmove((char *) return_tuple,
+ (char *) pg_class_tuple,
+ (int) pg_class_tuple->t_len);
+ ReleaseBuffer(buf);
+ }
+
+ /* all done */
+ heap_endscan(pg_class_scan);
+ if (!IsInitProcessingMode())
+ RelationUnsetLockForRead(pg_class_desc);
+ heap_close(pg_class_desc);
+
+ return return_tuple;
}
-static HeapTuple
+static HeapTuple
scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
{
- Relation pg_class_desc;
- HeapTuple return_tuple;
-
- pg_class_desc = heap_openr(RelationRelationName);
- if (!IsInitProcessingMode())
- RelationSetLockForRead(pg_class_desc);
-
- switch (buildinfo.infotype) {
- case INFO_RELID:
- return_tuple = ClassOidIndexScan(pg_class_desc, buildinfo.i.info_id);
- break;
-
- case INFO_RELNAME:
- return_tuple = ClassNameIndexScan(pg_class_desc,
- buildinfo.i.info_name);
- break;
-
- default:
- elog(WARN, "ScanPgRelation: bad buildinfo");
- /* XXX I hope this is right. It seems better than returning
- * an uninitialized value */
- return_tuple = NULL;
- }
-
- /* all done */
- if (!IsInitProcessingMode())
- RelationUnsetLockForRead(pg_class_desc);
- heap_close(pg_class_desc);
-
- return return_tuple;
+ Relation pg_class_desc;
+ HeapTuple return_tuple;
+
+ pg_class_desc = heap_openr(RelationRelationName);
+ if (!IsInitProcessingMode())
+ RelationSetLockForRead(pg_class_desc);
+
+ switch (buildinfo.infotype)
+ {
+ case INFO_RELID:
+ return_tuple = ClassOidIndexScan(pg_class_desc, buildinfo.i.info_id);
+ break;
+
+ case INFO_RELNAME:
+ return_tuple = ClassNameIndexScan(pg_class_desc,
+ buildinfo.i.info_name);
+ break;
+
+ default:
+ elog(WARN, "ScanPgRelation: bad buildinfo");
+
+ /*
+ * XXX I hope this is right. It seems better than returning an
+ * uninitialized value
+ */
+ return_tuple = NULL;
+ }
+
+ /* all done */
+ if (!IsInitProcessingMode())
+ RelationUnsetLockForRead(pg_class_desc);
+ heap_close(pg_class_desc);
+
+ return return_tuple;
}
/* ----------------
- * AllocateRelationDesc
+ * AllocateRelationDesc
*
- * This is used to allocate memory for a new relation descriptor
- * and initialize the rd_rel field.
+ * This is used to allocate memory for a new relation descriptor
+ * and initialize the rd_rel field.
* ----------------
*/
-static Relation
+static Relation
AllocateRelationDesc(u_int natts, Form_pg_class relp)
{
- Relation relation;
- Size len;
- Form_pg_class relationTupleForm;
-
- /* ----------------
- * allocate space for the relation tuple form
- * ----------------
- */
- relationTupleForm = (Form_pg_class)
- palloc((Size) (sizeof(FormData_pg_class)));
-
- memmove((char *) relationTupleForm, (char *) relp, CLASS_TUPLE_SIZE);
-
- /* ----------------
- * allocate space for new relation descriptor
- */
- len = sizeof(RelationData) + 10; /* + 10 is voodoo XXX mao */
-
- relation = (Relation) palloc(len);
-
- /* ----------------
- * clear new reldesc
- * ----------------
- */
- memset((char *) relation, 0, len);
-
- /* initialize attribute tuple form */
- relation->rd_att = CreateTemplateTupleDesc(natts);
-
- /*and initialize relation tuple form */
- relation->rd_rel = relationTupleForm;
-
- return relation;
+ Relation relation;
+ Size len;
+ Form_pg_class relationTupleForm;
+
+ /* ----------------
+ * allocate space for the relation tuple form
+ * ----------------
+ */
+ relationTupleForm = (Form_pg_class)
+ palloc((Size) (sizeof(FormData_pg_class)));
+
+ memmove((char *) relationTupleForm, (char *) relp, CLASS_TUPLE_SIZE);
+
+ /* ----------------
+ * allocate space for new relation descriptor
+ */
+ len = sizeof(RelationData) + 10; /* + 10 is voodoo XXX mao */
+
+ relation = (Relation) palloc(len);
+
+ /* ----------------
+ * clear new reldesc
+ * ----------------
+ */
+ memset((char *) relation, 0, len);
+
+ /* initialize attribute tuple form */
+ relation->rd_att = CreateTemplateTupleDesc(natts);
+
+ /* and initialize relation tuple form */
+ relation->rd_rel = relationTupleForm;
+
+ return relation;
}
/* --------------------------------
- * RelationBuildTupleDesc
+ * RelationBuildTupleDesc
*
- * Form the relation's tuple descriptor from information in
- * the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
+ * Form the relation's tuple descriptor from information in
+ * the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
* --------------------------------
*/
static void
-RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
- Relation relation,
- u_int natts)
+RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
+ Relation relation,
+ u_int natts)
{
- /*
- * If this is bootstrap time (initdb), then we can't use the system
- * catalog indices, because they may not exist yet. Otherwise, we
- * can, and do.
- */
-
- if (IsBootstrapProcessingMode())
- build_tupdesc_seq(buildinfo, relation, natts);
- else
- build_tupdesc_ind(buildinfo, relation, natts);
+
+ /*
+ * If this is bootstrap time (initdb), then we can't use the system
+ * catalog indices, because they may not exist yet. Otherwise, we
+ * can, and do.
+ */
+
+ if (IsBootstrapProcessingMode())
+ build_tupdesc_seq(buildinfo, relation, natts);
+ else
+ build_tupdesc_ind(buildinfo, relation, natts);
}
static void
build_tupdesc_seq(RelationBuildDescInfo buildinfo,
- Relation relation,
- u_int natts)
+ Relation relation,
+ u_int natts)
{
- HeapTuple pg_attribute_tuple;
- Relation pg_attribute_desc;
- HeapScanDesc pg_attribute_scan;
- AttributeTupleForm attp;
- ScanKeyData key;
- int need;
-
- /* ----------------
- * form a scan key
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_attribute_attrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- /* ----------------
- * open pg_attribute and begin a scan
- * ----------------
- */
- pg_attribute_desc = heap_openr(AttributeRelationName);
- pg_attribute_scan =
- heap_beginscan(pg_attribute_desc, 0, NowTimeQual, 1, &key);
-
- /* ----------------
- * add attribute data to relation->rd_att
- * ----------------
- */
- need = natts;
-
- pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
- while (HeapTupleIsValid(pg_attribute_tuple) && need > 0) {
- attp = (AttributeTupleForm) GETSTRUCT(pg_attribute_tuple);
-
- if (attp->attnum > 0) {
- relation->rd_att->attrs[attp->attnum - 1] =
- (AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
-
- memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]),
- (char *) attp,
- ATTRIBUTE_TUPLE_SIZE);
- need--;
+ HeapTuple pg_attribute_tuple;
+ Relation pg_attribute_desc;
+ HeapScanDesc pg_attribute_scan;
+ AttributeTupleForm attp;
+ ScanKeyData key;
+ int need;
+
+ /* ----------------
+ * form a scan key
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_attribute_attrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ /* ----------------
+ * open pg_attribute and begin a scan
+ * ----------------
+ */
+ pg_attribute_desc = heap_openr(AttributeRelationName);
+ pg_attribute_scan =
+ heap_beginscan(pg_attribute_desc, 0, NowTimeQual, 1, &key);
+
+ /* ----------------
+ * add attribute data to relation->rd_att
+ * ----------------
+ */
+ need = natts;
+
+ pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
+ while (HeapTupleIsValid(pg_attribute_tuple) && need > 0)
+ {
+ attp = (AttributeTupleForm) GETSTRUCT(pg_attribute_tuple);
+
+ if (attp->attnum > 0)
+ {
+ relation->rd_att->attrs[attp->attnum - 1] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+
+ memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]),
+ (char *) attp,
+ ATTRIBUTE_TUPLE_SIZE);
+ need--;
+ }
+ pg_attribute_tuple = heap_getnext(pg_attribute_scan,
+ 0, (Buffer *) NULL);
}
- pg_attribute_tuple = heap_getnext(pg_attribute_scan,
- 0, (Buffer *) NULL);
- }
-
- if (need > 0)
- elog(WARN, "catalog is missing %d attribute%s for relid %d",
- need, (need == 1 ? "" : "s"), relation->rd_id);
-
- /* ----------------
- * end the scan and close the attribute relation
- * ----------------
- */
- heap_endscan(pg_attribute_scan);
- heap_close(pg_attribute_desc);
+
+ if (need > 0)
+ elog(WARN, "catalog is missing %d attribute%s for relid %d",
+ need, (need == 1 ? "" : "s"), relation->rd_id);
+
+ /* ----------------
+ * end the scan and close the attribute relation
+ * ----------------
+ */
+ heap_endscan(pg_attribute_scan);
+ heap_close(pg_attribute_desc);
}
static void
build_tupdesc_ind(RelationBuildDescInfo buildinfo,
- Relation relation,
- u_int natts)
+ Relation relation,
+ u_int natts)
{
- Relation attrel;
- HeapTuple atttup;
- AttributeTupleForm attp;
- TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
- AttrDefault *attrdef = NULL;
- int ndef = 0;
- int i;
-
- constr->has_not_null = false;
-
- attrel = heap_openr(AttributeRelationName);
-
- for (i = 1; i <= relation->rd_rel->relnatts; i++) {
-
- atttup = (HeapTuple) AttributeNumIndexScan(attrel, relation->rd_id, i);
-
- if (!HeapTupleIsValid(atttup))
- elog(WARN, "cannot find attribute %d of relation %.*s", i,
- NAMEDATALEN, &(relation->rd_rel->relname.data[0]));
- attp = (AttributeTupleForm) GETSTRUCT(atttup);
-
- relation->rd_att->attrs[i - 1] =
- (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
-
- memmove((char *) (relation->rd_att->attrs[i - 1]),
- (char *) attp,
- ATTRIBUTE_TUPLE_SIZE);
-
- /* Update if this attribute have a constraint */
- if (attp->attnotnull)
- constr->has_not_null = true;
-
- if (attp->atthasdef)
+ Relation attrel;
+ HeapTuple atttup;
+ AttributeTupleForm attp;
+ TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
+ AttrDefault *attrdef = NULL;
+ int ndef = 0;
+ int i;
+
+ constr->has_not_null = false;
+
+ attrel = heap_openr(AttributeRelationName);
+
+ for (i = 1; i <= relation->rd_rel->relnatts; i++)
{
- if ( attrdef == NULL )
- attrdef = (AttrDefault*) palloc (relation->rd_rel->relnatts *
- sizeof (AttrDefault));
- attrdef[ndef].adnum = i;
- attrdef[ndef].adbin = NULL;
- attrdef[ndef].adsrc = NULL;
- ndef++;
+
+ atttup = (HeapTuple) AttributeNumIndexScan(attrel, relation->rd_id, i);
+
+ if (!HeapTupleIsValid(atttup))
+ elog(WARN, "cannot find attribute %d of relation %.*s", i,
+ NAMEDATALEN, &(relation->rd_rel->relname.data[0]));
+ attp = (AttributeTupleForm) GETSTRUCT(atttup);
+
+ relation->rd_att->attrs[i - 1] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+
+ memmove((char *) (relation->rd_att->attrs[i - 1]),
+ (char *) attp,
+ ATTRIBUTE_TUPLE_SIZE);
+
+ /* Update if this attribute have a constraint */
+ if (attp->attnotnull)
+ constr->has_not_null = true;
+
+ if (attp->atthasdef)
+ {
+ if (attrdef == NULL)
+ attrdef = (AttrDefault *) palloc(relation->rd_rel->relnatts *
+ sizeof(AttrDefault));
+ attrdef[ndef].adnum = i;
+ attrdef[ndef].adbin = NULL;
+ attrdef[ndef].adsrc = NULL;
+ ndef++;
+ }
}
- }
-
- heap_close(attrel);
-
- if ( constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks )
- {
- relation->rd_att->constr = constr;
-
- if ( ndef > 0 ) /* DEFAULTs */
- {
- if ( ndef < relation->rd_rel->relnatts )
- constr->defval = (AttrDefault*)
- repalloc (attrdef, ndef * sizeof (AttrDefault));
- else
- constr->defval = attrdef;
- constr->num_defval = ndef;
- AttrDefaultFetch (relation);
- }
- else
- constr->num_defval = 0;
-
- if ( relation->rd_rel->relchecks > 0 ) /* CHECKs */
+
+ heap_close(attrel);
+
+ if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)
{
- constr->num_check = relation->rd_rel->relchecks;
- constr->check = (ConstrCheck *) palloc (constr->num_check *
- sizeof (ConstrCheck));
- memset (constr->check, 0, constr->num_check * sizeof (ConstrCheck));
- RelCheckFetch (relation);
+ relation->rd_att->constr = constr;
+
+ if (ndef > 0) /* DEFAULTs */
+ {
+ if (ndef < relation->rd_rel->relnatts)
+ constr->defval = (AttrDefault *)
+ repalloc(attrdef, ndef * sizeof(AttrDefault));
+ else
+ constr->defval = attrdef;
+ constr->num_defval = ndef;
+ AttrDefaultFetch(relation);
+ }
+ else
+ constr->num_defval = 0;
+
+ if (relation->rd_rel->relchecks > 0) /* CHECKs */
+ {
+ constr->num_check = relation->rd_rel->relchecks;
+ constr->check = (ConstrCheck *) palloc(constr->num_check *
+ sizeof(ConstrCheck));
+ memset(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
+ RelCheckFetch(relation);
+ }
+ else
+ constr->num_check = 0;
}
else
- constr->num_check = 0;
- }
- else
- {
- pfree (constr);
- relation->rd_att->constr = NULL;
- }
-
+ {
+ pfree(constr);
+ relation->rd_att->constr = NULL;
+ }
+
}
/* --------------------------------
- * RelationBuildRuleLock
+ * RelationBuildRuleLock
*
- * Form the relation's rewrite rules from information in
- * the pg_rewrite system catalog.
+ * Form the relation's rewrite rules from information in
+ * the pg_rewrite system catalog.
* --------------------------------
*/
static void
RelationBuildRuleLock(Relation relation)
{
- HeapTuple pg_rewrite_tuple;
- Relation pg_rewrite_desc;
- TupleDesc pg_rewrite_tupdesc;
- HeapScanDesc pg_rewrite_scan;
- ScanKeyData key;
- RuleLock *rulelock;
- int numlocks;
- RewriteRule **rules;
- int maxlocks;
-
- /* ----------------
- * form an array to hold the rewrite rules (the array is extended if
- * necessary)
- * ----------------
- */
- maxlocks = 4;
- rules = (RewriteRule **)palloc(sizeof(RewriteRule*)*maxlocks);
- numlocks = 0;
-
- /* ----------------
- * form a scan key
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_rewrite_ev_class,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- /* ----------------
- * open pg_attribute and begin a scan
- * ----------------
- */
- pg_rewrite_desc = heap_openr(RewriteRelationName);
- pg_rewrite_scan =
- heap_beginscan(pg_rewrite_desc, 0, NowTimeQual, 1, &key);
- pg_rewrite_tupdesc =
- RelationGetTupleDescriptor(pg_rewrite_desc);
-
- /* ----------------
- * add attribute data to relation->rd_att
- * ----------------
- */
- while ((pg_rewrite_tuple = heap_getnext(pg_rewrite_scan, 0,
- (Buffer *) NULL)) != NULL) {
- bool isnull;
- char *ruleaction = NULL;
- char *rule_evqual_string;
- RewriteRule *rule;
-
- rule = (RewriteRule *)palloc(sizeof(RewriteRule));
-
- rule->ruleId = pg_rewrite_tuple->t_oid;
-
- rule->event =
- (int)heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_ev_type, pg_rewrite_tupdesc,
- &isnull) - 48;
- rule->attrno =
- (int)heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_ev_attr, pg_rewrite_tupdesc,
- &isnull);
- rule->isInstead =
- !!heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_is_instead, pg_rewrite_tupdesc,
- &isnull);
-
- ruleaction =
- heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_action, pg_rewrite_tupdesc,
- &isnull);
- rule_evqual_string =
- heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_ev_qual, pg_rewrite_tupdesc,
- &isnull);
-
- ruleaction = textout((struct varlena *)ruleaction);
- rule_evqual_string = textout((struct varlena *)rule_evqual_string);
-
- rule->actions = (List*)stringToNode(ruleaction);
- rule->qual = (Node*)stringToNode(rule_evqual_string);
-
- rules[numlocks++] = rule;
- if (numlocks==maxlocks) {
- maxlocks *= 2;
- rules =
- (RewriteRule **)repalloc(rules, sizeof(RewriteRule*)*maxlocks);
+ HeapTuple pg_rewrite_tuple;
+ Relation pg_rewrite_desc;
+ TupleDesc pg_rewrite_tupdesc;
+ HeapScanDesc pg_rewrite_scan;
+ ScanKeyData key;
+ RuleLock *rulelock;
+ int numlocks;
+ RewriteRule **rules;
+ int maxlocks;
+
+ /* ----------------
+ * form an array to hold the rewrite rules (the array is extended if
+ * necessary)
+ * ----------------
+ */
+ maxlocks = 4;
+ rules = (RewriteRule **) palloc(sizeof(RewriteRule *) * maxlocks);
+ numlocks = 0;
+
+ /* ----------------
+ * form a scan key
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_rewrite_ev_class,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ /* ----------------
+ * open pg_attribute and begin a scan
+ * ----------------
+ */
+ pg_rewrite_desc = heap_openr(RewriteRelationName);
+ pg_rewrite_scan =
+ heap_beginscan(pg_rewrite_desc, 0, NowTimeQual, 1, &key);
+ pg_rewrite_tupdesc =
+ RelationGetTupleDescriptor(pg_rewrite_desc);
+
+ /* ----------------
+ * add attribute data to relation->rd_att
+ * ----------------
+ */
+ while ((pg_rewrite_tuple = heap_getnext(pg_rewrite_scan, 0,
+ (Buffer *) NULL)) != NULL)
+ {
+ bool isnull;
+ char *ruleaction = NULL;
+ char *rule_evqual_string;
+ RewriteRule *rule;
+
+ rule = (RewriteRule *) palloc(sizeof(RewriteRule));
+
+ rule->ruleId = pg_rewrite_tuple->t_oid;
+
+ rule->event =
+ (int) heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_type, pg_rewrite_tupdesc,
+ &isnull) - 48;
+ rule->attrno =
+ (int) heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_attr, pg_rewrite_tupdesc,
+ &isnull);
+ rule->isInstead =
+ !!heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_is_instead, pg_rewrite_tupdesc,
+ &isnull);
+
+ ruleaction =
+ heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_action, pg_rewrite_tupdesc,
+ &isnull);
+ rule_evqual_string =
+ heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_qual, pg_rewrite_tupdesc,
+ &isnull);
+
+ ruleaction = textout((struct varlena *) ruleaction);
+ rule_evqual_string = textout((struct varlena *) rule_evqual_string);
+
+ rule->actions = (List *) stringToNode(ruleaction);
+ rule->qual = (Node *) stringToNode(rule_evqual_string);
+
+ rules[numlocks++] = rule;
+ if (numlocks == maxlocks)
+ {
+ maxlocks *= 2;
+ rules =
+ (RewriteRule **) repalloc(rules, sizeof(RewriteRule *) * maxlocks);
+ }
}
- }
-
- /* ----------------
- * end the scan and close the attribute relation
- * ----------------
- */
- heap_endscan(pg_rewrite_scan);
- heap_close(pg_rewrite_desc);
-
- /* ----------------
- * form a RuleLock and insert into relation
- * ----------------
- */
- rulelock = (RuleLock *)palloc(sizeof(RuleLock));
- rulelock->numLocks = numlocks;
- rulelock->rules = rules;
-
- relation->rd_rules = rulelock;
- return;
+
+ /* ----------------
+ * end the scan and close the attribute relation
+ * ----------------
+ */
+ heap_endscan(pg_rewrite_scan);
+ heap_close(pg_rewrite_desc);
+
+ /* ----------------
+ * form a RuleLock and insert into relation
+ * ----------------
+ */
+ rulelock = (RuleLock *) palloc(sizeof(RuleLock));
+ rulelock->numLocks = numlocks;
+ rulelock->rules = rules;
+
+ relation->rd_rules = rulelock;
+ return;
}
/* --------------------------------
- * RelationBuildDesc
- *
- * To build a relation descriptor, we have to allocate space,
- * open the underlying unix file and initialize the following
- * fields:
+ * RelationBuildDesc
+ *
+ * To build a relation descriptor, we have to allocate space,
+ * open the underlying unix file and initialize the following
+ * fields:
*
- * File rd_fd; open file descriptor
- * int rd_nblocks; number of blocks in rel
- * it will be set in ambeginscan()
- * uint16 rd_refcnt; reference count
- * Form_pg_am rd_am; AM tuple
- * Form_pg_class rd_rel; RELATION tuple
- * Oid rd_id; relations's object id
- * Pointer lockInfo; ptr. to misc. info.
- * TupleDesc rd_att; tuple desciptor
+ * File rd_fd; open file descriptor
+ * int rd_nblocks; number of blocks in rel
+ * it will be set in ambeginscan()
+ * uint16 rd_refcnt; reference count
+ * Form_pg_am rd_am; AM tuple
+ * Form_pg_class rd_rel; RELATION tuple
+ * Oid rd_id; relations's object id
+ * Pointer lockInfo; ptr. to misc. info.
+ * TupleDesc rd_att; tuple desciptor
*
- * Note: rd_ismem (rel is in-memory only) is currently unused
- * by any part of the system. someday this will indicate that
- * the relation lives only in the main-memory buffer pool
- * -cim 2/4/91
+ * Note: rd_ismem (rel is in-memory only) is currently unused
+ * by any part of the system. someday this will indicate that
+ * the relation lives only in the main-memory buffer pool
+ * -cim 2/4/91
* --------------------------------
*/
-static Relation
+static Relation
RelationBuildDesc(RelationBuildDescInfo buildinfo)
{
- File fd;
- Relation relation;
- u_int natts;
- Oid relid;
- Oid relam;
- Form_pg_class relp;
-
- MemoryContext oldcxt;
-
- HeapTuple pg_class_tuple;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * find the tuple in pg_class corresponding to the given relation id
- * ----------------
- */
- pg_class_tuple = ScanPgRelation(buildinfo);
-
- /* ----------------
- * if no such tuple exists, return NULL
- * ----------------
- */
- if (! HeapTupleIsValid(pg_class_tuple)) {
-
- MemoryContextSwitchTo(oldcxt);
-
- return NULL;
- }
-
- /* ----------------
- * get information from the pg_class_tuple
- * ----------------
- */
- relid = pg_class_tuple->t_oid;
- relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
- natts = relp->relnatts;
-
- /* ----------------
- * allocate storage for the relation descriptor,
- * initialize relation->rd_rel and get the access method id.
- * ----------------
- */
- relation = AllocateRelationDesc(natts, relp);
- relam = relation->rd_rel->relam;
-
- /* ----------------
- * initialize the relation's relation id (relation->rd_id)
- * ----------------
- */
- relation->rd_id = relid;
-
- /* ----------------
- * initialize relation->rd_refcnt
- * ----------------
- */
- RelationSetReferenceCount(relation, 1);
-
- /* ----------------
- * normal relations are not nailed into the cache
- * ----------------
- */
- relation->rd_isnailed = false;
-
- /* ----------------
- * initialize the access method information (relation->rd_am)
- * ----------------
- */
- if (OidIsValid(relam)) {
- relation->rd_am = (Form_pg_am)
- AccessMethodObjectIdGetAccessMethodTupleForm(relam);
- }
-
- /* ----------------
- * initialize the tuple descriptor (relation->rd_att).
- * remember, rd_att is an array of attribute pointers that lives
- * off the end of the relation descriptor structure so space was
- * already allocated for it by AllocateRelationDesc.
- * ----------------
- */
- RelationBuildTupleDesc(buildinfo, relation, natts);
-
- /* ----------------
- * initialize rules that affect this relation
- * ----------------
- */
- if (relp->relhasrules) {
- RelationBuildRuleLock(relation);
- } else {
- relation->rd_rules = NULL;
- }
-
- /* Triggers */
- if ( relp->reltriggers > 0 )
- RelationBuildTriggers (relation);
- else
- relation->trigdesc = NULL;
-
- /* ----------------
- * initialize index strategy and support information for this relation
- * ----------------
- */
- if (OidIsValid(relam)) {
- IndexedAccessMethodInitialize(relation);
- }
-
- /* ----------------
- * initialize the relation lock manager information
- * ----------------
- */
- RelationInitLockInfo(relation); /* see lmgr.c */
-
- /* ----------------
- * open the relation and assign the file descriptor returned
- * by the storage manager code to rd_fd.
- * ----------------
- */
- fd = smgropen(relp->relsmgr, relation);
-
- Assert (fd >= -1);
- if (fd == -1)
- elog(NOTICE, "RelationIdBuildRelation: smgropen(%s): %m",
- &relp->relname);
-
- relation->rd_fd = fd;
-
- /* ----------------
- * insert newly created relation into proper relcaches,
- * restore memory context and return the new reldesc.
- * ----------------
- */
-
- RelationCacheInsert(relation);
-
- /* -------------------
- * free the memory allocated for pg_class_tuple
- * and for lock data pointed to by pg_class_tuple
- * -------------------
- */
- pfree(pg_class_tuple);
-
- MemoryContextSwitchTo(oldcxt);
-
- return relation;
+ File fd;
+ Relation relation;
+ u_int natts;
+ Oid relid;
+ Oid relam;
+ Form_pg_class relp;
+
+ MemoryContext oldcxt;
+
+ HeapTuple pg_class_tuple;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * find the tuple in pg_class corresponding to the given relation id
+ * ----------------
+ */
+ pg_class_tuple = ScanPgRelation(buildinfo);
+
+ /* ----------------
+ * if no such tuple exists, return NULL
+ * ----------------
+ */
+ if (!HeapTupleIsValid(pg_class_tuple))
+ {
+
+ MemoryContextSwitchTo(oldcxt);
+
+ return NULL;
+ }
+
+ /* ----------------
+ * get information from the pg_class_tuple
+ * ----------------
+ */
+ relid = pg_class_tuple->t_oid;
+ relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
+ natts = relp->relnatts;
+
+ /* ----------------
+ * allocate storage for the relation descriptor,
+ * initialize relation->rd_rel and get the access method id.
+ * ----------------
+ */
+ relation = AllocateRelationDesc(natts, relp);
+ relam = relation->rd_rel->relam;
+
+ /* ----------------
+ * initialize the relation's relation id (relation->rd_id)
+ * ----------------
+ */
+ relation->rd_id = relid;
+
+ /* ----------------
+ * initialize relation->rd_refcnt
+ * ----------------
+ */
+ RelationSetReferenceCount(relation, 1);
+
+ /* ----------------
+ * normal relations are not nailed into the cache
+ * ----------------
+ */
+ relation->rd_isnailed = false;
+
+ /* ----------------
+ * initialize the access method information (relation->rd_am)
+ * ----------------
+ */
+ if (OidIsValid(relam))
+ {
+ relation->rd_am = (Form_pg_am)
+ AccessMethodObjectIdGetAccessMethodTupleForm(relam);
+ }
+
+ /* ----------------
+ * initialize the tuple descriptor (relation->rd_att).
+ * remember, rd_att is an array of attribute pointers that lives
+ * off the end of the relation descriptor structure so space was
+ * already allocated for it by AllocateRelationDesc.
+ * ----------------
+ */
+ RelationBuildTupleDesc(buildinfo, relation, natts);
+
+ /* ----------------
+ * initialize rules that affect this relation
+ * ----------------
+ */
+ if (relp->relhasrules)
+ {
+ RelationBuildRuleLock(relation);
+ }
+ else
+ {
+ relation->rd_rules = NULL;
+ }
+
+ /* Triggers */
+ if (relp->reltriggers > 0)
+ RelationBuildTriggers(relation);
+ else
+ relation->trigdesc = NULL;
+
+ /* ----------------
+ * initialize index strategy and support information for this relation
+ * ----------------
+ */
+ if (OidIsValid(relam))
+ {
+ IndexedAccessMethodInitialize(relation);
+ }
+
+ /* ----------------
+ * initialize the relation lock manager information
+ * ----------------
+ */
+ RelationInitLockInfo(relation); /* see lmgr.c */
+
+ /* ----------------
+ * open the relation and assign the file descriptor returned
+ * by the storage manager code to rd_fd.
+ * ----------------
+ */
+ fd = smgropen(relp->relsmgr, relation);
+
+ Assert(fd >= -1);
+ if (fd == -1)
+ elog(NOTICE, "RelationIdBuildRelation: smgropen(%s): %m",
+ &relp->relname);
+
+ relation->rd_fd = fd;
+
+ /* ----------------
+ * insert newly created relation into proper relcaches,
+ * restore memory context and return the new reldesc.
+ * ----------------
+ */
+
+ RelationCacheInsert(relation);
+
+ /* -------------------
+ * free the memory allocated for pg_class_tuple
+ * and for lock data pointed to by pg_class_tuple
+ * -------------------
+ */
+ pfree(pg_class_tuple);
+
+ MemoryContextSwitchTo(oldcxt);
+
+ return relation;
}
static void
IndexedAccessMethodInitialize(Relation relation)
{
- IndexStrategy strategy;
- RegProcedure *support;
- int natts;
- Size stratSize;
- Size supportSize;
- uint16 relamstrategies;
- uint16 relamsupport;
-
- natts = relation->rd_rel->relnatts;
- relamstrategies = relation->rd_am->amstrategies;
- stratSize = AttributeNumberGetIndexStrategySize(natts, relamstrategies);
- strategy = (IndexStrategy) palloc(stratSize);
- relamsupport = relation->rd_am->amsupport;
-
- if (relamsupport > 0) {
- supportSize = natts * (relamsupport * sizeof (RegProcedure));
- support = (RegProcedure *) palloc(supportSize);
- } else {
- support = (RegProcedure *) NULL;
- }
-
- IndexSupportInitialize(strategy, support,
- relation->rd_att->attrs[0]->attrelid,
- relation->rd_rel->relam,
- relamstrategies, relamsupport, natts);
-
- RelationSetIndexSupport(relation, strategy, support);
+ IndexStrategy strategy;
+ RegProcedure *support;
+ int natts;
+ Size stratSize;
+ Size supportSize;
+ uint16 relamstrategies;
+ uint16 relamsupport;
+
+ natts = relation->rd_rel->relnatts;
+ relamstrategies = relation->rd_am->amstrategies;
+ stratSize = AttributeNumberGetIndexStrategySize(natts, relamstrategies);
+ strategy = (IndexStrategy) palloc(stratSize);
+ relamsupport = relation->rd_am->amsupport;
+
+ if (relamsupport > 0)
+ {
+ supportSize = natts * (relamsupport * sizeof(RegProcedure));
+ support = (RegProcedure *) palloc(supportSize);
+ }
+ else
+ {
+ support = (RegProcedure *) NULL;
+ }
+
+ IndexSupportInitialize(strategy, support,
+ relation->rd_att->attrs[0]->attrelid,
+ relation->rd_rel->relam,
+ relamstrategies, relamsupport, natts);
+
+ RelationSetIndexSupport(relation, strategy, support);
}
/* --------------------------------
- * formrdesc
+ * formrdesc
*
- * This is a special version of RelationBuildDesc()
- * used by RelationInitialize() in initializing the
- * relcache. The system relation descriptors built
- * here are all nailed in the descriptor caches, for
- * bootstrapping.
+ * This is a special version of RelationBuildDesc()
+ * used by RelationInitialize() in initializing the
+ * relcache. The system relation descriptors built
+ * here are all nailed in the descriptor caches, for
+ * bootstrapping.
* --------------------------------
*/
static void
formrdesc(char *relationName,
- u_int natts,
- FormData_pg_attribute att[])
+ u_int natts,
+ FormData_pg_attribute att[])
{
- Relation relation;
- Size len;
- int i;
-
- /* ----------------
- * allocate new relation desc
- * ----------------
- */
- len = sizeof (RelationData);
- relation = (Relation) palloc(len);
- memset((char *)relation, 0,len);
-
- /* ----------------
- * don't open the unix file yet..
- * ----------------
- */
- relation->rd_fd = -1;
-
- /* ----------------
- * initialize reference count
- * ----------------
- */
- RelationSetReferenceCount(relation, 1);
-
- /* ----------------
- * initialize relation tuple form
- * ----------------
- */
- relation->rd_rel = (Form_pg_class)
- palloc((Size) (sizeof(*relation->rd_rel)));
- memset(relation->rd_rel, 0, sizeof(FormData_pg_class));
- namestrcpy(&relation->rd_rel->relname, relationName);
-
- /* ----------------
- initialize attribute tuple form
- */
- relation->rd_att = CreateTemplateTupleDesc(natts);
-
- /*
- * For debugging purposes, it's important to distinguish between
- * shared and non-shared relations, even at bootstrap time. There's
- * code in the buffer manager that traces allocations that has to
- * know about this.
- */
-
- if (IsSystemRelationName(relationName)) {
- relation->rd_rel->relowner = 6; /* XXX use sym const */
- relation->rd_rel->relisshared =
- IsSharedSystemRelationName(relationName);
- } else {
- relation->rd_rel->relowner = InvalidOid; /* XXX incorrect*/
- relation->rd_rel->relisshared = false;
- }
-
- relation->rd_rel->relpages = 1; /* XXX */
- relation->rd_rel->reltuples = 1; /* XXX */
- relation->rd_rel->relkind = RELKIND_RELATION;
- relation->rd_rel->relarch = 'n';
- relation->rd_rel->relnatts = (uint16) natts;
- relation->rd_isnailed = true;
-
- /* ----------------
- * initialize tuple desc info
- * ----------------
- */
- for (i = 0; i < natts; i++) {
- relation->rd_att->attrs[i] =
- (AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
-
- memset((char *)relation->rd_att->attrs[i], 0,
- ATTRIBUTE_TUPLE_SIZE);
- memmove((char *)relation->rd_att->attrs[i],
- (char *)&att[i],
- ATTRIBUTE_TUPLE_SIZE);
- }
-
- /* ----------------
- * initialize relation id
- * ----------------
- */
- relation->rd_id = relation->rd_att->attrs[0]->attrelid;
-
- /* ----------------
- * add new reldesc to relcache
- * ----------------
- */
- RelationCacheInsert(relation);
- /*
- * Determining this requires a scan on pg_class, but to do the
- * scan the rdesc for pg_class must already exist. Therefore
- * we must do the check (and possible set) after cache insertion.
- */
- relation->rd_rel->relhasindex =
- CatalogHasIndex(relationName, relation->rd_id);
+ Relation relation;
+ Size len;
+ int i;
+
+ /* ----------------
+ * allocate new relation desc
+ * ----------------
+ */
+ len = sizeof(RelationData);
+ relation = (Relation) palloc(len);
+ memset((char *) relation, 0, len);
+
+ /* ----------------
+ * don't open the unix file yet..
+ * ----------------
+ */
+ relation->rd_fd = -1;
+
+ /* ----------------
+ * initialize reference count
+ * ----------------
+ */
+ RelationSetReferenceCount(relation, 1);
+
+ /* ----------------
+ * initialize relation tuple form
+ * ----------------
+ */
+ relation->rd_rel = (Form_pg_class)
+ palloc((Size) (sizeof(*relation->rd_rel)));
+ memset(relation->rd_rel, 0, sizeof(FormData_pg_class));
+ namestrcpy(&relation->rd_rel->relname, relationName);
+
+ /* ----------------
+ initialize attribute tuple form
+ */
+ relation->rd_att = CreateTemplateTupleDesc(natts);
+
+ /*
+ * For debugging purposes, it's important to distinguish between
+ * shared and non-shared relations, even at bootstrap time. There's
+ * code in the buffer manager that traces allocations that has to know
+ * about this.
+ */
+
+ if (IsSystemRelationName(relationName))
+ {
+ relation->rd_rel->relowner = 6; /* XXX use sym const */
+ relation->rd_rel->relisshared =
+ IsSharedSystemRelationName(relationName);
+ }
+ else
+ {
+ relation->rd_rel->relowner = InvalidOid; /* XXX incorrect */
+ relation->rd_rel->relisshared = false;
+ }
+
+ relation->rd_rel->relpages = 1; /* XXX */
+ relation->rd_rel->reltuples = 1; /* XXX */
+ relation->rd_rel->relkind = RELKIND_RELATION;
+ relation->rd_rel->relarch = 'n';
+ relation->rd_rel->relnatts = (uint16) natts;
+ relation->rd_isnailed = true;
+
+ /* ----------------
+ * initialize tuple desc info
+ * ----------------
+ */
+ for (i = 0; i < natts; i++)
+ {
+ relation->rd_att->attrs[i] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+
+ memset((char *) relation->rd_att->attrs[i], 0,
+ ATTRIBUTE_TUPLE_SIZE);
+ memmove((char *) relation->rd_att->attrs[i],
+ (char *) &att[i],
+ ATTRIBUTE_TUPLE_SIZE);
+ }
+
+ /* ----------------
+ * initialize relation id
+ * ----------------
+ */
+ relation->rd_id = relation->rd_att->attrs[0]->attrelid;
+
+ /* ----------------
+ * add new reldesc to relcache
+ * ----------------
+ */
+ RelationCacheInsert(relation);
+
+ /*
+ * Determining this requires a scan on pg_class, but to do the scan
+ * the rdesc for pg_class must already exist. Therefore we must do
+ * the check (and possible set) after cache insertion.
+ */
+ relation->rd_rel->relhasindex =
+ CatalogHasIndex(relationName, relation->rd_id);
}
/* ----------------------------------------------------------------
- * Relation Descriptor Lookup Interface
+ * Relation Descriptor Lookup Interface
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RelationIdCacheGetRelation
+ * RelationIdCacheGetRelation
*
- * only try to get the reldesc by looking up the cache
- * do not go to the disk. this is used by BlockPrepareFile()
- * and RelationIdGetRelation below.
+ * only try to get the reldesc by looking up the cache
+ * do not go to the disk. this is used by BlockPrepareFile()
+ * and RelationIdGetRelation below.
* --------------------------------
*/
Relation
RelationIdCacheGetRelation(Oid relationId)
{
- Relation rd;
-
- RelationIdCacheLookup(relationId, rd);
-
- if (RelationIsValid(rd)) {
- if (rd->rd_fd == -1) {
- rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
- Assert(rd->rd_fd != -1);
+ Relation rd;
+
+ RelationIdCacheLookup(relationId, rd);
+
+ if (RelationIsValid(rd))
+ {
+ if (rd->rd_fd == -1)
+ {
+ rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
+ Assert(rd->rd_fd != -1);
+ }
+
+ RelationIncrementReferenceCount(rd);
+ RelationSetLockForDescriptorOpen(rd);
+
}
-
- RelationIncrementReferenceCount(rd);
- RelationSetLockForDescriptorOpen(rd);
-
- }
-
- return(rd);
+
+ return (rd);
}
/* --------------------------------
- * RelationNameCacheGetRelation
+ * RelationNameCacheGetRelation
* --------------------------------
*/
-static Relation
+static Relation
RelationNameCacheGetRelation(char *relationName)
{
- Relation rd;
- NameData name;
-
- /* make sure that the name key used for hash lookup is properly
- null-padded */
- namestrcpy(&name, relationName);
- RelationNameCacheLookup(name.data, rd);
-
- if (RelationIsValid(rd)) {
- if (rd->rd_fd == -1) {
- rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
- Assert(rd->rd_fd != -1);
+ Relation rd;
+ NameData name;
+
+ /*
+ * make sure that the name key used for hash lookup is properly
+ * null-padded
+ */
+ namestrcpy(&name, relationName);
+ RelationNameCacheLookup(name.data, rd);
+
+ if (RelationIsValid(rd))
+ {
+ if (rd->rd_fd == -1)
+ {
+ rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
+ Assert(rd->rd_fd != -1);
+ }
+
+ RelationIncrementReferenceCount(rd);
+ RelationSetLockForDescriptorOpen(rd);
+
}
-
- RelationIncrementReferenceCount(rd);
- RelationSetLockForDescriptorOpen(rd);
-
- }
-
- return(rd);
+
+ return (rd);
}
/* --------------------------------
- * RelationIdGetRelation
+ * RelationIdGetRelation
*
- * return a relation descriptor based on its id.
- * return a cached value if possible
+ * return a relation descriptor based on its id.
+ * return a cached value if possible
* --------------------------------
*/
Relation
RelationIdGetRelation(Oid relationId)
{
- Relation rd;
- RelationBuildDescInfo buildinfo;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_RelationIdGetRelation);
- IncrHeapAccessStat(global_RelationIdGetRelation);
-
- /* ----------------
- * first try and get a reldesc from the cache
- * ----------------
- */
- rd = RelationIdCacheGetRelation(relationId);
- if (RelationIsValid(rd))
- return rd;
-
- /* ----------------
- * no reldesc in the cache, so have RelationBuildDesc()
- * build one and add it.
- * ----------------
- */
- buildinfo.infotype = INFO_RELID;
- buildinfo.i.info_id = relationId;
-
- rd = RelationBuildDesc(buildinfo);
- return
- rd;
+ Relation rd;
+ RelationBuildDescInfo buildinfo;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_RelationIdGetRelation);
+ IncrHeapAccessStat(global_RelationIdGetRelation);
+
+ /* ----------------
+ * first try and get a reldesc from the cache
+ * ----------------
+ */
+ rd = RelationIdCacheGetRelation(relationId);
+ if (RelationIsValid(rd))
+ return rd;
+
+ /* ----------------
+ * no reldesc in the cache, so have RelationBuildDesc()
+ * build one and add it.
+ * ----------------
+ */
+ buildinfo.infotype = INFO_RELID;
+ buildinfo.i.info_id = relationId;
+
+ rd = RelationBuildDesc(buildinfo);
+ return
+ rd;
}
/* --------------------------------
- * RelationNameGetRelation
+ * RelationNameGetRelation
*
- * return a relation descriptor based on its name.
- * return a cached value if possible
+ * return a relation descriptor based on its name.
+ * return a cached value if possible
* --------------------------------
*/
Relation
RelationNameGetRelation(char *relationName)
{
- Relation rd;
- RelationBuildDescInfo buildinfo;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_RelationNameGetRelation);
- IncrHeapAccessStat(global_RelationNameGetRelation);
-
- /* ----------------
- * first try and get a reldesc from the cache
- * ----------------
- */
- rd = RelationNameCacheGetRelation(relationName);
- if (RelationIsValid(rd))
+ Relation rd;
+ RelationBuildDescInfo buildinfo;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_RelationNameGetRelation);
+ IncrHeapAccessStat(global_RelationNameGetRelation);
+
+ /* ----------------
+ * first try and get a reldesc from the cache
+ * ----------------
+ */
+ rd = RelationNameCacheGetRelation(relationName);
+ if (RelationIsValid(rd))
+ return rd;
+
+ /* ----------------
+ * no reldesc in the cache, so have RelationBuildDesc()
+ * build one and add it.
+ * ----------------
+ */
+ buildinfo.infotype = INFO_RELNAME;
+ buildinfo.i.info_name = relationName;
+
+ rd = RelationBuildDesc(buildinfo);
return rd;
-
- /* ----------------
- * no reldesc in the cache, so have RelationBuildDesc()
- * build one and add it.
- * ----------------
- */
- buildinfo.infotype = INFO_RELNAME;
- buildinfo.i.info_name = relationName;
-
- rd = RelationBuildDesc(buildinfo);
- return rd;
}
/* ----------------
- * old "getreldesc" interface.
+ * old "getreldesc" interface.
* ----------------
*/
#ifdef NOT_USED
Relation
getreldesc(char *relationName)
{
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_getreldesc);
- IncrHeapAccessStat(global_getreldesc);
-
- return RelationNameGetRelation(relationName);
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_getreldesc);
+ IncrHeapAccessStat(global_getreldesc);
+
+ return RelationNameGetRelation(relationName);
}
+
#endif
/* ----------------------------------------------------------------
- * cache invalidation support routines
+ * cache invalidation support routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RelationClose - close an open relation
+ * RelationClose - close an open relation
* --------------------------------
*/
void
RelationClose(Relation relation)
{
- /* Note: no locking manipulations needed */
- RelationDecrementReferenceCount(relation);
+ /* Note: no locking manipulations needed */
+ RelationDecrementReferenceCount(relation);
}
/* --------------------------------
* RelationFlushRelation
*
- * Actually blows away a relation... RelationFree doesn't do
- * anything anymore.
+ * Actually blows away a relation... RelationFree doesn't do
+ * anything anymore.
* --------------------------------
*/
static void
-RelationFlushRelation(Relation *relationPtr,
- bool onlyFlushReferenceCountZero)
+RelationFlushRelation(Relation * relationPtr,
+ bool onlyFlushReferenceCountZero)
{
- MemoryContext oldcxt;
- Relation relation = *relationPtr;
-
- if (relation->rd_isnailed) {
- /* this is a nailed special relation for bootstraping */
- return;
- }
-
- if (!onlyFlushReferenceCountZero ||
- RelationHasReferenceCountZero(relation)) {
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- RelationCacheDelete(relation);
-
- FreeTupleDesc (relation->rd_att);
-
- FreeTriggerDesc (relation);
+ MemoryContext oldcxt;
+ Relation relation = *relationPtr;
-#if 0
- if (relation->rd_rules) {
- int j;
- for(j=0; j < relation->rd_rules->numLocks; j++) {
- pfree(relation->rd_rules->rules[j]);
- }
- pfree(relation->rd_rules->rules);
- pfree(relation->rd_rules);
+ if (relation->rd_isnailed)
+ {
+ /* this is a nailed special relation for bootstraping */
+ return;
}
+
+ if (!onlyFlushReferenceCountZero ||
+ RelationHasReferenceCountZero(relation))
+ {
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ RelationCacheDelete(relation);
+
+ FreeTupleDesc(relation->rd_att);
+
+ FreeTriggerDesc(relation);
+
+#if 0
+ if (relation->rd_rules)
+ {
+ int j;
+
+ for (j = 0; j < relation->rd_rules->numLocks; j++)
+ {
+ pfree(relation->rd_rules->rules[j]);
+ }
+ pfree(relation->rd_rules->rules);
+ pfree(relation->rd_rules);
+ }
#endif
-
- pfree(RelationGetLockInfo(relation));
- pfree(RelationGetRelationTupleForm(relation));
- pfree(relation);
-
- MemoryContextSwitchTo(oldcxt);
- }
+
+ pfree(RelationGetLockInfo(relation));
+ pfree(RelationGetRelationTupleForm(relation));
+ pfree(relation);
+
+ MemoryContextSwitchTo(oldcxt);
+ }
}
/* --------------------------------
- * RelationForgetRelation -
- * RelationFlushRelation + if the relation is local then get rid of
- * the relation descriptor from the newly created relation list.
+ * RelationForgetRelation -
+ * RelationFlushRelation + if the relation is local then get rid of
+ * the relation descriptor from the newly created relation list.
* --------------------------------
*/
void
-RelationForgetRelation (Oid rid)
+RelationForgetRelation(Oid rid)
{
- Relation relation;
-
- RelationIdCacheLookup (rid, relation);
- Assert ( PointerIsValid (relation) );
-
- if ( relation->rd_islocal )
- {
- MemoryContext oldcxt;
- List *curr;
- List *prev = NIL;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- foreach (curr, newlyCreatedRelns)
- {
- Relation reln = lfirst(curr);
-
- Assert ( reln != NULL && reln->rd_islocal );
- if ( reln->rd_id == rid )
- break;
- prev = curr;
- }
- if ( curr == NIL )
- elog (FATAL, "Local relation %s not found in list",
- (RelationGetRelationName(relation))->data);
- if ( prev == NIL )
- newlyCreatedRelns = lnext (newlyCreatedRelns);
- else
- lnext (prev) = lnext (curr);
- pfree (curr);
- MemoryContextSwitchTo(oldcxt);
- }
-
- RelationFlushRelation (&relation, false);
+ Relation relation;
+
+ RelationIdCacheLookup(rid, relation);
+ Assert(PointerIsValid(relation));
+
+ if (relation->rd_islocal)
+ {
+ MemoryContext oldcxt;
+ List *curr;
+ List *prev = NIL;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ foreach(curr, newlyCreatedRelns)
+ {
+ Relation reln = lfirst(curr);
+
+ Assert(reln != NULL && reln->rd_islocal);
+ if (reln->rd_id == rid)
+ break;
+ prev = curr;
+ }
+ if (curr == NIL)
+ elog(FATAL, "Local relation %s not found in list",
+ (RelationGetRelationName(relation))->data);
+ if (prev == NIL)
+ newlyCreatedRelns = lnext(newlyCreatedRelns);
+ else
+ lnext(prev) = lnext(curr);
+ pfree(curr);
+ MemoryContextSwitchTo(oldcxt);
+ }
+
+ RelationFlushRelation(&relation, false);
}
/* --------------------------------
- * RelationIdInvalidateRelationCacheByRelationId
+ * RelationIdInvalidateRelationCacheByRelationId
* --------------------------------
*/
void
RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
{
- Relation relation;
-
- RelationIdCacheLookup(relationId, relation);
-
- /*
- * "local" relations are invalidated by RelationPurgeLocalRelation.
- * (This is to make LocalBufferSync's life easier: want the descriptor
- * to hang around for a while. In fact, won't we want this for
- * BufferSync also? But I'll leave it for now since I don't want to
- * break anything.) - ay 3/95
- */
- if (PointerIsValid(relation) && !relation->rd_islocal) {
+ Relation relation;
+
+ RelationIdCacheLookup(relationId, relation);
+
/*
- * The boolean onlyFlushReferenceCountZero in RelationFlushReln()
- * should be set to true when we are incrementing the command
- * counter and to false when we are starting a new xaction. This
- * can be determined by checking the current xaction status.
+ * "local" relations are invalidated by RelationPurgeLocalRelation.
+ * (This is to make LocalBufferSync's life easier: want the descriptor
+ * to hang around for a while. In fact, won't we want this for
+ * BufferSync also? But I'll leave it for now since I don't want to
+ * break anything.) - ay 3/95
*/
- RelationFlushRelation(&relation, CurrentXactInProgress());
- }
+ if (PointerIsValid(relation) && !relation->rd_islocal)
+ {
+
+ /*
+ * The boolean onlyFlushReferenceCountZero in RelationFlushReln()
+ * should be set to true when we are incrementing the command
+ * counter and to false when we are starting a new xaction. This
+ * can be determined by checking the current xaction status.
+ */
+ RelationFlushRelation(&relation, CurrentXactInProgress());
+ }
}
-#if NOT_USED /* See comments at line 1304 */
+#if NOT_USED /* See comments at line 1304 */
/* --------------------------------
- * RelationIdInvalidateRelationCacheByAccessMethodId
+ * RelationIdInvalidateRelationCacheByAccessMethodId
*
- * RelationFlushIndexes is needed for use with HashTableWalk..
+ * RelationFlushIndexes is needed for use with HashTableWalk..
* --------------------------------
*/
static void
-RelationFlushIndexes(Relation *r,
- Oid accessMethodId)
+RelationFlushIndexes(Relation * r,
+ Oid accessMethodId)
{
- Relation relation = *r;
-
- if (!RelationIsValid(relation)) {
- elog(NOTICE, "inval call to RFI");
- return;
- }
-
- if (relation->rd_rel->relkind == RELKIND_INDEX && /* XXX style */
- (!OidIsValid(accessMethodId) ||
- relation->rd_rel->relam == accessMethodId))
+ Relation relation = *r;
+
+ if (!RelationIsValid(relation))
+ {
+ elog(NOTICE, "inval call to RFI");
+ return;
+ }
+
+ if (relation->rd_rel->relkind == RELKIND_INDEX && /* XXX style */
+ (!OidIsValid(accessMethodId) ||
+ relation->rd_rel->relam == accessMethodId))
{
- RelationFlushRelation(&relation, false);
+ RelationFlushRelation(&relation, false);
}
}
+
#endif
void
RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId)
{
-# if 0
- /*
- * 25 aug 1992: mao commented out the ht walk below. it should be
- * doing the right thing, in theory, but flushing reldescs for index
- * relations apparently doesn't work. we want to cut 4.0.1, and i
- * don't want to introduce new bugs. this code never executed before,
- * so i'm turning it off for now. after the release is cut, i'll
- * fix this up.
- */
-
- HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushIndexes,
- accessMethodId);
-# else
- return;
-# endif
+#if 0
+
+ /*
+ * 25 aug 1992: mao commented out the ht walk below. it should be
+ * doing the right thing, in theory, but flushing reldescs for index
+ * relations apparently doesn't work. we want to cut 4.0.1, and i
+ * don't want to introduce new bugs. this code never executed before,
+ * so i'm turning it off for now. after the release is cut, i'll fix
+ * this up.
+ */
+
+ HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushIndexes,
+ accessMethodId);
+#else
+ return;
+#endif
}
/*
* RelationCacheInvalidate
*
- * Will blow away either all the cached relation descriptors or
- * those that have a zero reference count.
+ * Will blow away either all the cached relation descriptors or
+ * those that have a zero reference count.
*
*/
void
RelationCacheInvalidate(bool onlyFlushReferenceCountZero)
{
- HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushRelation,
- onlyFlushReferenceCountZero);
-
- /*
- * nailed-in reldescs will still be in the cache...
- * 7 hardwired heaps + 3 hardwired indices == 10 total.
- */
- if (!onlyFlushReferenceCountZero) {
- Assert(RelationNameCache->hctl->nkeys == 10);
- Assert(RelationIdCache->hctl->nkeys == 10);
- }
+ HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushRelation,
+ onlyFlushReferenceCountZero);
+
+ /*
+ * nailed-in reldescs will still be in the cache... 7 hardwired heaps
+ * + 3 hardwired indices == 10 total.
+ */
+ if (!onlyFlushReferenceCountZero)
+ {
+ Assert(RelationNameCache->hctl->nkeys == 10);
+ Assert(RelationIdCache->hctl->nkeys == 10);
+ }
}
-
+
/* --------------------------------
- * RelationRegisterRelation -
- * register the Relation descriptor of a newly created relation
- * with the relation descriptor Cache.
+ * RelationRegisterRelation -
+ * register the Relation descriptor of a newly created relation
+ * with the relation descriptor Cache.
* --------------------------------
*/
void
RelationRegisterRelation(Relation relation)
{
- MemoryContext oldcxt;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- if (oldcxt != (MemoryContext)CacheCxt)
- elog(NOIND,"RelationRegisterRelation: WARNING: Context != CacheCxt");
-
- RelationCacheInsert(relation);
-
- RelationInitLockInfo(relation);
-
- /*
- * we've just created the relation. It is invisible to anyone else
- * before the transaction is committed. Setting rd_islocal allows us
- * to use the local buffer manager for select/insert/etc before the end
- * of transaction. (We also need to keep track of relations
- * created during a transaction and does the necessary clean up at
- * the end of the transaction.) - ay 3/95
- */
- relation->rd_islocal = TRUE;
- newlyCreatedRelns = lcons(relation, newlyCreatedRelns);
-
- MemoryContextSwitchTo(oldcxt);
+ MemoryContext oldcxt;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ if (oldcxt != (MemoryContext) CacheCxt)
+ elog(NOIND, "RelationRegisterRelation: WARNING: Context != CacheCxt");
+
+ RelationCacheInsert(relation);
+
+ RelationInitLockInfo(relation);
+
+ /*
+ * we've just created the relation. It is invisible to anyone else
+ * before the transaction is committed. Setting rd_islocal allows us
+ * to use the local buffer manager for select/insert/etc before the
+ * end of transaction. (We also need to keep track of relations
+ * created during a transaction and does the necessary clean up at the
+ * end of the transaction.) - ay 3/95
+ */
+ relation->rd_islocal = TRUE;
+ newlyCreatedRelns = lcons(relation, newlyCreatedRelns);
+
+ MemoryContextSwitchTo(oldcxt);
}
/*
* RelationPurgeLocalRelation -
- * find all the Relation descriptors marked rd_islocal and reset them.
- * This should be called at the end of a transaction (commit/abort) when
- * the "local" relations will become visible to others and the multi-user
- * buffer pool should be used.
+ * find all the Relation descriptors marked rd_islocal and reset them.
+ * This should be called at the end of a transaction (commit/abort) when
+ * the "local" relations will become visible to others and the multi-user
+ * buffer pool should be used.
*/
void
RelationPurgeLocalRelation(bool xactCommitted)
{
- MemoryContext oldcxt;
-
- if (newlyCreatedRelns==NULL)
- return;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- while (newlyCreatedRelns) {
- List *l = newlyCreatedRelns;
- Relation reln = lfirst(l);
-
- Assert(reln!=NULL && reln->rd_islocal);
-
- if (!xactCommitted) {
- /*
- * remove the file if we abort. This is so that files for
- * tables created inside a transaction block get removed.
- */
- if(reln->rd_istemp) {
- if(!(reln->rd_tmpunlinked)) {
- smgrunlink(reln->rd_rel->relsmgr, reln);
- reln->rd_tmpunlinked = TRUE;
- }
- } else {
- smgrunlink(reln->rd_rel->relsmgr, reln);
- }
- }
- else if ( !IsBootstrapProcessingMode () && !(reln->rd_istemp) )
- /*
- * RelationFlushRelation () below will flush relation information
- * from the cache. We must call smgrclose to flush relation
- * information from SMGR & FMGR, too. We assume that for temp
- * relations smgrunlink is already called by heap_destroyr
- * and we skip smgrclose for them. - vadim 05/22/97
- */
- smgrclose(reln->rd_rel->relsmgr, reln);
-
- reln->rd_islocal = FALSE;
+ MemoryContext oldcxt;
- if (!IsBootstrapProcessingMode())
- RelationFlushRelation(&reln, FALSE);
-
- newlyCreatedRelns = lnext(newlyCreatedRelns);
- pfree(l);
- }
+ if (newlyCreatedRelns == NULL)
+ return;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
- MemoryContextSwitchTo(oldcxt);
+ while (newlyCreatedRelns)
+ {
+ List *l = newlyCreatedRelns;
+ Relation reln = lfirst(l);
+
+ Assert(reln != NULL && reln->rd_islocal);
+
+ if (!xactCommitted)
+ {
+
+ /*
+ * remove the file if we abort. This is so that files for
+ * tables created inside a transaction block get removed.
+ */
+ if (reln->rd_istemp)
+ {
+ if (!(reln->rd_tmpunlinked))
+ {
+ smgrunlink(reln->rd_rel->relsmgr, reln);
+ reln->rd_tmpunlinked = TRUE;
+ }
+ }
+ else
+ {
+ smgrunlink(reln->rd_rel->relsmgr, reln);
+ }
+ }
+ else if (!IsBootstrapProcessingMode() && !(reln->rd_istemp))
+
+ /*
+ * RelationFlushRelation () below will flush relation
+ * information from the cache. We must call smgrclose to flush
+ * relation information from SMGR & FMGR, too. We assume that
+ * for temp relations smgrunlink is already called by
+ * heap_destroyr and we skip smgrclose for them. -
+ * vadim 05/22/97
+ */
+ smgrclose(reln->rd_rel->relsmgr, reln);
+
+ reln->rd_islocal = FALSE;
+
+ if (!IsBootstrapProcessingMode())
+ RelationFlushRelation(&reln, FALSE);
+
+ newlyCreatedRelns = lnext(newlyCreatedRelns);
+ pfree(l);
+ }
+
+ MemoryContextSwitchTo(oldcxt);
}
/* --------------------------------
- * RelationInitialize
+ * RelationInitialize
*
- * This initializes the relation descriptor cache.
+ * This initializes the relation descriptor cache.
* --------------------------------
*/
-#define INITRELCACHESIZE 400
+#define INITRELCACHESIZE 400
void
RelationInitialize(void)
{
- MemoryContext oldcxt;
- HASHCTL ctl;
-
- /* ----------------
- * switch to cache memory context
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * create global caches
- * ----------------
- */
- memset(&ctl,0, (int) sizeof(ctl));
- ctl.keysize = sizeof(NameData);
- ctl.datasize = sizeof(Relation);
- RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
-
- ctl.keysize = sizeof(Oid);
- ctl.hash = tag_hash;
- RelationIdCache = hash_create(INITRELCACHESIZE, &ctl,
- HASH_ELEM | HASH_FUNCTION);
-
- /* ----------------
- * initialize the cache with pre-made relation descriptors
- * for some of the more important system relations. These
- * relations should always be in the cache.
- * ----------------
- */
- formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
- formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
- formrdesc(ProcedureRelationName, Natts_pg_proc, Desc_pg_proc);
- formrdesc(TypeRelationName, Natts_pg_type, Desc_pg_type);
- formrdesc(VariableRelationName, Natts_pg_variable, Desc_pg_variable);
- formrdesc(LogRelationName, Natts_pg_log, Desc_pg_log);
- formrdesc(TimeRelationName, Natts_pg_time, Desc_pg_time);
-
- /*
- * If this isn't initdb time, then we want to initialize some index
- * relation descriptors, as well. The descriptors are for pg_attnumind
- * (to make building relation descriptors fast) and possibly others,
- * as they're added.
- */
-
- if (!IsBootstrapProcessingMode())
- init_irels();
-
- MemoryContextSwitchTo(oldcxt);
+ MemoryContext oldcxt;
+ HASHCTL ctl;
+
+ /* ----------------
+ * switch to cache memory context
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * create global caches
+ * ----------------
+ */
+ memset(&ctl, 0, (int) sizeof(ctl));
+ ctl.keysize = sizeof(NameData);
+ ctl.datasize = sizeof(Relation);
+ RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
+
+ ctl.keysize = sizeof(Oid);
+ ctl.hash = tag_hash;
+ RelationIdCache = hash_create(INITRELCACHESIZE, &ctl,
+ HASH_ELEM | HASH_FUNCTION);
+
+ /* ----------------
+ * initialize the cache with pre-made relation descriptors
+ * for some of the more important system relations. These
+ * relations should always be in the cache.
+ * ----------------
+ */
+ formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
+ formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
+ formrdesc(ProcedureRelationName, Natts_pg_proc, Desc_pg_proc);
+ formrdesc(TypeRelationName, Natts_pg_type, Desc_pg_type);
+ formrdesc(VariableRelationName, Natts_pg_variable, Desc_pg_variable);
+ formrdesc(LogRelationName, Natts_pg_log, Desc_pg_log);
+ formrdesc(TimeRelationName, Natts_pg_time, Desc_pg_time);
+
+ /*
+ * If this isn't initdb time, then we want to initialize some index
+ * relation descriptors, as well. The descriptors are for
+ * pg_attnumind (to make building relation descriptors fast) and
+ * possibly others, as they're added.
+ */
+
+ if (!IsBootstrapProcessingMode())
+ init_irels();
+
+ MemoryContextSwitchTo(oldcxt);
}
static void
-AttrDefaultFetch (Relation relation)
+AttrDefaultFetch(Relation relation)
{
- AttrDefault *attrdef = relation->rd_att->constr->defval;
- int ndef = relation->rd_att->constr->num_defval;
- Relation adrel;
- Relation irel;
- ScanKeyData skey;
- HeapTuple tuple;
- Form_pg_attrdef adform;
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- Buffer buffer;
- ItemPointer iptr;
- struct varlena *val;
- bool isnull;
- int found;
- int i;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- adrel = heap_openr(AttrDefaultRelationName);
- irel = index_openr(AttrDefaultIndex);
- sd = index_beginscan(irel, false, 1, &skey);
- tuple = (HeapTuple)NULL;
-
- for (found = 0; ; )
- {
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (!indexRes)
- break;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(adrel, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- if (!HeapTupleIsValid(tuple))
- continue;
- found++;
- adform = (Form_pg_attrdef) GETSTRUCT(tuple);
- for (i = 0; i < ndef; i++)
- {
- if ( adform->adnum != attrdef[i].adnum )
- continue;
- if ( attrdef[i].adsrc != NULL )
- elog (WARN, "AttrDefaultFetch: second record found for attr %.*s in rel %.*s",
- NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_attrdef_adbin,
- adrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "AttrDefaultFetch: adbin IS NULL for attr %.*s in rel %.*s",
- NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
- NAMEDATALEN, relation->rd_rel->relname.data);
- attrdef[i].adbin = textout (val);
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_attrdef_adsrc,
- adrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "AttrDefaultFetch: adsrc IS NULL for attr %.*s in rel %.*s",
- NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
- NAMEDATALEN, relation->rd_rel->relname.data);
- attrdef[i].adsrc = textout (val);
- break;
- }
-
- if ( i >= ndef )
- elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
- adform->adnum,
- NAMEDATALEN, relation->rd_rel->relname.data);
- ReleaseBuffer(buffer);
- }
-
- if ( found < ndef )
- elog (WARN, "AttrDefaultFetch: %d record not found for rel %.*s",
- ndef - found,
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- index_endscan (sd);
- pfree (sd);
- index_close (irel);
- heap_close (adrel);
-
+ AttrDefault *attrdef = relation->rd_att->constr->defval;
+ int ndef = relation->rd_att->constr->num_defval;
+ Relation adrel;
+ Relation irel;
+ ScanKeyData skey;
+ HeapTuple tuple;
+ Form_pg_attrdef adform;
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ Buffer buffer;
+ ItemPointer iptr;
+ struct varlena *val;
+ bool isnull;
+ int found;
+ int i;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ adrel = heap_openr(AttrDefaultRelationName);
+ irel = index_openr(AttrDefaultIndex);
+ sd = index_beginscan(irel, false, 1, &skey);
+ tuple = (HeapTuple) NULL;
+
+ for (found = 0;;)
+ {
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (!indexRes)
+ break;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(adrel, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ if (!HeapTupleIsValid(tuple))
+ continue;
+ found++;
+ adform = (Form_pg_attrdef) GETSTRUCT(tuple);
+ for (i = 0; i < ndef; i++)
+ {
+ if (adform->adnum != attrdef[i].adnum)
+ continue;
+ if (attrdef[i].adsrc != NULL)
+ elog(WARN, "AttrDefaultFetch: second record found for attr %.*s in rel %.*s",
+ NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_attrdef_adbin,
+ adrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "AttrDefaultFetch: adbin IS NULL for attr %.*s in rel %.*s",
+ NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ attrdef[i].adbin = textout(val);
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_attrdef_adsrc,
+ adrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "AttrDefaultFetch: adsrc IS NULL for attr %.*s in rel %.*s",
+ NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ attrdef[i].adsrc = textout(val);
+ break;
+ }
+
+ if (i >= ndef)
+ elog(WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
+ adform->adnum,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ ReleaseBuffer(buffer);
+ }
+
+ if (found < ndef)
+ elog(WARN, "AttrDefaultFetch: %d record not found for rel %.*s",
+ ndef - found,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ index_endscan(sd);
+ pfree(sd);
+ index_close(irel);
+ heap_close(adrel);
+
}
static void
-RelCheckFetch (Relation relation)
+RelCheckFetch(Relation relation)
{
- ConstrCheck *check = relation->rd_att->constr->check;
- int ncheck = relation->rd_att->constr->num_check;
- Relation rcrel;
- Relation irel;
- ScanKeyData skey;
- HeapTuple tuple;
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- Buffer buffer;
- ItemPointer iptr;
- Name rcname;
- struct varlena *val;
- bool isnull;
- int found;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- rcrel = heap_openr(RelCheckRelationName);
- irel = index_openr(RelCheckIndex);
- sd = index_beginscan(irel, false, 1, &skey);
- tuple = (HeapTuple)NULL;
-
- for (found = 0; ; )
- {
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (!indexRes)
- break;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(rcrel, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- if (!HeapTupleIsValid(tuple))
- continue;
- if ( found == ncheck )
- elog (WARN, "RelCheckFetch: unexpected record found for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- rcname = (Name) fastgetattr (tuple,
- Anum_pg_relcheck_rcname,
- rcrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelCheckFetch: rcname IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- check[found].ccname = nameout (rcname);
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_relcheck_rcbin,
- rcrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelCheckFetch: rcbin IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- check[found].ccbin = textout (val);
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_relcheck_rcsrc,
- rcrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelCheckFetch: rcsrc IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- check[found].ccsrc = textout (val);
- found++;
-
- ReleaseBuffer(buffer);
- }
-
- if ( found < ncheck )
- elog (WARN, "RelCheckFetch: %d record not found for rel %.*s",
- ncheck - found,
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- index_endscan (sd);
- pfree (sd);
- index_close (irel);
- heap_close (rcrel);
-
+ ConstrCheck *check = relation->rd_att->constr->check;
+ int ncheck = relation->rd_att->constr->num_check;
+ Relation rcrel;
+ Relation irel;
+ ScanKeyData skey;
+ HeapTuple tuple;
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ Buffer buffer;
+ ItemPointer iptr;
+ Name rcname;
+ struct varlena *val;
+ bool isnull;
+ int found;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ rcrel = heap_openr(RelCheckRelationName);
+ irel = index_openr(RelCheckIndex);
+ sd = index_beginscan(irel, false, 1, &skey);
+ tuple = (HeapTuple) NULL;
+
+ for (found = 0;;)
+ {
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (!indexRes)
+ break;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(rcrel, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ if (!HeapTupleIsValid(tuple))
+ continue;
+ if (found == ncheck)
+ elog(WARN, "RelCheckFetch: unexpected record found for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ rcname = (Name) fastgetattr(tuple,
+ Anum_pg_relcheck_rcname,
+ rcrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelCheckFetch: rcname IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ check[found].ccname = nameout(rcname);
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_relcheck_rcbin,
+ rcrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelCheckFetch: rcbin IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ check[found].ccbin = textout(val);
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_relcheck_rcsrc,
+ rcrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelCheckFetch: rcsrc IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ check[found].ccsrc = textout(val);
+ found++;
+
+ ReleaseBuffer(buffer);
+ }
+
+ if (found < ncheck)
+ elog(WARN, "RelCheckFetch: %d record not found for rel %.*s",
+ ncheck - found,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ index_endscan(sd);
+ pfree(sd);
+ index_close(irel);
+ heap_close(rcrel);
+
}
/*
- * init_irels(), write_irels() -- handle special-case initialization of
- * index relation descriptors.
+ * init_irels(), write_irels() -- handle special-case initialization of
+ * index relation descriptors.
*
- * In late 1992, we started regularly having databases with more than
- * a thousand classes in them. With this number of classes, it became
- * critical to do indexed lookups on the system catalogs.
+ * In late 1992, we started regularly having databases with more than
+ * a thousand classes in them. With this number of classes, it became
+ * critical to do indexed lookups on the system catalogs.
*
- * Bootstrapping these lookups is very hard. We want to be able to
- * use an index on pg_attribute, for example, but in order to do so,
- * we must have read pg_attribute for the attributes in the index,
- * which implies that we need to use the index.
+ * Bootstrapping these lookups is very hard. We want to be able to
+ * use an index on pg_attribute, for example, but in order to do so,
+ * we must have read pg_attribute for the attributes in the index,
+ * which implies that we need to use the index.
*
- * In order to get around the problem, we do the following:
+ * In order to get around the problem, we do the following:
*
- * + When the database system is initialized (at initdb time), we
- * don't use indices on pg_attribute. We do sequential scans.
+ * + When the database system is initialized (at initdb time), we
+ * don't use indices on pg_attribute. We do sequential scans.
*
- * + When the backend is started up in normal mode, we load an image
- * of the appropriate relation descriptors, in internal format,
- * from an initialization file in the data/base/... directory.
+ * + When the backend is started up in normal mode, we load an image
+ * of the appropriate relation descriptors, in internal format,
+ * from an initialization file in the data/base/... directory.
*
- * + If the initialization file isn't there, then we create the
- * relation descriptor using sequential scans and write it to
- * the initialization file for use by subsequent backends.
+ * + If the initialization file isn't there, then we create the
+ * relation descriptor using sequential scans and write it to
+ * the initialization file for use by subsequent backends.
*
- * This is complicated and interferes with system changes, but
- * performance is so bad that we're willing to pay the tax.
+ * This is complicated and interferes with system changes, but
+ * performance is so bad that we're willing to pay the tax.
*/
/* pg_attnumind, pg_classnameind, pg_classoidind */
@@ -1833,268 +1902,288 @@ RelCheckFetch (Relation relation)
static void
init_irels(void)
{
- Size len;
- int nread;
- File fd;
- Relation irel[Num_indices_bootstrap];
- Relation ird;
- Form_pg_am am;
- Form_pg_class relform;
- IndexStrategy strat;
- RegProcedure *support;
- int i;
- int relno;
-
- if ((fd = FileNameOpenFile(INIT_FILENAME, O_RDONLY, 0600)) < 0) {
- write_irels();
- return;
- }
-
- FileSeek(fd, 0L, SEEK_SET);
-
- for (relno = 0; relno < Num_indices_bootstrap; relno++) {
- /* first read the relation descriptor length*/
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- ird = irel[relno] = (Relation) palloc(len);
- memset(ird, 0, len);
-
- /* then, read the Relation structure */
- if ((nread = FileRead(fd, (char*)ird, len)) != len) {
- write_irels();
- return;
- }
-
- /* the file descriptor is not yet opened */
- ird->rd_fd = -1;
-
- /* lock info is not initialized */
- ird->lockInfo = (char *) NULL;
-
- /* next, read the access method tuple form */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- am = (Form_pg_am) palloc(len);
- if ((nread = FileRead(fd, (char*)am, len)) != len) {
- write_irels();
- return;
- }
-
- ird->rd_am = am;
-
- /* next read the relation tuple form */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- relform = (Form_pg_class) palloc(len);
- if ((nread = FileRead(fd, (char*)relform, len)) != len) {
- write_irels();
- return;
- }
-
- ird->rd_rel = relform;
-
- /* initialize attribute tuple forms */
- ird->rd_att = CreateTemplateTupleDesc(relform->relnatts);
-
- /* next read all the attribute tuple form data entries */
- len = ATTRIBUTE_TUPLE_SIZE;
- for (i = 0; i < relform->relnatts; i++) {
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- ird->rd_att->attrs[i] = (AttributeTupleForm) palloc(len);
-
- if ((nread = FileRead(fd, (char*)ird->rd_att->attrs[i], len)) != len) {
+ Size len;
+ int nread;
+ File fd;
+ Relation irel[Num_indices_bootstrap];
+ Relation ird;
+ Form_pg_am am;
+ Form_pg_class relform;
+ IndexStrategy strat;
+ RegProcedure *support;
+ int i;
+ int relno;
+
+ if ((fd = FileNameOpenFile(INIT_FILENAME, O_RDONLY, 0600)) < 0)
+ {
write_irels();
return;
- }
- }
-
- /* next, read the index strategy map */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- strat = (IndexStrategy) palloc(len);
- if ((nread = FileRead(fd, (char*)strat, len)) != len) {
- write_irels();
- return;
}
-
- /* oh, for god's sake... */
+
+ FileSeek(fd, 0L, SEEK_SET);
+
+ for (relno = 0; relno < Num_indices_bootstrap; relno++)
+ {
+ /* first read the relation descriptor length */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ ird = irel[relno] = (Relation) palloc(len);
+ memset(ird, 0, len);
+
+ /* then, read the Relation structure */
+ if ((nread = FileRead(fd, (char *) ird, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ /* the file descriptor is not yet opened */
+ ird->rd_fd = -1;
+
+ /* lock info is not initialized */
+ ird->lockInfo = (char *) NULL;
+
+ /* next, read the access method tuple form */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ am = (Form_pg_am) palloc(len);
+ if ((nread = FileRead(fd, (char *) am, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ ird->rd_am = am;
+
+ /* next read the relation tuple form */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ relform = (Form_pg_class) palloc(len);
+ if ((nread = FileRead(fd, (char *) relform, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ ird->rd_rel = relform;
+
+ /* initialize attribute tuple forms */
+ ird->rd_att = CreateTemplateTupleDesc(relform->relnatts);
+
+ /* next read all the attribute tuple form data entries */
+ len = ATTRIBUTE_TUPLE_SIZE;
+ for (i = 0; i < relform->relnatts; i++)
+ {
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ ird->rd_att->attrs[i] = (AttributeTupleForm) palloc(len);
+
+ if ((nread = FileRead(fd, (char *) ird->rd_att->attrs[i], len)) != len)
+ {
+ write_irels();
+ return;
+ }
+ }
+
+ /* next, read the index strategy map */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ strat = (IndexStrategy) palloc(len);
+ if ((nread = FileRead(fd, (char *) strat, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ /* oh, for god's sake... */
#define SMD(i) strat[0].strategyMapData[i].entry[0]
-
- /* have to reinit the function pointers in the strategy maps */
- for (i = 0; i < am->amstrategies; i++)
- fmgr_info(SMD(i).sk_procedure,
- &(SMD(i).sk_func), &(SMD(i).sk_nargs));
-
-
- /* use a real field called rd_istrat instead of the
- bogosity of hanging invisible fields off the end of a structure
- - jolly */
- ird->rd_istrat = strat;
-
- /* finally, read the vector of support procedures */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- support = (RegProcedure *) palloc(len);
- if ((nread = FileRead(fd, (char*)support, len)) != len) {
- write_irels();
- return;
- }
-
- /*
- p += sizeof(IndexStrategy);
- *((RegProcedure **) p) = support;
- */
- ird->rd_support = support;
-
- RelationCacheInsert(ird);
- }
+ /* have to reinit the function pointers in the strategy maps */
+ for (i = 0; i < am->amstrategies; i++)
+ fmgr_info(SMD(i).sk_procedure,
+ &(SMD(i).sk_func), &(SMD(i).sk_nargs));
+
+
+ /*
+ * use a real field called rd_istrat instead of the bogosity of
+ * hanging invisible fields off the end of a structure - jolly
+ */
+ ird->rd_istrat = strat;
+
+ /* finally, read the vector of support procedures */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ support = (RegProcedure *) palloc(len);
+ if ((nread = FileRead(fd, (char *) support, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ /*
+ * p += sizeof(IndexStrategy); ((RegProcedure **) p) = support;
+ */
+
+ ird->rd_support = support;
+
+ RelationCacheInsert(ird);
+ }
}
static void
write_irels(void)
{
- int len;
- int nwritten;
- File fd;
- Relation irel[Num_indices_bootstrap];
- Relation ird;
- Form_pg_am am;
- Form_pg_class relform;
- IndexStrategy strat;
- RegProcedure *support;
- ProcessingMode oldmode;
- int i;
- int relno;
- RelationBuildDescInfo bi;
-
- fd = FileNameOpenFile(INIT_FILENAME, O_WRONLY|O_CREAT|O_TRUNC, 0600);
- if (fd < 0)
- elog(FATAL, "cannot create init file %s", INIT_FILENAME);
-
- FileSeek(fd, 0L, SEEK_SET);
-
- /*
- * Build a relation descriptor for pg_attnumind without resort to the
- * descriptor cache. In order to do this, we set ProcessingMode
- * to Bootstrap. The effect of this is to disable indexed relation
- * searches -- a necessary step, since we're trying to instantiate
- * the index relation descriptors here.
- */
-
- oldmode = GetProcessingMode();
- SetProcessingMode(BootstrapProcessing);
-
- bi.infotype = INFO_RELNAME;
- bi.i.info_name = AttributeNumIndex;
- irel[0] = RelationBuildDesc(bi);
- irel[0]->rd_isnailed = true;
-
- bi.i.info_name = ClassNameIndex;
- irel[1] = RelationBuildDesc(bi);
- irel[1]->rd_isnailed = true;
-
- bi.i.info_name = ClassOidIndex;
- irel[2] = RelationBuildDesc(bi);
- irel[2]->rd_isnailed = true;
-
- SetProcessingMode(oldmode);
-
- /* nail the descriptor in the cache */
- for (relno = 0; relno < Num_indices_bootstrap; relno++) {
- ird = irel[relno];
-
- /* save the volatile fields in the relation descriptor */
- am = ird->rd_am;
- ird->rd_am = (Form_pg_am) NULL;
- relform = ird->rd_rel;
- ird->rd_rel = (Form_pg_class) NULL;
- strat = ird->rd_istrat;
- support = ird->rd_support;
-
- /* first write the relation descriptor , excluding strategy and support */
- len = sizeof(RelationData);
-
- /* first, write the relation descriptor length */
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- descriptor length");
-
- /* next, write out the Relation structure */
- if ((nwritten = FileWrite(fd, (char*) ird, len)) != len)
- elog(FATAL, "cannot write init file -- reldesc");
-
- /* next, write the access method tuple form */
- len = sizeof(FormData_pg_am);
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- am tuple form length");
-
- if ((nwritten = FileWrite(fd, (char*) am, len)) != len)
- elog(FATAL, "cannot write init file -- am tuple form");
-
- /* next write the relation tuple form */
- len = sizeof(FormData_pg_class);
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- relation tuple form length");
-
- if ((nwritten = FileWrite(fd, (char*) relform, len)) != len)
- elog(FATAL, "cannot write init file -- relation tuple form");
-
- /* next, do all the attribute tuple form data entries */
- len = ATTRIBUTE_TUPLE_SIZE;
- for (i = 0; i < relform->relnatts; i++) {
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- length of attdesc %d", i);
- if ((nwritten = FileWrite(fd, (char*) ird->rd_att->attrs[i], len))
- != len)
- elog(FATAL, "cannot write init file -- attdesc %d", i);
+ int len;
+ int nwritten;
+ File fd;
+ Relation irel[Num_indices_bootstrap];
+ Relation ird;
+ Form_pg_am am;
+ Form_pg_class relform;
+ IndexStrategy strat;
+ RegProcedure *support;
+ ProcessingMode oldmode;
+ int i;
+ int relno;
+ RelationBuildDescInfo bi;
+
+ fd = FileNameOpenFile(INIT_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
+ elog(FATAL, "cannot create init file %s", INIT_FILENAME);
+
+ FileSeek(fd, 0L, SEEK_SET);
+
+ /*
+ * Build a relation descriptor for pg_attnumind without resort to the
+ * descriptor cache. In order to do this, we set ProcessingMode to
+ * Bootstrap. The effect of this is to disable indexed relation
+ * searches -- a necessary step, since we're trying to instantiate the
+ * index relation descriptors here.
+ */
+
+ oldmode = GetProcessingMode();
+ SetProcessingMode(BootstrapProcessing);
+
+ bi.infotype = INFO_RELNAME;
+ bi.i.info_name = AttributeNumIndex;
+ irel[0] = RelationBuildDesc(bi);
+ irel[0]->rd_isnailed = true;
+
+ bi.i.info_name = ClassNameIndex;
+ irel[1] = RelationBuildDesc(bi);
+ irel[1]->rd_isnailed = true;
+
+ bi.i.info_name = ClassOidIndex;
+ irel[2] = RelationBuildDesc(bi);
+ irel[2]->rd_isnailed = true;
+
+ SetProcessingMode(oldmode);
+
+ /* nail the descriptor in the cache */
+ for (relno = 0; relno < Num_indices_bootstrap; relno++)
+ {
+ ird = irel[relno];
+
+ /* save the volatile fields in the relation descriptor */
+ am = ird->rd_am;
+ ird->rd_am = (Form_pg_am) NULL;
+ relform = ird->rd_rel;
+ ird->rd_rel = (Form_pg_class) NULL;
+ strat = ird->rd_istrat;
+ support = ird->rd_support;
+
+ /*
+ * first write the relation descriptor , excluding strategy and
+ * support
+ */
+ len = sizeof(RelationData);
+
+ /* first, write the relation descriptor length */
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- descriptor length");
+
+ /* next, write out the Relation structure */
+ if ((nwritten = FileWrite(fd, (char *) ird, len)) != len)
+ elog(FATAL, "cannot write init file -- reldesc");
+
+ /* next, write the access method tuple form */
+ len = sizeof(FormData_pg_am);
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- am tuple form length");
+
+ if ((nwritten = FileWrite(fd, (char *) am, len)) != len)
+ elog(FATAL, "cannot write init file -- am tuple form");
+
+ /* next write the relation tuple form */
+ len = sizeof(FormData_pg_class);
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- relation tuple form length");
+
+ if ((nwritten = FileWrite(fd, (char *) relform, len)) != len)
+ elog(FATAL, "cannot write init file -- relation tuple form");
+
+ /* next, do all the attribute tuple form data entries */
+ len = ATTRIBUTE_TUPLE_SIZE;
+ for (i = 0; i < relform->relnatts; i++)
+ {
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- length of attdesc %d", i);
+ if ((nwritten = FileWrite(fd, (char *) ird->rd_att->attrs[i], len))
+ != len)
+ elog(FATAL, "cannot write init file -- attdesc %d", i);
+ }
+
+ /* next, write the index strategy map */
+ len = AttributeNumberGetIndexStrategySize(relform->relnatts,
+ am->amstrategies);
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- strategy map length");
+
+ if ((nwritten = FileWrite(fd, (char *) strat, len)) != len)
+ elog(FATAL, "cannot write init file -- strategy map");
+
+ /* finally, write the vector of support procedures */
+ len = relform->relnatts * (am->amsupport * sizeof(RegProcedure));
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- support vector length");
+
+ if ((nwritten = FileWrite(fd, (char *) support, len)) != len)
+ elog(FATAL, "cannot write init file -- support vector");
+
+ /* restore volatile fields */
+ ird->rd_am = am;
+ ird->rd_rel = relform;
}
-
- /* next, write the index strategy map */
- len = AttributeNumberGetIndexStrategySize(relform->relnatts,
- am->amstrategies);
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- strategy map length");
-
- if ((nwritten = FileWrite(fd, (char*) strat, len)) != len)
- elog(FATAL, "cannot write init file -- strategy map");
-
- /* finally, write the vector of support procedures */
- len = relform->relnatts * (am->amsupport * sizeof(RegProcedure));
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- support vector length");
-
- if ((nwritten = FileWrite(fd, (char*) support, len)) != len)
- elog(FATAL, "cannot write init file -- support vector");
-
- /* restore volatile fields */
- ird->rd_am = am;
- ird->rd_rel = relform;
- }
-
- FileClose(fd);
+
+ FileClose(fd);
}
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 460e8d40af0..5f6c22b95fc 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -1,37 +1,37 @@
/*-------------------------------------------------------------------------
*
* syscache.c--
- * System cache management routines
+ * System cache management routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.4 1996/11/06 10:31:29 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.5 1997/09/07 04:53:10 momjian Exp $
*
* NOTES
- * These routines allow the parser/planner/executor to perform
- * rapid lookups on the contents of the system catalogs.
+ * These routines allow the parser/planner/executor to perform
+ * rapid lookups on the contents of the system catalogs.
*
- * see catalog/syscache.h for a list of the cache id's
+ * see catalog/syscache.h for a list of the cache id's
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-
+
#include "access/heapam.h"
#include "access/htup.h"
#include "catalog/catname.h"
#include "utils/catcache.h"
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-
+
/* ----------------
- * hardwired attribute information comes from system catalog files.
+ * hardwired attribute information comes from system catalog files.
* ----------------
*/
#include "catalog/pg_am.h"
@@ -51,592 +51,625 @@
#include "catalog/pg_user.h"
#include "storage/large_object.h"
#include "catalog/pg_listener.h"
-
-extern bool AMI_OVERRIDE; /* XXX style */
-
+
+extern bool AMI_OVERRIDE; /* XXX style */
+
#include "utils/syscache.h"
#include "catalog/indexing.h"
-
-typedef HeapTuple (*ScanFunc)();
+
+typedef HeapTuple(*ScanFunc) ();
/* ----------------
- * Warning: cacheinfo[] below is changed, then be sure and
- * update the magic constants in syscache.h!
+ * Warning: cacheinfo[] below is changed, then be sure and
+ * update the magic constants in syscache.h!
* ----------------
*/
static struct cachedesc cacheinfo[] = {
- { AccessMethodOperatorRelationName, /* AMOPOPID */
- 3,
- { Anum_pg_amop_amopclaid,
- Anum_pg_amop_amopopr,
- Anum_pg_amop_amopid,
- 0 },
- sizeof(FormData_pg_amop),
- NULL,
- (ScanFunc) NULL },
- { AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
- 3,
- { Anum_pg_amop_amopid,
- Anum_pg_amop_amopclaid,
- Anum_pg_amop_amopstrategy,
- 0 },
- sizeof(FormData_pg_amop),
- NULL,
- (ScanFunc) NULL },
- { AttributeRelationName, /* ATTNAME */
- 2,
- { Anum_pg_attribute_attrelid,
- Anum_pg_attribute_attname,
- 0,
- 0 },
- ATTRIBUTE_TUPLE_SIZE,
- AttributeNameIndex,
- (ScanFunc) AttributeNameIndexScan },
- { AttributeRelationName, /* ATTNUM */
- 2,
- { Anum_pg_attribute_attrelid,
- Anum_pg_attribute_attnum,
- 0,
- 0 },
- ATTRIBUTE_TUPLE_SIZE,
- AttributeNumIndex,
- (ScanFunc) AttributeNumIndexScan },
- { IndexRelationName, /* INDEXRELID */
- 1,
- { Anum_pg_index_indexrelid,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_index, indpred),
- NULL,
- NULL },
- { LanguageRelationName, /* LANNAME */
- 1,
- { Anum_pg_language_lanname,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_language, lancompiler),
- NULL,
- NULL },
- { OperatorRelationName, /* OPRNAME */
- 4,
- { Anum_pg_operator_oprname,
- Anum_pg_operator_oprleft,
- Anum_pg_operator_oprright,
- Anum_pg_operator_oprkind },
- sizeof(FormData_pg_operator),
- NULL,
- NULL },
- { OperatorRelationName, /* OPROID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_operator),
- NULL,
- (ScanFunc) NULL },
- { ProcedureRelationName, /* PRONAME */
- 3,
- { Anum_pg_proc_proname,
- Anum_pg_proc_pronargs,
- Anum_pg_proc_proargtypes,
- 0 },
- offsetof(FormData_pg_proc, prosrc),
- ProcedureNameIndex,
- (ScanFunc) ProcedureNameIndexScan },
- { ProcedureRelationName, /* PROOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_proc, prosrc),
- ProcedureOidIndex,
- (ScanFunc) ProcedureOidIndexScan },
- { RelationRelationName, /* RELNAME */
- 1,
- { Anum_pg_class_relname,
- 0,
- 0,
- 0 },
- CLASS_TUPLE_SIZE,
- ClassNameIndex,
- (ScanFunc) ClassNameIndexScan },
- { RelationRelationName, /* RELOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- CLASS_TUPLE_SIZE,
- ClassOidIndex,
- (ScanFunc) ClassOidIndexScan },
- { TypeRelationName, /* TYPNAME */
- 1,
- { Anum_pg_type_typname,
- 0,
- 0,
- 0 },
- offsetof(TypeTupleFormData,typalign)+sizeof(char),
- TypeNameIndex,
- TypeNameIndexScan },
- { TypeRelationName, /* TYPOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
+ {AccessMethodOperatorRelationName, /* AMOPOPID */
+ 3,
+ {Anum_pg_amop_amopclaid,
+ Anum_pg_amop_amopopr,
+ Anum_pg_amop_amopid,
+ 0},
+ sizeof(FormData_pg_amop),
+ NULL,
+ (ScanFunc) NULL},
+ {AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
+ 3,
+ {Anum_pg_amop_amopid,
+ Anum_pg_amop_amopclaid,
+ Anum_pg_amop_amopstrategy,
+ 0},
+ sizeof(FormData_pg_amop),
+ NULL,
+ (ScanFunc) NULL},
+ {AttributeRelationName, /* ATTNAME */
+ 2,
+ {Anum_pg_attribute_attrelid,
+ Anum_pg_attribute_attname,
+ 0,
+ 0},
+ ATTRIBUTE_TUPLE_SIZE,
+ AttributeNameIndex,
+ (ScanFunc) AttributeNameIndexScan},
+ {AttributeRelationName, /* ATTNUM */
+ 2,
+ {Anum_pg_attribute_attrelid,
+ Anum_pg_attribute_attnum,
+ 0,
+ 0},
+ ATTRIBUTE_TUPLE_SIZE,
+ AttributeNumIndex,
+ (ScanFunc) AttributeNumIndexScan},
+ {IndexRelationName, /* INDEXRELID */
+ 1,
+ {Anum_pg_index_indexrelid,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_index, indpred),
+ NULL,
+ NULL},
+ {LanguageRelationName, /* LANNAME */
+ 1,
+ {Anum_pg_language_lanname,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_language, lancompiler),
+ NULL,
+ NULL},
+ {OperatorRelationName, /* OPRNAME */
+ 4,
+ {Anum_pg_operator_oprname,
+ Anum_pg_operator_oprleft,
+ Anum_pg_operator_oprright,
+ Anum_pg_operator_oprkind},
+ sizeof(FormData_pg_operator),
+ NULL,
+ NULL},
+ {OperatorRelationName, /* OPROID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_operator),
+ NULL,
+ (ScanFunc) NULL},
+ {ProcedureRelationName, /* PRONAME */
+ 3,
+ {Anum_pg_proc_proname,
+ Anum_pg_proc_pronargs,
+ Anum_pg_proc_proargtypes,
+ 0},
+ offsetof(FormData_pg_proc, prosrc),
+ ProcedureNameIndex,
+ (ScanFunc) ProcedureNameIndexScan},
+ {ProcedureRelationName, /* PROOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_proc, prosrc),
+ ProcedureOidIndex,
+ (ScanFunc) ProcedureOidIndexScan},
+ {RelationRelationName, /* RELNAME */
+ 1,
+ {Anum_pg_class_relname,
+ 0,
+ 0,
+ 0},
+ CLASS_TUPLE_SIZE,
+ ClassNameIndex,
+ (ScanFunc) ClassNameIndexScan},
+ {RelationRelationName, /* RELOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ CLASS_TUPLE_SIZE,
+ ClassOidIndex,
+ (ScanFunc) ClassOidIndexScan},
+ {TypeRelationName, /* TYPNAME */
+ 1,
+ {Anum_pg_type_typname,
+ 0,
+ 0,
+ 0},
+ offsetof(TypeTupleFormData, typalign) + sizeof(char),
+ TypeNameIndex,
+ TypeNameIndexScan},
+ {TypeRelationName, /* TYPOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ offsetof(TypeTupleFormData, typalign) +sizeof(char),
+ TypeOidIndex,
+ TypeOidIndexScan},
+ {AccessMethodRelationName, /* AMNAME */
+ 1,
+ {Anum_pg_am_amname,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_am),
+ NULL,
+ NULL},
+ {OperatorClassRelationName, /* CLANAME */
+ 1,
+ {Anum_pg_opclass_opcname,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_opclass),
+ NULL,
+ NULL},
+ {IndexRelationName, /* INDRELIDKEY */
+ 2,
+ {Anum_pg_index_indrelid,
+ Anum_pg_index_indkey,
+ 0,
+ 0},
+ offsetof(FormData_pg_index, indpred),
+ NULL,
+ (ScanFunc) NULL},
+ {InheritsRelationName, /* INHRELID */
+ 2,
+ {Anum_pg_inherits_inhrel,
+ Anum_pg_inherits_inhseqno,
+ 0,
0},
- offsetof(TypeTupleFormData,typalign)+sizeof(char),
- TypeOidIndex,
- TypeOidIndexScan },
- { AccessMethodRelationName, /* AMNAME */
- 1,
- { Anum_pg_am_amname,
- 0,
- 0,
+ sizeof(FormData_pg_inherits),
+ NULL,
+ (ScanFunc) NULL},
+ {RewriteRelationName, /* RULOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_rewrite, ev_qual),
+ NULL,
+ (ScanFunc) NULL},
+ {AggregateRelationName, /* AGGNAME */
+ 2,
+ {Anum_pg_aggregate_aggname,
+ Anum_pg_aggregate_aggbasetype,
+ 0,
0},
- sizeof(FormData_pg_am),
- NULL,
- NULL },
- { OperatorClassRelationName, /* CLANAME */
- 1,
- { Anum_pg_opclass_opcname,
- 0,
- 0,
+ offsetof(FormData_pg_aggregate, agginitval1),
+ NULL,
+ (ScanFunc) NULL},
+ {ListenerRelationName, /* LISTENREL */
+ 2,
+ {Anum_pg_listener_relname,
+ Anum_pg_listener_pid,
+ 0,
0},
- sizeof(FormData_pg_opclass),
- NULL,
- NULL },
- { IndexRelationName, /* INDRELIDKEY */
- 2,
- { Anum_pg_index_indrelid,
- Anum_pg_index_indkey,
- 0,
+ sizeof(FormData_pg_listener),
+ NULL,
+ (ScanFunc) NULL},
+ {UserRelationName, /* USENAME */
+ 1,
+ {Anum_pg_user_usename,
+ 0,
+ 0,
0},
- offsetof(FormData_pg_index, indpred),
- NULL,
- (ScanFunc) NULL },
- { InheritsRelationName, /* INHRELID */
- 2,
- { Anum_pg_inherits_inhrel,
- Anum_pg_inherits_inhseqno,
- 0,
+ sizeof(FormData_pg_user),
+ NULL,
+ (ScanFunc) NULL},
+ {UserRelationName, /* USESYSID */
+ 1,
+ {Anum_pg_user_usesysid,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_user),
+ NULL,
+ (ScanFunc) NULL},
+ {GroupRelationName, /* GRONAME */
+ 1,
+ {Anum_pg_group_groname,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_group, grolist[0]),
+ NULL,
+ (ScanFunc) NULL},
+ {GroupRelationName, /* GROSYSID */
+ 1,
+ {Anum_pg_group_grosysid,
+ 0,
+ 0,
0},
- sizeof(FormData_pg_inherits),
- NULL,
- (ScanFunc) NULL },
- { RewriteRelationName, /* RULOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_rewrite, ev_qual),
- NULL,
- (ScanFunc) NULL },
- { AggregateRelationName, /*AGGNAME*/
- 2,
- { Anum_pg_aggregate_aggname,
- Anum_pg_aggregate_aggbasetype,
- 0,
- 0 },
- offsetof(FormData_pg_aggregate, agginitval1),
- NULL,
- (ScanFunc) NULL },
- { ListenerRelationName, /* LISTENREL */
- 2,
- { Anum_pg_listener_relname,
- Anum_pg_listener_pid,
- 0,
- 0 },
- sizeof(FormData_pg_listener),
- NULL,
- (ScanFunc) NULL },
- { UserRelationName, /* USENAME */
- 1,
- { Anum_pg_user_usename,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_user),
- NULL,
- (ScanFunc) NULL },
- { UserRelationName, /* USESYSID */
- 1,
- { Anum_pg_user_usesysid,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_user),
- NULL,
- (ScanFunc) NULL },
- { GroupRelationName, /* GRONAME */
- 1,
- { Anum_pg_group_groname,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_group, grolist[0]),
- NULL,
- (ScanFunc) NULL },
- { GroupRelationName, /* GROSYSID */
- 1,
- { Anum_pg_group_grosysid,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_group, grolist[0]),
- NULL,
- (ScanFunc) NULL },
- { RewriteRelationName, /* REWRITENAME */
- 1,
- { Anum_pg_rewrite_rulename,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_rewrite, ev_qual),
- NULL,
- (ScanFunc) NULL },
- { ProcedureRelationName, /* PROSRC */
- 1,
- { Anum_pg_proc_prosrc,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_proc, prosrc),
- ProcedureSrcIndex,
- (ScanFunc) ProcedureSrcIndexScan },
- { OperatorClassRelationName, /* CLADEFTYPE */
- 1,
- { Anum_pg_opclass_opcdeftype,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_opclass),
- NULL,
- (ScanFunc) NULL }
+ offsetof(FormData_pg_group, grolist[0]),
+ NULL,
+ (ScanFunc) NULL},
+ {RewriteRelationName, /* REWRITENAME */
+ 1,
+ {Anum_pg_rewrite_rulename,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_rewrite, ev_qual),
+ NULL,
+ (ScanFunc) NULL},
+ {ProcedureRelationName, /* PROSRC */
+ 1,
+ {Anum_pg_proc_prosrc,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_proc, prosrc),
+ ProcedureSrcIndex,
+ (ScanFunc) ProcedureSrcIndexScan},
+ {OperatorClassRelationName, /* CLADEFTYPE */
+ 1,
+ {Anum_pg_opclass_opcdeftype,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_opclass),
+ NULL,
+ (ScanFunc) NULL}
};
-
-static struct catcache *SysCache[lengthof(cacheinfo)];
-static int32 SysCacheSize = lengthof(cacheinfo);
-
-
+
+static struct catcache *SysCache[
+ lengthof(cacheinfo)];
+static int32 SysCacheSize = lengthof(cacheinfo);
+
+
/*
* zerocaches--
*
- * Make sure the SysCache structure is zero'd.
+ * Make sure the SysCache structure is zero'd.
*/
void
zerocaches()
{
- memset((char *) SysCache, 0, SysCacheSize * sizeof(struct catcache *));
+ memset((char *) SysCache, 0, SysCacheSize * sizeof(struct catcache *));
}
/*
* Note:
- * This function was written because the initialized catalog caches
- * are used to determine which caches may contain tuples which need
- * to be invalidated in other backends.
+ * This function was written because the initialized catalog caches
+ * are used to determine which caches may contain tuples which need
+ * to be invalidated in other backends.
*/
void
InitCatalogCache()
{
- int cacheId; /* XXX type */
-
- if (!AMI_OVERRIDE) {
- for (cacheId = 0; cacheId < SysCacheSize; cacheId += 1) {
-
- Assert(!PointerIsValid((Pointer)SysCache[cacheId]));
-
- SysCache[cacheId] =
- InitSysCache(cacheinfo[cacheId].name,
- cacheinfo[cacheId].indname,
- cacheId,
- cacheinfo[cacheId].nkeys,
- cacheinfo[cacheId].key,
- cacheinfo[cacheId].iScanFunc);
- if (!PointerIsValid((char *)SysCache[cacheId])) {
- elog(WARN,
- "InitCatalogCache: Can't init cache %.16s(%d)",
- cacheinfo[cacheId].name,
- cacheId);
- }
-
+ int cacheId; /* XXX type */
+
+ if (!AMI_OVERRIDE)
+ {
+ for (cacheId = 0; cacheId < SysCacheSize; cacheId += 1)
+ {
+
+ Assert(!PointerIsValid((Pointer) SysCache[cacheId]));
+
+ SysCache[cacheId] =
+ InitSysCache(cacheinfo[cacheId].name,
+ cacheinfo[cacheId].indname,
+ cacheId,
+ cacheinfo[cacheId].nkeys,
+ cacheinfo[cacheId].key,
+ cacheinfo[cacheId].iScanFunc);
+ if (!PointerIsValid((char *) SysCache[cacheId]))
+ {
+ elog(WARN,
+ "InitCatalogCache: Can't init cache %.16s(%d)",
+ cacheinfo[cacheId].name,
+ cacheId);
+ }
+
+ }
}
- }
}
/*
* SearchSysCacheTuple--
*
- * A layer on top of SearchSysCache that does the initialization and
- * key-setting for you.
+ * A layer on top of SearchSysCache that does the initialization and
+ * key-setting for you.
*
* Returns the tuple if one is found, NULL if not.
*
* XXX The tuple that is returned is NOT supposed to be pfree'd!
*/
HeapTuple
-SearchSysCacheTuple(int cacheId, /* cache selection code */
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+SearchSysCacheTuple(int cacheId, /* cache selection code */
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- register HeapTuple tp;
-
- if (cacheId < 0 || cacheId >= SysCacheSize) {
- elog(WARN, "SearchSysCacheTuple: Bad cache id %d", cacheId);
- return((HeapTuple) NULL);
- }
-
- if (!AMI_OVERRIDE) {
- Assert(PointerIsValid(SysCache[cacheId]));
- } else {
- if (!PointerIsValid(SysCache[cacheId])) {
- SysCache[cacheId] =
- InitSysCache(cacheinfo[cacheId].name,
- cacheinfo[cacheId].indname,
- cacheId,
- cacheinfo[cacheId].nkeys,
- cacheinfo[cacheId].key,
- cacheinfo[cacheId].iScanFunc);
- if (!PointerIsValid(SysCache[cacheId])) {
- elog(WARN,
- "InitCatalogCache: Can't init cache %.16s(%d)",
- cacheinfo[cacheId].name,
- cacheId);
- }
-
+ register HeapTuple tp;
+
+ if (cacheId < 0 || cacheId >= SysCacheSize)
+ {
+ elog(WARN, "SearchSysCacheTuple: Bad cache id %d", cacheId);
+ return ((HeapTuple) NULL);
+ }
+
+ if (!AMI_OVERRIDE)
+ {
+ Assert(PointerIsValid(SysCache[cacheId]));
+ }
+ else
+ {
+ if (!PointerIsValid(SysCache[cacheId]))
+ {
+ SysCache[cacheId] =
+ InitSysCache(cacheinfo[cacheId].name,
+ cacheinfo[cacheId].indname,
+ cacheId,
+ cacheinfo[cacheId].nkeys,
+ cacheinfo[cacheId].key,
+ cacheinfo[cacheId].iScanFunc);
+ if (!PointerIsValid(SysCache[cacheId]))
+ {
+ elog(WARN,
+ "InitCatalogCache: Can't init cache %.16s(%d)",
+ cacheinfo[cacheId].name,
+ cacheId);
+ }
+
+ }
}
- }
-
- tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4);
- if (!HeapTupleIsValid(tp)) {
+
+ tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4);
+ if (!HeapTupleIsValid(tp))
+ {
#ifdef CACHEDEBUG
- elog(DEBUG,
- "SearchSysCacheTuple: Search %s(%d) %d %d %d %d failed",
- (*cacheinfo[cacheId].name)->data,
- cacheId, key1, key2, key3, key4);
+ elog(DEBUG,
+ "SearchSysCacheTuple: Search %s(%d) %d %d %d %d failed",
+ (*cacheinfo[cacheId].name)->data,
+ cacheId, key1, key2, key3, key4);
#endif
- return((HeapTuple) NULL);
- }
- return(tp);
+ return ((HeapTuple) NULL);
+ }
+ return (tp);
}
/*
* SearchSysCacheStruct--
- * Fills 's' with the information retrieved by calling SearchSysCache()
- * with arguments key1...key4. Retrieves only the portion of the tuple
- * which is not variable-length.
+ * Fills 's' with the information retrieved by calling SearchSysCache()
+ * with arguments key1...key4. Retrieves only the portion of the tuple
+ * which is not variable-length.
*
* NOTE: we are assuming that non-variable-length fields in the system
- * catalogs will always be defined!
+ * catalogs will always be defined!
*
* Returns 1L if a tuple was found, 0L if not.
*/
int32
SearchSysCacheStruct(int cacheId, /* cache selection code */
- char *returnStruct, /* (preallocated!) */
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+ char *returnStruct, /* (preallocated!) */
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- HeapTuple tp;
-
- if (!PointerIsValid(returnStruct)) {
- elog(WARN, "SearchSysCacheStruct: No receiving struct");
- return(0);
- }
- tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
- if (!HeapTupleIsValid(tp))
- return(0);
- memmove(returnStruct, (char *) GETSTRUCT(tp), cacheinfo[cacheId].size);
- return(1);
+ HeapTuple tp;
+
+ if (!PointerIsValid(returnStruct))
+ {
+ elog(WARN, "SearchSysCacheStruct: No receiving struct");
+ return (0);
+ }
+ tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
+ if (!HeapTupleIsValid(tp))
+ return (0);
+ memmove(returnStruct, (char *) GETSTRUCT(tp), cacheinfo[cacheId].size);
+ return (1);
}
/*
* SearchSysCacheGetAttribute--
- * Returns the attribute corresponding to 'attributeNumber' for
- * a given cached tuple.
+ * Returns the attribute corresponding to 'attributeNumber' for
+ * a given cached tuple.
*
* XXX This re-opens a relation, so this is slower.
*
* [callers all assume this returns a (struct varlena *). -ay 10/94]
*/
-void *
+void *
SearchSysCacheGetAttribute(int cacheId,
- AttrNumber attributeNumber,
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+ AttrNumber attributeNumber,
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- HeapTuple tp;
- char *cacheName;
- Relation relation;
- int32 attributeLength, attributeByValue;
- bool isNull;
- char *attributeValue;
- void *returnValue;
-
- tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
- cacheName = cacheinfo[cacheId].name;
-
- if (!HeapTupleIsValid(tp)) {
+ HeapTuple tp;
+ char *cacheName;
+ Relation relation;
+ int32 attributeLength,
+ attributeByValue;
+ bool isNull;
+ char *attributeValue;
+ void *returnValue;
+
+ tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
+ cacheName = cacheinfo[cacheId].name;
+
+ if (!HeapTupleIsValid(tp))
+ {
#ifdef CACHEDEBUG
- elog(DEBUG,
- "SearchSysCacheGetAttribute: Lookup in %s(%d) failed",
- cacheName, cacheId);
-#endif /* defined(CACHEDEBUG) */
- return(NULL);
- }
-
- relation = heap_openr(cacheName);
-
- if (attributeNumber < 0 &&
- attributeNumber > FirstLowInvalidHeapAttributeNumber) {
- attributeLength = heap_sysattrlen(attributeNumber);
- attributeByValue = heap_sysattrbyval(attributeNumber);
- } else if (attributeNumber > 0 &&
- attributeNumber <= relation->rd_rel->relnatts) {
- attributeLength =
- relation->rd_att->attrs[attributeNumber-1]->attlen;
- attributeByValue =
- relation->rd_att->attrs[attributeNumber-1]->attbyval;
- } else {
- elog(WARN,
- "SearchSysCacheGetAttribute: Bad attr # %d in %s(%d)",
- attributeNumber, cacheName, cacheId);
- return(NULL);
- }
-
- attributeValue = heap_getattr(tp,
- (Buffer) 0,
- attributeNumber,
- RelationGetTupleDescriptor(relation),
- &isNull);
-
- if (isNull) {
- /*
- * Used to be an elog(DEBUG, ...) here and a claim that it should
- * be a FATAL error, I don't think either is warranted -mer 6/9/92
- */
- return(NULL);
- }
-
- if (attributeByValue) {
- returnValue = (void *)attributeValue;
- } else {
- char *tmp;
- int size = (attributeLength < 0)
- ? VARSIZE((struct varlena *) attributeValue) /* variable length */
- : attributeLength; /* fixed length */
-
- tmp = (char *) palloc(size);
- memmove(tmp, attributeValue, size);
- returnValue = (void *)tmp;
- }
-
- heap_close(relation);
- return(returnValue);
+ elog(DEBUG,
+ "SearchSysCacheGetAttribute: Lookup in %s(%d) failed",
+ cacheName, cacheId);
+#endif /* defined(CACHEDEBUG) */
+ return (NULL);
+ }
+
+ relation = heap_openr(cacheName);
+
+ if (attributeNumber < 0 &&
+ attributeNumber > FirstLowInvalidHeapAttributeNumber)
+ {
+ attributeLength = heap_sysattrlen(attributeNumber);
+ attributeByValue = heap_sysattrbyval(attributeNumber);
+ }
+ else if (attributeNumber > 0 &&
+ attributeNumber <= relation->rd_rel->relnatts)
+ {
+ attributeLength =
+ relation->rd_att->attrs[attributeNumber - 1]->attlen;
+ attributeByValue =
+ relation->rd_att->attrs[attributeNumber - 1]->attbyval;
+ }
+ else
+ {
+ elog(WARN,
+ "SearchSysCacheGetAttribute: Bad attr # %d in %s(%d)",
+ attributeNumber, cacheName, cacheId);
+ return (NULL);
+ }
+
+ attributeValue = heap_getattr(tp,
+ (Buffer) 0,
+ attributeNumber,
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+
+ if (isNull)
+ {
+
+ /*
+ * Used to be an elog(DEBUG, ...) here and a claim that it should
+ * be a FATAL error, I don't think either is warranted -mer 6/9/92
+ */
+ return (NULL);
+ }
+
+ if (attributeByValue)
+ {
+ returnValue = (void *) attributeValue;
+ }
+ else
+ {
+ char *tmp;
+ int size = (attributeLength < 0)
+ ? VARSIZE((struct varlena *) attributeValue) /* variable length */
+ : attributeLength; /* fixed length */
+
+ tmp = (char *) palloc(size);
+ memmove(tmp, attributeValue, size);
+ returnValue = (void *) tmp;
+ }
+
+ heap_close(relation);
+ return (returnValue);
}
/*
* TypeDefaultRetrieve--
*
- * Given a type OID, return the typdefault field associated with that
- * type. The typdefault is returned as the car of a dotted pair which
- * is passed to TypeDefaultRetrieve by the calling routine.
+ * Given a type OID, return the typdefault field associated with that
+ * type. The typdefault is returned as the car of a dotted pair which
+ * is passed to TypeDefaultRetrieve by the calling routine.
*
* Returns a fixnum for types which are passed by value and a ppreserve'd
* vectori for types which are not.
*
* [identical to get_typdefault, expecting a (struct varlena *) as ret val.
- * some day, either of the functions should be removed -ay 10/94]
+ * some day, either of the functions should be removed -ay 10/94]
*/
-void *
+void *
TypeDefaultRetrieve(Oid typId)
{
- HeapTuple typeTuple;
- TypeTupleForm type;
- int32 typByVal, typLen;
- struct varlena *typDefault;
- int32 dataSize;
- void *returnValue;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(typId),
- 0,0,0);
-
- if (!HeapTupleIsValid(typeTuple)) {
-#ifdef CACHEDEBUG
- elog(DEBUG, "TypeDefaultRetrieve: Lookup in %s(%d) failed",
- (*cacheinfo[TYPOID].name)->data, TYPOID);
-#endif /* defined(CACHEDEBUG) */
- return(NULL);
- }
-
- type = (TypeTupleForm) GETSTRUCT(typeTuple);
- typByVal = type->typbyval;
- typLen = type->typlen;
-
- typDefault = (struct varlena *)
- SearchSysCacheGetAttribute(TYPOID,
- Anum_pg_type_typdefault,
- ObjectIdGetDatum(typId),
- 0,0,0);
-
- if (typDefault == (struct varlena *)NULL) {
+ HeapTuple typeTuple;
+ TypeTupleForm type;
+ int32 typByVal,
+ typLen;
+ struct varlena *typDefault;
+ int32 dataSize;
+ void *returnValue;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(typId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(typeTuple))
+ {
#ifdef CACHEDEBUG
- elog(DEBUG, "TypeDefaultRetrieve: No extractable typdefault",
- (*cacheinfo[TYPOID].name)->data, TYPOID);
-#endif /* defined(CACHEDEBUG) */
- return (NULL);
-
- }
-
- dataSize = VARSIZE(typDefault) - VARHDRSZ;
-
- if (typByVal) {
- int8 i8;
- int16 i16;
- int32 i32;
-
- if (dataSize == typLen) {
- switch (typLen) {
- case sizeof(int8):
- memmove((char *) &i8, VARDATA(typDefault), sizeof(int8));
- i32 = i8;
- break;
- case sizeof(int16):
- memmove((char *) &i16, VARDATA(typDefault), sizeof(int16));
- i32 = i16;
- break;
- case sizeof(int32):
- memmove((char *) &i32, VARDATA(typDefault), sizeof(int32));
- break;
- }
- returnValue = (void *)i32;
- } else {
- returnValue = NULL;
+ elog(DEBUG, "TypeDefaultRetrieve: Lookup in %s(%d) failed",
+ (*cacheinfo[TYPOID].name)->data, TYPOID);
+#endif /* defined(CACHEDEBUG) */
+ return (NULL);
}
- } else {
- if ((typLen < 0 && dataSize < 0) || dataSize != typLen)
- returnValue = NULL;
- else {
- returnValue = (void *)palloc(VARSIZE(typDefault));
- memmove((char *) returnValue,
- (char *) typDefault,
- (int) VARSIZE(typDefault));
+
+ type = (TypeTupleForm) GETSTRUCT(typeTuple);
+ typByVal = type->typbyval;
+ typLen = type->typlen;
+
+ typDefault = (struct varlena *)
+ SearchSysCacheGetAttribute(TYPOID,
+ Anum_pg_type_typdefault,
+ ObjectIdGetDatum(typId),
+ 0, 0, 0);
+
+ if (typDefault == (struct varlena *) NULL)
+ {
+#ifdef CACHEDEBUG
+ elog(DEBUG, "TypeDefaultRetrieve: No extractable typdefault",
+ (*cacheinfo[TYPOID].name)->data, TYPOID);
+#endif /* defined(CACHEDEBUG) */
+ return (NULL);
+
}
- }
-
- return(returnValue);
-}
+ dataSize = VARSIZE(typDefault) - VARHDRSZ;
+ if (typByVal)
+ {
+ int8 i8;
+ int16 i16;
+ int32 i32;
+
+ if (dataSize == typLen)
+ {
+ switch (typLen)
+ {
+ case sizeof(int8):
+ memmove((char *) &i8, VARDATA(typDefault), sizeof(int8));
+ i32 = i8;
+ break;
+ case sizeof(int16):
+ memmove((char *) &i16, VARDATA(typDefault), sizeof(int16));
+ i32 = i16;
+ break;
+ case sizeof(int32):
+ memmove((char *) &i32, VARDATA(typDefault), sizeof(int32));
+ break;
+ }
+ returnValue = (void *) i32;
+ }
+ else
+ {
+ returnValue = NULL;
+ }
+ }
+ else
+ {
+ if ((typLen < 0 && dataSize < 0) || dataSize != typLen)
+ returnValue = NULL;
+ else
+ {
+ returnValue = (void *) palloc(VARSIZE(typDefault));
+ memmove((char *) returnValue,
+ (char *) typDefault,
+ (int) VARSIZE(typDefault));
+ }
+ }
+
+ return (returnValue);
+}