Change SearchSysCache coding conventions so that a reference count is

maintained for each cache entry.  A cache entry will not be freed until
the matching ReleaseSysCache call has been executed.  This eliminates
worries about cache entries getting dropped while still in use.  See
my posting to pg-hackers of even date for more info.
This commit is contained in:
Tom Lane 2000-11-16 22:30:52 +00:00
parent cff23842a4
commit a933ee38bb
95 changed files with 2672 additions and 2314 deletions

View File

@ -14,30 +14,29 @@
* either version 2, or (at your option) any later version. * either version 2, or (at your option) any later version.
*/ */
#include "postgres.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include "postgres.h"
#include "miscadmin.h"
#include "access/xact.h" #include "access/xact.h"
#include "fmgr.h" #include "fmgr.h"
#include "catalog/pg_type.h" #include "miscadmin.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/syscache.h" #include "utils/lsyscache.h"
#include "array_iterator.h" #include "array_iterator.h"
static int32 static int32
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value) array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
{ {
HeapTuple typ_tuple; int16 typlen;
Form_pg_type typ_struct;
bool typbyval; bool typbyval;
int typlen;
int nitems, int nitems,
i; i;
Datum result; Datum result;
@ -66,16 +65,7 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
} }
/* Lookup element type information */ /* Lookup element type information */
typ_tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(elemtype), get_typlenbyval(elemtype, &typlen, &typbyval);
0, 0, 0);
if (!HeapTupleIsValid(typ_tuple))
{
elog(ERROR, "array_iterator: cache lookup failed for type %u", elemtype);
return 0;
}
typ_struct = (Form_pg_type) GETSTRUCT(typ_tuple);
typlen = typ_struct->typlen;
typbyval = typ_struct->typbyval;
/* Lookup the function entry point */ /* Lookup the function entry point */
fmgr_info(proc, &finfo); fmgr_info(proc, &finfo);

View File

@ -311,7 +311,7 @@ c-mode)
9) How do I efficiently access information in tables from the backend code? 9) How do I efficiently access information in tables from the backend code?
You first need to find the tuples(rows) you are interested in. There You first need to find the tuples(rows) you are interested in. There
are two ways. First, SearchSysCacheTuple() and related functions allow are two ways. First, SearchSysCache() and related functions allow
you to query the system catalogs. This is the preferred way to access you to query the system catalogs. This is the preferred way to access
system tables, because the first call to the cache loads the needed system tables, because the first call to the cache loads the needed
rows, and future requests can return the results without accessing the rows, and future requests can return the results without accessing the
@ -321,14 +321,13 @@ c-mode)
src/backend/utils/cache/lsyscache.c contains many column-specific src/backend/utils/cache/lsyscache.c contains many column-specific
cache lookup functions. cache lookup functions.
The rows returned are cached-owned versions of the heap rows. They are The rows returned are cache-owned versions of the heap rows. Therefore,
invalidated when the base table changes. Because the cache is local to you must not modify or delete the tuple returned by SearchSysCache().
each backend, you may use the pointer returned from the cache for What you *should* do is release it with ReleaseSysCache() when you are
short periods without making a copy of the tuple. If you send the done using it; this informs the cache that it can discard that tuple
pointer into a large function that will be doing its own cache if necessary. If you neglect to call ReleaseSysCache(), then the cache
lookups, it is possible the cache entry may be flushed, so you should entry will remain locked in the cache until end of transaction, which is
use SearchSysCacheTupleCopy() in these cases, and pfree() the tuple tolerable but not very desirable.
when you are done.
If you can't use the system cache, you will need to retrieve the data If you can't use the system cache, you will need to retrieve the data
directly from the heap table, using the buffer cache that is shared by directly from the heap table, using the buffer cache that is shared by
@ -344,7 +343,9 @@ c-mode)
You can also use heap_fetch() to fetch rows by block number/offset. You can also use heap_fetch() to fetch rows by block number/offset.
While scans automatically lock/unlock rows from the buffer cache, with While scans automatically lock/unlock rows from the buffer cache, with
heap_fetch(), you must pass a Buffer pointer, and ReleaseBuffer() it heap_fetch(), you must pass a Buffer pointer, and ReleaseBuffer() it
when completed. Once you have the row, you can get data that is common when completed.
Once you have the row, you can get data that is common
to all tuples, like t_self and t_oid, by merely accessing the to all tuples, like t_self and t_oid, by merely accessing the
HeapTuple structure entries. If you need a table-specific column, you HeapTuple structure entries. If you need a table-specific column, you
should take the HeapTuple pointer, and use the GETSTRUCT() macro to should take the HeapTuple pointer, and use the GETSTRUCT() macro to
@ -355,15 +356,16 @@ c-mode)
((Form_pg_class) GETSTRUCT(tuple))->relnatts ((Form_pg_class) GETSTRUCT(tuple))->relnatts
You should not directly change live tuples in this way. The best way You must not directly change live tuples in this way. The best way
is to use heap_tuplemodify() and pass it your palloc'ed tuple, and the is to use heap_modifytuple() and pass it your original tuple, and the
values you want changed. It returns another palloc'ed tuple, which you values you want changed. It returns a palloc'ed tuple, which you
pass to heap_replace(). You can delete tuples by passing the tuple's pass to heap_replace(). You can delete tuples by passing the tuple's
t_self to heap_destroy(). You can use it for heap_update() too. t_self to heap_destroy(). You use t_self for heap_update() too.
Remember, tuples can be either system cache versions, which may go
away soon after you get them, buffer cache versions, which go away Remember, tuples can be either system cache copies, which may go away
when you heap_getnext(), heap_endscan, or ReleaseBuffer(), in the after you call ReleaseSysCache(), or read directly from disk buffers,
heap_fetch() case. Or it may be a palloc'ed tuple, that you must which go away when you heap_getnext(), heap_endscan, or ReleaseBuffer(),
in the heap_fetch() case. Or it may be a palloc'ed tuple, that you must
pfree() when finished. pfree() when finished.
10) What is elog()? 10) What is elog()?

View File

@ -358,7 +358,7 @@ cases where Name and char * are used interchangeably.<P>
tables from the backend code?</H3><P> tables from the backend code?</H3><P>
You first need to find the tuples(rows) you are interested in. There You first need to find the tuples(rows) you are interested in. There
are two ways. First, <I>SearchSysCacheTuple()</I> and related functions are two ways. First, <I>SearchSysCache()</I> and related functions
allow you to query the system catalogs. This is the preferred way to allow you to query the system catalogs. This is the preferred way to
access system tables, because the first call to the cache loads the access system tables, because the first call to the cache loads the
needed rows, and future requests can return the results without needed rows, and future requests can return the results without
@ -367,15 +367,14 @@ to look up tuples. A list of available caches is located in
<I>src/backend/utils/cache/syscache.c.</I> <I>src/backend/utils/cache/syscache.c.</I>
<I>src/backend/utils/cache/lsyscache.c</I> contains many column-specific <I>src/backend/utils/cache/lsyscache.c</I> contains many column-specific
cache lookup functions.<P> cache lookup functions.<P>
The rows returned are cached-owned versions of the heap rows. They are The rows returned are cache-owned versions of the heap rows. Therefore, you
invalidated when the base table changes. Because the cache is local to must not modify or delete the tuple returned by <I>SearchSysCache()</I>. What
each backend, you may use the pointer returned from the cache for short you <I>should</I> do is release it with <I>ReleaseSysCache()</I> when you are
periods without making a copy of the tuple. If you send the pointer done using it; this informs the cache that it can discard that tuple if
into a large function that will be doing its own cache lookups, it is necessary. If you neglect to call <I>ReleaseSysCache()</I>, then the cache
possible the cache entry may be flushed, so you should use entry will remain locked in the cache until end of transaction, which is
<I>SearchSysCacheTupleCopy()</I> in these cases, and <I>pfree()</I> the tolerable but not very desirable.<P>
tuple when you are done.<P>
If you can't use the system cache, you will need to retrieve the data If you can't use the system cache, you will need to retrieve the data
directly from the heap table, using the buffer cache that is shared by directly from the heap table, using the buffer cache that is shared by
@ -392,12 +391,11 @@ and only the valid rows returned.<P>
You can also use <I>heap_fetch()</I> to fetch rows by block You can also use <I>heap_fetch()</I> to fetch rows by block
number/offset. While scans automatically lock/unlock rows from the number/offset. While scans automatically lock/unlock rows from the
buffer cache, with <I>heap_fetch(),</I> you must pass a <I>Buffer</I> buffer cache, with <I>heap_fetch(),</I> you must pass a <I>Buffer</I>
pointer, and <I>ReleaseBuffer()</I> it when completed. pointer, and <I>ReleaseBuffer()</I> it when completed.<P>
Once you have the row, you can get data that is common to all tuples, Once you have the row, you can get data that is common to all tuples,
like <I>t_self</I> and <I>t_oid,</I> by merely accessing the like <I>t_self</I> and <I>t_oid,</I> by merely accessing the
<I>HeapTuple</I> structure entries. <I>HeapTuple</I> structure entries.
If you need a table-specific column, you should take the HeapTuple If you need a table-specific column, you should take the HeapTuple
pointer, and use the <I>GETSTRUCT()</I> macro to access the pointer, and use the <I>GETSTRUCT()</I> macro to access the
table-specific start of the tuple. You then cast the pointer as a table-specific start of the tuple. You then cast the pointer as a
@ -411,18 +409,18 @@ the columns by using a structure pointer:
</CODE> </CODE>
</PRE> </PRE>
You should not directly change <I>live</I> tuples in this way. The best You must not directly change <I>live</I> tuples in this way. The best
way is to use <I>heap_tuplemodify()</I> and pass it your palloc'ed way is to use <I>heap_modifytuple()</I> and pass it your original
tuple, and the values you want changed. It returns another palloc'ed tuple, and the values you want changed. It returns a palloc'ed
tuple, which you pass to <I>heap_replace().</I> tuple, which you pass to <I>heap_replace().</I>
You can delete tuples by passing the tuple's <I>t_self</I> to You can delete tuples by passing the tuple's <I>t_self</I> to
<I>heap_destroy().</I> You can use it for <I>heap_update()</I> too. <I>heap_destroy().</I> You use <I>t_self</I> for <I>heap_update()</I> too.
Remember, tuples can be either system cache versions, which may go away Remember, tuples can be either system cache copies, which may go away after
soon after you get them, buffer cache versions, which go away when you call <I>ReleaseSysCache()</I>, or read directly from disk buffers, which
you <I>heap_getnext(),</I> <I>heap_endscan,</I> or go away when you <I>heap_getnext()</I>, <I>heap_endscan</I>, or
<I>ReleaseBuffer()</I>, in the <I>heap_fetch()</I> case. Or it may be a <I>ReleaseBuffer()</I>, in the <I>heap_fetch()</I> case. Or it may be a
palloc'ed tuple, that you must <I>pfree()</I> when finished. palloc'ed tuple, that you must <I>pfree()</I> when finished.
<H3><a name="10">10</a>) What is elog()?</H3><P> <H3><a name="10">10</a>) What is elog()?</H3><P>

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.53 2000/05/30 04:24:27 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.54 2000/11/16 22:30:15 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -36,7 +36,7 @@ static void printtup_cleanup(DestReceiver *self);
* getTypeOutAndElem -- get both typoutput and typelem for a type * getTypeOutAndElem -- get both typoutput and typelem for a type
* *
* We used to fetch these with two separate function calls, * We used to fetch these with two separate function calls,
* typtoout() and gettypelem(), which each called SearchSysCacheTuple. * typtoout() and gettypelem(), which each called SearchSysCache.
* This way takes half the time. * This way takes half the time.
* ---------------- * ----------------
*/ */
@ -44,25 +44,19 @@ int
getTypeOutAndElem(Oid type, Oid *typOutput, Oid *typElem) getTypeOutAndElem(Oid type, Oid *typOutput, Oid *typElem)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
Form_pg_type pt;
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(type), ObjectIdGetDatum(type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "getTypeOutAndElem: Cache lookup of type %u failed", type);
pt = (Form_pg_type) GETSTRUCT(typeTuple);
if (HeapTupleIsValid(typeTuple)) *typOutput = pt->typoutput;
{ *typElem = pt->typelem;
Form_pg_type pt = (Form_pg_type) GETSTRUCT(typeTuple); ReleaseSysCache(typeTuple);
return OidIsValid(*typOutput);
*typOutput = (Oid) pt->typoutput;
*typElem = (Oid) pt->typelem;
return OidIsValid(*typOutput);
}
elog(ERROR, "getTypeOutAndElem: Cache lookup of type %u failed", type);
*typOutput = InvalidOid;
*typElem = InvalidOid;
return 0;
} }
/* ---------------- /* ----------------

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.68 2000/11/08 22:09:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.69 2000/11/16 22:30:15 tgl Exp $
* *
* NOTES * NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be * some of the executor utility code such as "ExecTypeFromTL" should be
@ -401,9 +401,9 @@ TupleDescInitEntry(TupleDesc desc,
* -cim 6/14/90 * -cim 6/14/90
* ---------------- * ----------------
*/ */
tuple = SearchSysCacheTuple(TYPEOID, tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(oidtypeid), ObjectIdGetDatum(oidtypeid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
/* ---------------- /* ----------------
@ -455,25 +455,18 @@ TupleDescInitEntry(TupleDesc desc,
*/ */
if (attisset) if (attisset)
{ {
Type t = typeidType(OIDOID); att->attlen = sizeof(Oid);
att->attbyval = true;
att->attlen = typeLen(t); att->attstorage = 'p';
att->attbyval = typeByVal(t);
} }
else else
{ {
att->attlen = typeForm->typlen; att->attlen = typeForm->typlen;
att->attbyval = typeForm->typbyval; att->attbyval = typeForm->typbyval;
/*
* Default to the types storage
*/
#ifdef TUPLE_TOASTER_ACTIVE
att->attstorage = typeForm->typstorage; att->attstorage = typeForm->typstorage;
#else
att->attstorage = 'p';
#endif
} }
ReleaseSysCache(tuple);
return true; return true;
} }
@ -496,12 +489,11 @@ TupleDescMakeSelfReference(TupleDesc desc,
char *relname) char *relname)
{ {
Form_pg_attribute att; Form_pg_attribute att;
Type t = typeidType(OIDOID);
att = desc->attrs[attnum - 1]; att = desc->attrs[attnum - 1];
att->atttypid = TypeShellMake(relname); att->atttypid = TypeShellMake(relname);
att->attlen = typeLen(t); att->attlen = sizeof(Oid);
att->attbyval = typeByVal(t); att->attbyval = true;
att->attstorage = 'p'; att->attstorage = 'p';
att->attnelems = 0; att->attnelems = 0;
} }
@ -580,7 +572,7 @@ BuildDescForRelation(List *schema, char *relname)
} }
if (!TupleDescInitEntry(desc, attnum, attname, if (!TupleDescInitEntry(desc, attnum, attname,
typeTypeId(typenameType(typename)), typenameTypeId(typename),
atttypmod, attdim, attisset)) atttypmod, attdim, attisset))
{ {
/* ---------------- /* ----------------

View File

@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.64 2000/11/08 22:09:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.65 2000/11/16 22:30:15 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1140,6 +1140,7 @@ initGISTstate(GISTSTATE *giststate, Relation index)
equal_proc; equal_proc;
HeapTuple htup; HeapTuple htup;
Form_pg_index itupform; Form_pg_index itupform;
Oid indexrelid;
consistent_proc = index_getprocid(index, 1, GIST_CONSISTENT_PROC); consistent_proc = index_getprocid(index, 1, GIST_CONSISTENT_PROC);
union_proc = index_getprocid(index, 1, GIST_UNION_PROC); union_proc = index_getprocid(index, 1, GIST_UNION_PROC);
@ -1157,32 +1158,32 @@ initGISTstate(GISTSTATE *giststate, Relation index)
fmgr_info(equal_proc, &giststate->equalFn); fmgr_info(equal_proc, &giststate->equalFn);
/* see if key type is different from type of attribute being indexed */ /* see if key type is different from type of attribute being indexed */
htup = SearchSysCacheTuple(INDEXRELID, htup = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(RelationGetRelid(index)), ObjectIdGetDatum(RelationGetRelid(index)),
0, 0, 0); 0, 0, 0);
itupform = (Form_pg_index) GETSTRUCT(htup);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup))
elog(ERROR, "initGISTstate: index %u not found", elog(ERROR, "initGISTstate: index %u not found",
RelationGetRelid(index)); RelationGetRelid(index));
itupform = (Form_pg_index) GETSTRUCT(htup);
giststate->haskeytype = itupform->indhaskeytype; giststate->haskeytype = itupform->indhaskeytype;
indexrelid = itupform->indexrelid;
ReleaseSysCache(htup);
if (giststate->haskeytype) if (giststate->haskeytype)
{ {
/* key type is different -- is it byval? */ /* key type is different -- is it byval? */
htup = SearchSysCacheTuple(ATTNUM, htup = SearchSysCache(ATTNUM,
ObjectIdGetDatum(itupform->indexrelid), ObjectIdGetDatum(indexrelid),
UInt16GetDatum(FirstOffsetNumber), UInt16GetDatum(FirstOffsetNumber),
0, 0); 0, 0);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup))
{
elog(ERROR, "initGISTstate: no attribute tuple %u %d", elog(ERROR, "initGISTstate: no attribute tuple %u %d",
itupform->indexrelid, FirstOffsetNumber); indexrelid, FirstOffsetNumber);
return;
}
giststate->keytypbyval = (((Form_pg_attribute) htup)->attbyval); giststate->keytypbyval = (((Form_pg_attribute) htup)->attbyval);
ReleaseSysCache(htup);
} }
else else
giststate->keytypbyval = FALSE; giststate->keytypbyval = FALSE;
return;
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.46 2000/07/14 22:17:30 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.47 2000/11/16 22:30:16 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -482,9 +482,9 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
if (cachesearch) if (cachesearch)
{ {
tuple = SearchSysCacheTuple(OPEROID, tuple = SearchSysCache(OPEROID,
ObjectIdGetDatum(operatorObjectId), ObjectIdGetDatum(operatorObjectId),
0, 0, 0); 0, 0, 0);
} }
else else
{ {
@ -505,24 +505,25 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
{ {
if (!cachesearch) if (!cachesearch)
heap_endscan(scan); heap_endscan(scan);
elog(ERROR, "OperatorObjectIdFillScanKeyEntry: unknown operator %u", elog(ERROR, "OperatorRelationFillScanKeyEntry: unknown operator %u",
operatorObjectId); operatorObjectId);
} }
entry->sk_flags = 0; entry->sk_flags = 0;
entry->sk_procedure = ((Form_pg_operator) GETSTRUCT(tuple))->oprcode; entry->sk_procedure = ((Form_pg_operator) GETSTRUCT(tuple))->oprcode;
fmgr_info(entry->sk_procedure, &entry->sk_func);
entry->sk_nargs = entry->sk_func.fn_nargs;
if (!cachesearch) if (cachesearch)
ReleaseSysCache(tuple);
else
heap_endscan(scan); heap_endscan(scan);
if (!RegProcedureIsValid(entry->sk_procedure)) if (!RegProcedureIsValid(entry->sk_procedure))
{
elog(ERROR, elog(ERROR,
"OperatorObjectIdFillScanKeyEntry: no procedure for operator %u", "OperatorRelationFillScanKeyEntry: no procedure for operator %u",
operatorObjectId); operatorObjectId);
}
fmgr_info(entry->sk_procedure, &entry->sk_func);
entry->sk_nargs = entry->sk_func.fn_nargs;
} }
@ -547,16 +548,16 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
HeapTuple tuple; HeapTuple tuple;
Form_pg_index iform; Form_pg_index iform;
StrategyMap map; StrategyMap map;
AttrNumber attributeNumber; AttrNumber attNumber;
int attributeIndex; int attIndex;
Oid operatorClassObjectId[INDEX_MAX_KEYS]; Oid operatorClassObjectId[INDEX_MAX_KEYS];
bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized(); bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
if (cachesearch) if (cachesearch)
{ {
tuple = SearchSysCacheTuple(INDEXRELID, tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexObjectId), ObjectIdGetDatum(indexObjectId),
0, 0, 0); 0, 0, 0);
} }
else else
{ {
@ -583,19 +584,23 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
* XXX note that the following assumes the INDEX tuple is well formed * XXX note that the following assumes the INDEX tuple is well formed
* and that the *key and *class are 0 terminated. * and that the *key and *class are 0 terminated.
*/ */
for (attributeIndex = 0; attributeIndex < maxAttributeNumber; attributeIndex++) for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{ {
if (!OidIsValid(iform->indkey[attributeIndex])) if (!OidIsValid(iform->indkey[attIndex]))
{ {
if (attributeIndex == InvalidAttrNumber) if (attIndex == InvalidAttrNumber)
elog(ERROR, "IndexSupportInitialize: no pg_index tuple"); elog(ERROR, "IndexSupportInitialize: no pg_index tuple");
break; break;
} }
operatorClassObjectId[attributeIndex] = iform->indclass[attributeIndex]; operatorClassObjectId[attIndex] = iform->indclass[attIndex];
} }
if (!cachesearch) if (cachesearch)
{
ReleaseSysCache(tuple);
}
else
{ {
heap_endscan(scan); heap_endscan(scan);
heap_close(relation, AccessShareLock); heap_close(relation, AccessShareLock);
@ -614,20 +619,19 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
relation = heap_openr(AccessMethodProcedureRelationName, relation = heap_openr(AccessMethodProcedureRelationName,
AccessShareLock); AccessShareLock);
for (attributeNumber = 1; attributeNumber <= maxAttributeNumber; for (attNumber = 1; attNumber <= maxAttributeNumber; attNumber++)
attributeNumber++)
{ {
int16 support; int16 support;
Form_pg_amproc aform; Form_pg_amproc aform;
RegProcedure *loc; RegProcedure *loc;
loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)]; loc = &indexSupport[((attNumber - 1) * maxSupportNumber)];
for (support = 0; support < maxSupportNumber; ++support) for (support = 0; support < maxSupportNumber; ++support)
loc[support] = InvalidOid; loc[support] = InvalidOid;
entry[1].sk_argument = entry[1].sk_argument =
ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]); ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
scan = heap_beginscan(relation, false, SnapshotNow, 2, entry); scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
@ -654,17 +658,16 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock); relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
operatorRelation = heap_openr(OperatorRelationName, AccessShareLock); operatorRelation = heap_openr(OperatorRelationName, AccessShareLock);
for (attributeNumber = maxAttributeNumber; attributeNumber > 0; for (attNumber = maxAttributeNumber; attNumber > 0; attNumber--)
attributeNumber--)
{ {
StrategyNumber strategy; StrategyNumber strategy;
entry[1].sk_argument = entry[1].sk_argument =
ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]); ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
map = IndexStrategyGetStrategyMap(indexStrategy, map = IndexStrategyGetStrategyMap(indexStrategy,
maxStrategyNumber, maxStrategyNumber,
attributeNumber); attNumber);
for (strategy = 1; strategy <= maxStrategyNumber; strategy++) for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy)); ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy));

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.82 2000/11/10 00:33:08 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.83 2000/11/16 22:30:16 tgl Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
@ -1112,6 +1112,7 @@ CommitTransaction(void)
AtEOXact_nbtree(); AtEOXact_nbtree();
AtCommit_Cache(); AtCommit_Cache();
AtCommit_Locks(); AtCommit_Locks();
AtEOXact_CatCache(true);
AtCommit_Memory(); AtCommit_Memory();
AtEOXact_Files(); AtEOXact_Files();
@ -1192,6 +1193,7 @@ AbortTransaction(void)
AtEOXact_SPI(); AtEOXact_SPI();
AtEOXact_nbtree(); AtEOXact_nbtree();
AtAbort_Cache(); AtAbort_Cache();
AtEOXact_CatCache(false);
AtAbort_Memory(); AtAbort_Memory();
AtEOXact_Files(); AtEOXact_Files();

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.42 2000/11/03 19:02:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.43 2000/11/16 22:30:17 tgl Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.
@ -77,6 +77,7 @@ ChangeAcl(char *relname,
*new_acl; *new_acl;
Relation relation; Relation relation;
HeapTuple tuple; HeapTuple tuple;
HeapTuple newtuple;
Datum aclDatum; Datum aclDatum;
Datum values[Natts_pg_class]; Datum values[Natts_pg_class];
char nulls[Natts_pg_class]; char nulls[Natts_pg_class];
@ -89,9 +90,9 @@ ChangeAcl(char *relname,
* there's no ACL, create a default using the pg_class.relowner field. * there's no ACL, create a default using the pg_class.relowner field.
*/ */
relation = heap_openr(RelationRelationName, RowExclusiveLock); relation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCache(RELNAME,
PointerGetDatum(relname), PointerGetDatum(relname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
@ -134,14 +135,16 @@ ChangeAcl(char *relname,
} }
replaces[Anum_pg_class_relacl - 1] = 'r'; replaces[Anum_pg_class_relacl - 1] = 'r';
values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl); values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
tuple = heap_modifytuple(tuple, relation, values, nulls, replaces); newtuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
heap_update(relation, &tuple->t_self, tuple, NULL); ReleaseSysCache(tuple);
heap_update(relation, &newtuple->t_self, newtuple, NULL);
/* keep the catalog indices up to date */ /* keep the catalog indices up to date */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
idescs); idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, relation, tuple); CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newtuple);
CatalogCloseIndices(Num_pg_class_indices, idescs); CatalogCloseIndices(Num_pg_class_indices, idescs);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
@ -156,11 +159,14 @@ get_grosysid(char *groname)
HeapTuple tuple; HeapTuple tuple;
AclId id = 0; AclId id = 0;
tuple = SearchSysCacheTuple(GRONAME, tuple = SearchSysCache(GRONAME,
PointerGetDatum(groname), PointerGetDatum(groname),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))
{
id = ((Form_pg_group) GETSTRUCT(tuple))->grosysid; id = ((Form_pg_group) GETSTRUCT(tuple))->grosysid;
ReleaseSysCache(tuple);
}
else else
elog(ERROR, "non-existent group \"%s\"", groname); elog(ERROR, "non-existent group \"%s\"", groname);
return id; return id;
@ -172,11 +178,14 @@ get_groname(AclId grosysid)
HeapTuple tuple; HeapTuple tuple;
char *name = NULL; char *name = NULL;
tuple = SearchSysCacheTuple(GROSYSID, tuple = SearchSysCache(GROSYSID,
ObjectIdGetDatum(grosysid), ObjectIdGetDatum(grosysid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))
name = NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname); {
name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname));
ReleaseSysCache(tuple);
}
else else
elog(NOTICE, "get_groname: group %u not found", grosysid); elog(NOTICE, "get_groname: group %u not found", grosysid);
return name; return name;
@ -185,6 +194,7 @@ get_groname(AclId grosysid)
static bool static bool
in_group(AclId uid, AclId gid) in_group(AclId uid, AclId gid)
{ {
bool result = false;
HeapTuple tuple; HeapTuple tuple;
Datum att; Datum att;
bool isNull; bool isNull;
@ -193,9 +203,9 @@ in_group(AclId uid, AclId gid)
int i, int i,
num; num;
tuple = SearchSysCacheTuple(GROSYSID, tuple = SearchSysCache(GROSYSID,
ObjectIdGetDatum(gid), ObjectIdGetDatum(gid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))
{ {
att = SysCacheGetAttr(GROSYSID, att = SysCacheGetAttr(GROSYSID,
@ -212,13 +222,17 @@ in_group(AclId uid, AclId gid)
for (i = 0; i < num; ++i) for (i = 0; i < num; ++i)
{ {
if (aidp[i] == uid) if (aidp[i] == uid)
return true; {
result = true;
break;
}
} }
} }
ReleaseSysCache(tuple);
} }
else else
elog(NOTICE, "in_group: group %u not found", gid); elog(NOTICE, "in_group: group %u not found", gid);
return false; return result;
} }
/* /*
@ -342,9 +356,9 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
bool isNull; bool isNull;
Acl *acl; Acl *acl;
tuple = SearchSysCacheTuple(SHADOWSYSID, tuple = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(userid), ObjectIdGetDatum(userid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_aclcheck: invalid user id %u", elog(ERROR, "pg_aclcheck: invalid user id %u",
(unsigned) userid); (unsigned) userid);
@ -363,6 +377,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
{ {
elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied", elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied",
relname); relname);
ReleaseSysCache(tuple);
return ACLCHECK_NO_PRIV; return ACLCHECK_NO_PRIV;
} }
@ -375,15 +390,19 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
elog(DEBUG, "pg_aclcheck: \"%s\" is superuser", elog(DEBUG, "pg_aclcheck: \"%s\" is superuser",
usename); usename);
#endif #endif
ReleaseSysCache(tuple);
return ACLCHECK_OK; return ACLCHECK_OK;
} }
ReleaseSysCache(tuple);
/* caution: usename is inaccessible beyond this point... */
/* /*
* Normal case: get the relation's ACL from pg_class * Normal case: get the relation's ACL from pg_class
*/ */
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCache(RELNAME,
PointerGetDatum(relname), PointerGetDatum(relname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_aclcheck: class \"%s\" not found", relname); elog(ERROR, "pg_aclcheck: class \"%s\" not found", relname);
@ -404,8 +423,11 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
} }
result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode); result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode);
if (acl) if (acl)
pfree(acl); pfree(acl);
ReleaseSysCache(tuple);
return result; return result;
} }
@ -415,12 +437,12 @@ pg_ownercheck(Oid userid,
int cacheid) int cacheid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id = 0; AclId owner_id;
char *usename; char *usename;
tuple = SearchSysCacheTuple(SHADOWSYSID, tuple = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(userid), ObjectIdGetDatum(userid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_ownercheck: invalid user id %u", elog(ERROR, "pg_ownercheck: invalid user id %u",
(unsigned) userid); (unsigned) userid);
@ -435,11 +457,16 @@ pg_ownercheck(Oid userid,
elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
usename); usename);
#endif #endif
ReleaseSysCache(tuple);
return 1; return 1;
} }
tuple = SearchSysCacheTuple(cacheid, PointerGetDatum(value), ReleaseSysCache(tuple);
0, 0, 0); /* caution: usename is inaccessible beyond this point... */
tuple = SearchSysCache(cacheid,
PointerGetDatum(value),
0, 0, 0);
switch (cacheid) switch (cacheid)
{ {
case OPEROID: case OPEROID:
@ -468,9 +495,12 @@ pg_ownercheck(Oid userid,
break; break;
default: default:
elog(ERROR, "pg_ownercheck: invalid cache id: %d", cacheid); elog(ERROR, "pg_ownercheck: invalid cache id: %d", cacheid);
owner_id = 0; /* keep compiler quiet */
break; break;
} }
ReleaseSysCache(tuple);
return userid == owner_id; return userid == owner_id;
} }
@ -482,15 +512,15 @@ pg_func_ownercheck(Oid userid,
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; AclId owner_id;
char *username; char *usename;
tuple = SearchSysCacheTuple(SHADOWSYSID, tuple = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(userid), ObjectIdGetDatum(userid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_func_ownercheck: invalid user id %u", elog(ERROR, "pg_func_ownercheck: invalid user id %u",
(unsigned) userid); (unsigned) userid);
username = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename); usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
/* /*
* Superusers bypass all permission-checking. * Superusers bypass all permission-checking.
@ -499,21 +529,27 @@ pg_func_ownercheck(Oid userid,
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG_TRACE
elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
username); usename);
#endif #endif
ReleaseSysCache(tuple);
return 1; return 1;
} }
tuple = SearchSysCacheTuple(PROCNAME, ReleaseSysCache(tuple);
PointerGetDatum(funcname), /* caution: usename is inaccessible beyond this point... */
Int32GetDatum(nargs),
PointerGetDatum(arglist), tuple = SearchSysCache(PROCNAME,
0); PointerGetDatum(funcname),
Int32GetDatum(nargs),
PointerGetDatum(arglist),
0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
func_error("pg_func_ownercheck", funcname, nargs, arglist, NULL); func_error("pg_func_ownercheck", funcname, nargs, arglist, NULL);
owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
ReleaseSysCache(tuple);
return userid == owner_id; return userid == owner_id;
} }
@ -524,15 +560,15 @@ pg_aggr_ownercheck(Oid userid,
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; AclId owner_id;
char *username; char *usename;
tuple = SearchSysCacheTuple(SHADOWSYSID, tuple = SearchSysCache(SHADOWSYSID,
PointerGetDatum(userid), PointerGetDatum(userid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_aggr_ownercheck: invalid user id %u", elog(ERROR, "pg_aggr_ownercheck: invalid user id %u",
(unsigned) userid); (unsigned) userid);
username = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename); usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
/* /*
* Superusers bypass all permission-checking. * Superusers bypass all permission-checking.
@ -541,20 +577,25 @@ pg_aggr_ownercheck(Oid userid,
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG_TRACE
elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser", elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser",
username); usename);
#endif #endif
ReleaseSysCache(tuple);
return 1; return 1;
} }
tuple = SearchSysCacheTuple(AGGNAME, ReleaseSysCache(tuple);
PointerGetDatum(aggname), /* caution: usename is inaccessible beyond this point... */
ObjectIdGetDatum(basetypeID),
0, 0);
tuple = SearchSysCache(AGGNAME,
PointerGetDatum(aggname),
ObjectIdGetDatum(basetypeID),
0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
agg_error("pg_aggr_ownercheck", aggname, basetypeID); agg_error("pg_aggr_ownercheck", aggname, basetypeID);
owner_id = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggowner; owner_id = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggowner;
ReleaseSysCache(tuple);
return userid == owner_id; return userid == owner_id;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.36 2000/10/22 05:14:01 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.37 2000/11/16 22:30:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -20,7 +20,7 @@
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/syscache.h" #include "utils/lsyscache.h"
#ifdef OLD_FILE_NAMING #ifdef OLD_FILE_NAMING
/* /*
@ -251,12 +251,10 @@ newoid()
void void
fillatt(TupleDesc tupleDesc) fillatt(TupleDesc tupleDesc)
{ {
Form_pg_attribute *attributeP;
Form_pg_type typp;
HeapTuple tuple;
int i;
int natts = tupleDesc->natts; int natts = tupleDesc->natts;
Form_pg_attribute *att = tupleDesc->attrs; Form_pg_attribute *att = tupleDesc->attrs;
Form_pg_attribute *attributeP;
int i;
if (natts < 0 || natts > MaxHeapAttributeNumber) if (natts < 0 || natts > MaxHeapAttributeNumber)
elog(ERROR, "fillatt: %d attributes is too large", natts); elog(ERROR, "fillatt: %d attributes is too large", natts);
@ -268,33 +266,23 @@ fillatt(TupleDesc tupleDesc)
attributeP = &att[0]; attributeP = &att[0];
for (i = 0; i < natts;) for (i = 1; i <= natts; i++)
{ {
tuple = SearchSysCacheTuple(TYPEOID, (*attributeP)->attnum = (int16) i;
ObjectIdGetDatum((*attributeP)->atttypid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
elog(ERROR, "fillatt: unknown atttypid %d",
(*attributeP)->atttypid);
}
else
{
(*attributeP)->attnum = (int16) ++i;
/* /*
* Check if the attr is a set before messing with the length * Check if the attr is a set before messing with the length
* and byval, since those were already set in * and byval, since those were already set in
* TupleDescInitEntry. In fact, this seems redundant here, * TupleDescInitEntry. In fact, this seems redundant here,
* but who knows what I'll break if I take it out... * but who knows what I'll break if I take it out...
*/ */
if (!(*attributeP)->attisset) if (!(*attributeP)->attisset)
{ {
typp = (Form_pg_type) GETSTRUCT(tuple); /* XXX */ get_typlenbyval((*attributeP)->atttypid,
(*attributeP)->attlen = typp->typlen; & (*attributeP)->attlen,
(*attributeP)->attbyval = typp->typbyval; & (*attributeP)->attbyval);
}
} }
attributeP += 1;
attributeP++;
} }
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.151 2000/11/08 22:09:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.152 2000/11/16 22:30:17 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -488,7 +488,6 @@ CheckAttributeNames(TupleDesc tupdesc)
Oid Oid
RelnameFindRelid(const char *relname) RelnameFindRelid(const char *relname)
{ {
HeapTuple tuple;
Oid relid; Oid relid;
/* /*
@ -497,19 +496,16 @@ RelnameFindRelid(const char *relname)
*/ */
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
{ {
tuple = SearchSysCacheTuple(RELNAME, relid = GetSysCacheOid(RELNAME,
PointerGetDatum(relname), PointerGetDatum(relname),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tuple))
relid = tuple->t_data->t_oid;
else
relid = InvalidOid;
} }
else else
{ {
Relation pg_class_desc; Relation pg_class_desc;
ScanKeyData key; ScanKeyData key;
HeapScanDesc pg_class_scan; HeapScanDesc pg_class_scan;
HeapTuple tuple;
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock); pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
@ -756,8 +752,8 @@ AddNewRelationType(char *typeName, Oid new_rel_oid)
*/ */
new_type_oid = TypeCreate(typeName, /* type name */ new_type_oid = TypeCreate(typeName, /* type name */
new_rel_oid, /* relation oid */ new_rel_oid, /* relation oid */
typeLen(typeidType(OIDOID)), /* internal size */ sizeof(Oid), /* internal size */
typeLen(typeidType(OIDOID)), /* external size */ sizeof(Oid), /* external size */
'c', /* type-type (catalog) */ 'c', /* type-type (catalog) */
',', /* default array delimiter */ ',', /* default array delimiter */
"int4in", /* input procedure */ "int4in", /* input procedure */
@ -1080,15 +1076,12 @@ DeleteRelationTuple(Relation rel)
*/ */
pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock); pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
tup = SearchSysCacheTupleCopy(RELOID, tup = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(rel->rd_id), ObjectIdGetDatum(rel->rd_id),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
heap_close(pg_class_desc, RowExclusiveLock);
elog(ERROR, "Relation \"%s\" does not exist", elog(ERROR, "Relation \"%s\" does not exist",
RelationGetRelationName(rel)); RelationGetRelationName(rel));
}
/* ---------------- /* ----------------
* delete the relation tuple from pg_class, and finish up. * delete the relation tuple from pg_class, and finish up.
@ -1136,14 +1129,15 @@ RelationTruncateIndexes(Oid heapId)
indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid; indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid;
indexInfo = BuildIndexInfo(indexTuple); indexInfo = BuildIndexInfo(indexTuple);
/* Fetch the pg_class tuple associated with this index */ /* Fetch access method from pg_class tuple for this index */
classTuple = SearchSysCacheTupleCopy(RELOID, classTuple = SearchSysCache(RELOID,
ObjectIdGetDatum(indexId), ObjectIdGetDatum(indexId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(classTuple)) if (!HeapTupleIsValid(classTuple))
elog(ERROR, "RelationTruncateIndexes: index %u not found in pg_class", elog(ERROR, "RelationTruncateIndexes: index %u not found in pg_class",
indexId); indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam; accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
ReleaseSysCache(classTuple);
/* /*
* We have to re-open the heap rel each time through this loop * We have to re-open the heap rel each time through this loop
@ -1258,19 +1252,17 @@ DeleteAttributeTuples(Relation rel)
attnum <= rel->rd_att->natts; attnum <= rel->rd_att->natts;
attnum++) attnum++)
{ {
if (HeapTupleIsValid(tup = SearchSysCacheTupleCopy(ATTNUM, tup = SearchSysCacheCopy(ATTNUM,
ObjectIdGetDatum(RelationGetRelid(rel)), ObjectIdGetDatum(RelationGetRelid(rel)),
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0))) 0, 0);
if (HeapTupleIsValid(tup))
{ {
/*** Delete any comments associated with this attribute ***/ /*** Delete any comments associated with this attribute ***/
DeleteComments(tup->t_data->t_oid); DeleteComments(tup->t_data->t_oid);
heap_delete(pg_attribute_desc, &tup->t_self, NULL); heap_delete(pg_attribute_desc, &tup->t_self, NULL);
heap_freetuple(tup); heap_freetuple(tup);
} }
} }
@ -1586,9 +1578,10 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
return; /* done if pg_attribute is OK */ return; /* done if pg_attribute is OK */
attrrel = heap_openr(AttributeRelationName, RowExclusiveLock); attrrel = heap_openr(AttributeRelationName, RowExclusiveLock);
atttup = SearchSysCacheTupleCopy(ATTNUM, atttup = SearchSysCacheCopy(ATTNUM,
ObjectIdGetDatum(RelationGetRelid(rel)), ObjectIdGetDatum(RelationGetRelid(rel)),
(Datum) attnum, 0, 0); Int16GetDatum(attnum),
0, 0);
if (!HeapTupleIsValid(atttup)) if (!HeapTupleIsValid(atttup))
elog(ERROR, "cache lookup of attribute %d in relation %u failed", elog(ERROR, "cache lookup of attribute %d in relation %u failed",
attnum, RelationGetRelid(rel)); attnum, RelationGetRelid(rel));
@ -1953,11 +1946,12 @@ AddRelationRawConstraints(Relation rel,
* message, but for ALTER TABLE ADD ATTRIBUTE this'd be important.) * message, but for ALTER TABLE ADD ATTRIBUTE this'd be important.)
*/ */
relrel = heap_openr(RelationRelationName, RowExclusiveLock); relrel = heap_openr(RelationRelationName, RowExclusiveLock);
reltup = SearchSysCacheTupleCopy(RELOID, reltup = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(RelationGetRelid(rel)), ObjectIdGetDatum(RelationGetRelid(rel)),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
elog(ERROR, "cache lookup of relation %u failed", RelationGetRelid(rel)); elog(ERROR, "cache lookup of relation %u failed",
RelationGetRelid(rel));
relStruct = (Form_pg_class) GETSTRUCT(reltup); relStruct = (Form_pg_class) GETSTRUCT(reltup);
relStruct->relchecks = numchecks; relStruct->relchecks = numchecks;
@ -1970,8 +1964,8 @@ AddRelationRawConstraints(Relation rel,
CatalogIndexInsert(relidescs, Num_pg_class_indices, relrel, reltup); CatalogIndexInsert(relidescs, Num_pg_class_indices, relrel, reltup);
CatalogCloseIndices(Num_pg_class_indices, relidescs); CatalogCloseIndices(Num_pg_class_indices, relidescs);
heap_close(relrel, RowExclusiveLock);
heap_freetuple(reltup); heap_freetuple(reltup);
heap_close(relrel, RowExclusiveLock);
} }
static void static void

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.129 2000/11/08 22:09:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.130 2000/11/16 22:30:17 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -174,9 +174,9 @@ BuildFuncTupleDesc(Oid funcOid)
/* /*
* Lookup the function to get its name and return type. * Lookup the function to get its name and return type.
*/ */
tuple = SearchSysCacheTuple(PROCOID, tuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcOid), ObjectIdGetDatum(funcOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "Function %u does not exist", funcOid); elog(ERROR, "Function %u does not exist", funcOid);
retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype; retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;
@ -187,12 +187,14 @@ BuildFuncTupleDesc(Oid funcOid)
namestrcpy(&funcTupDesc->attrs[0]->attname, namestrcpy(&funcTupDesc->attrs[0]->attname,
NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname)); NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname));
ReleaseSysCache(tuple);
/* /*
* Lookup the return type in pg_type for the type length etc. * Lookup the return type in pg_type for the type length etc.
*/ */
tuple = SearchSysCacheTuple(TYPEOID, tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(retType), ObjectIdGetDatum(retType),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "Type %u does not exist", retType); elog(ERROR, "Type %u does not exist", retType);
@ -208,6 +210,8 @@ BuildFuncTupleDesc(Oid funcOid)
funcTupDesc->attrs[0]->attstorage = 'p'; funcTupDesc->attrs[0]->attstorage = 'p';
funcTupDesc->attrs[0]->attalign = ((Form_pg_type) GETSTRUCT(tuple))->typalign; funcTupDesc->attrs[0]->attalign = ((Form_pg_type) GETSTRUCT(tuple))->typalign;
ReleaseSysCache(tuple);
return funcTupDesc; return funcTupDesc;
} }
@ -759,10 +763,12 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
/* open the index system catalog relation */ /* open the index system catalog relation */
pg_index = heap_openr(IndexRelationName, RowExclusiveLock); pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
tuple = SearchSysCacheTuple(INDEXRELID, tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexoid), ObjectIdGetDatum(indexoid),
0, 0, 0); 0, 0, 0);
Assert(HeapTupleIsValid(tuple)); if (!HeapTupleIsValid(tuple))
elog(ERROR, "UpdateIndexPredicate: cache lookup failed for index %u",
indexoid);
for (i = 0; i < Natts_pg_index; i++) for (i = 0; i < Natts_pg_index; i++)
{ {
@ -779,6 +785,8 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
heap_update(pg_index, &newtup->t_self, newtup, NULL); heap_update(pg_index, &newtup->t_self, newtup, NULL);
heap_freetuple(newtup); heap_freetuple(newtup);
ReleaseSysCache(tuple);
heap_close(pg_index, RowExclusiveLock); heap_close(pg_index, RowExclusiveLock);
pfree(predText); pfree(predText);
} }
@ -1069,11 +1077,12 @@ index_drop(Oid indexId)
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock); relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
/* Remove the pg_class tuple for the index itself */ /* Remove the pg_class tuple for the index itself */
tuple = SearchSysCacheTupleCopy(RELOID, tuple = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(indexId), ObjectIdGetDatum(indexId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple))
Assert(HeapTupleIsValid(tuple)); elog(ERROR, "index_drop: cache lookup failed for index %u",
indexId);
heap_delete(relationRelation, &tuple->t_self, NULL); heap_delete(relationRelation, &tuple->t_self, NULL);
heap_freetuple(tuple); heap_freetuple(tuple);
@ -1098,10 +1107,10 @@ index_drop(Oid indexId)
attnum = 1; /* indexes start at 1 */ attnum = 1; /* indexes start at 1 */
while (HeapTupleIsValid(tuple = SearchSysCacheTupleCopy(ATTNUM, while (HeapTupleIsValid(tuple = SearchSysCacheCopy(ATTNUM,
ObjectIdGetDatum(indexId), ObjectIdGetDatum(indexId),
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0))) 0, 0)))
{ {
heap_delete(attributeRelation, &tuple->t_self, NULL); heap_delete(attributeRelation, &tuple->t_self, NULL);
heap_freetuple(tuple); heap_freetuple(tuple);
@ -1115,10 +1124,12 @@ index_drop(Oid indexId)
*/ */
indexRelation = heap_openr(IndexRelationName, RowExclusiveLock); indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
tuple = SearchSysCacheTupleCopy(INDEXRELID, tuple = SearchSysCacheCopy(INDEXRELID,
ObjectIdGetDatum(indexId), ObjectIdGetDatum(indexId),
0, 0, 0); 0, 0, 0);
Assert(HeapTupleIsValid(tuple)); if (!HeapTupleIsValid(tuple))
elog(ERROR, "index_drop: cache lookup failed for index %u",
indexId);
heap_delete(indexRelation, &tuple->t_self, NULL); heap_delete(indexRelation, &tuple->t_self, NULL);
heap_freetuple(tuple); heap_freetuple(tuple);
@ -1318,21 +1329,24 @@ LockClassinfoForUpdate(Oid relid, HeapTuple rtup,
Buffer *buffer, bool confirmCommitted) Buffer *buffer, bool confirmCommitted)
{ {
HeapTuple classTuple; HeapTuple classTuple;
Form_pg_class pgcform;
bool test; bool test;
Relation relationRelation; Relation relationRelation;
classTuple = SearchSysCacheTuple(RELOID, PointerGetDatum(relid),
0, 0, 0);
if (!HeapTupleIsValid(classTuple))
return false;
rtup->t_self = classTuple->t_self;
pgcform = (Form_pg_class) GETSTRUCT(classTuple);
/* /*
* NOTE: get and hold RowExclusiveLock on pg_class, because caller will * NOTE: get and hold RowExclusiveLock on pg_class, because caller will
* probably modify the rel's pg_class tuple later on. * probably modify the rel's pg_class tuple later on.
*/ */
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock); relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
classTuple = SearchSysCache(RELOID, PointerGetDatum(relid),
0, 0, 0);
if (!HeapTupleIsValid(classTuple))
{
heap_close(relationRelation, NoLock);
return false;
}
rtup->t_self = classTuple->t_self;
ReleaseSysCache(classTuple);
test = heap_mark4update(relationRelation, rtup, buffer); test = heap_mark4update(relationRelation, rtup, buffer);
switch (test) switch (test)
{ {
@ -1418,9 +1432,9 @@ setRelhasindex(Oid relid, bool hasindex)
if (!IsIgnoringSystemIndexes()) if (!IsIgnoringSystemIndexes())
{ {
tuple = SearchSysCacheTupleCopy(RELOID, tuple = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0);
} }
else else
{ {
@ -1542,9 +1556,9 @@ UpdateStats(Oid relid, long reltuples)
if (!in_place_upd) if (!in_place_upd)
{ {
tuple = SearchSysCacheTupleCopy(RELOID, tuple = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0);
} }
else else
{ {
@ -1887,19 +1901,20 @@ IndexGetRelation(Oid indexId)
{ {
HeapTuple tuple; HeapTuple tuple;
Form_pg_index index; Form_pg_index index;
Oid result;
tuple = SearchSysCacheTuple(INDEXRELID, tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexId), ObjectIdGetDatum(indexId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
elog(ERROR, "IndexGetRelation: can't find index id %u", elog(ERROR, "IndexGetRelation: can't find index id %u",
indexId); indexId);
}
index = (Form_pg_index) GETSTRUCT(tuple); index = (Form_pg_index) GETSTRUCT(tuple);
Assert(index->indexrelid == indexId); Assert(index->indexrelid == indexId);
return index->indrelid; result = index->indrelid;
ReleaseSysCache(tuple);
return result;
} }
/* --------------------------------- /* ---------------------------------
@ -1965,12 +1980,13 @@ reindex_index(Oid indexId, bool force)
heap_close(indexRelation, AccessShareLock); heap_close(indexRelation, AccessShareLock);
/* Fetch the classTuple associated with this index */ /* Fetch the classTuple associated with this index */
classTuple = SearchSysCacheTuple(RELOID, classTuple = SearchSysCache(RELOID,
ObjectIdGetDatum(indexId), ObjectIdGetDatum(indexId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(classTuple)) if (!HeapTupleIsValid(classTuple))
elog(ERROR, "reindex_index: index %u not found in pg_class", indexId); elog(ERROR, "reindex_index: index %u not found in pg_class", indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam; accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
ReleaseSysCache(classTuple);
/* Open our index relation */ /* Open our index relation */
heapRelation = heap_open(heapId, ExclusiveLock); heapRelation = heap_open(heapId, ExclusiveLock);

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.73 2000/11/10 00:33:09 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.74 2000/11/16 22:30:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -153,13 +153,14 @@ CatalogIndexInsert(Relation *idescs,
IndexInfo *indexInfo; IndexInfo *indexInfo;
InsertIndexResult indexRes; InsertIndexResult indexRes;
index_tup = SearchSysCacheTuple(INDEXRELID, index_tup = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(idescs[i]->rd_id), ObjectIdGetDatum(idescs[i]->rd_id),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(index_tup)) if (!HeapTupleIsValid(index_tup))
elog(ERROR, "CatalogIndexInsert: index %u not found", elog(ERROR, "CatalogIndexInsert: index %u not found",
idescs[i]->rd_id); idescs[i]->rd_id);
indexInfo = BuildIndexInfo(index_tup); indexInfo = BuildIndexInfo(index_tup);
ReleaseSysCache(index_tup);
FormIndexDatum(indexInfo, FormIndexDatum(indexInfo,
heapTuple, heapTuple,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.35 2000/07/17 03:04:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.36 2000/11/16 22:30:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -82,15 +82,10 @@ AggregateCreate(char *aggName,
* specified as 'ANY' for a data-independent transition function, * specified as 'ANY' for a data-independent transition function,
* such as COUNT(*). * such as COUNT(*).
*/ */
tup = SearchSysCacheTuple(TYPENAME, basetype = GetSysCacheOid(TYPENAME,
PointerGetDatum(aggbasetypeName), PointerGetDatum(aggbasetypeName),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tup)) if (!OidIsValid(basetype))
{
basetype = tup->t_data->t_oid;
Assert(OidIsValid(basetype));
}
else
{ {
if (strcasecmp(aggbasetypeName, "ANY") != 0) if (strcasecmp(aggbasetypeName, "ANY") != 0)
elog(ERROR, "AggregateCreate: Type '%s' undefined", elog(ERROR, "AggregateCreate: Type '%s' undefined",
@ -99,24 +94,21 @@ AggregateCreate(char *aggName,
} }
/* make sure there is no existing agg of same name and base type */ /* make sure there is no existing agg of same name and base type */
tup = SearchSysCacheTuple(AGGNAME, if (SearchSysCacheExists(AGGNAME,
PointerGetDatum(aggName), PointerGetDatum(aggName),
ObjectIdGetDatum(basetype), ObjectIdGetDatum(basetype),
0, 0); 0, 0))
if (HeapTupleIsValid(tup))
elog(ERROR, elog(ERROR,
"AggregateCreate: aggregate '%s' with base type '%s' already exists", "AggregateCreate: aggregate '%s' with base type '%s' already exists",
aggName, aggbasetypeName); aggName, aggbasetypeName);
/* handle transtype */ /* handle transtype */
tup = SearchSysCacheTuple(TYPENAME, transtype = GetSysCacheOid(TYPENAME,
PointerGetDatum(aggtranstypeName), PointerGetDatum(aggtranstypeName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!OidIsValid(transtype))
elog(ERROR, "AggregateCreate: Type '%s' undefined", elog(ERROR, "AggregateCreate: Type '%s' undefined",
aggtranstypeName); aggtranstypeName);
transtype = tup->t_data->t_oid;
Assert(OidIsValid(transtype));
/* handle transfn */ /* handle transfn */
fnArgs[0] = transtype; fnArgs[0] = transtype;
@ -129,48 +121,50 @@ AggregateCreate(char *aggName,
{ {
nargs = 1; nargs = 1;
} }
tup = SearchSysCacheTuple(PROCNAME, tup = SearchSysCache(PROCNAME,
PointerGetDatum(aggtransfnName), PointerGetDatum(aggtransfnName),
Int32GetDatum(nargs), Int32GetDatum(nargs),
PointerGetDatum(fnArgs), PointerGetDatum(fnArgs),
0); 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
func_error("AggregateCreate", aggtransfnName, nargs, fnArgs, NULL); func_error("AggregateCreate", aggtransfnName, nargs, fnArgs, NULL);
transfn = tup->t_data->t_oid; transfn = tup->t_data->t_oid;
Assert(OidIsValid(transfn));
proc = (Form_pg_proc) GETSTRUCT(tup); proc = (Form_pg_proc) GETSTRUCT(tup);
if (proc->prorettype != transtype) if (proc->prorettype != transtype)
elog(ERROR, "AggregateCreate: return type of '%s' is not '%s'", elog(ERROR, "AggregateCreate: return type of '%s' is not '%s'",
aggtransfnName, aggtranstypeName); aggtransfnName, aggtranstypeName);
Assert(OidIsValid(transfn));
/* /*
* If the transfn is strict and the initval is NULL, make sure * If the transfn is strict and the initval is NULL, make sure
* input type and transtype are the same (or at least binary- * input type and transtype are the same (or at least binary-
* compatible), so that it's OK to use the first input value * compatible), so that it's OK to use the first input value
* as the initial transValue. * as the initial transValue.
*/ */
if (((Form_pg_proc) GETSTRUCT(tup))->proisstrict && agginitval == NULL) if (proc->proisstrict && agginitval == NULL)
{ {
if (basetype != transtype && if (basetype != transtype &&
! IS_BINARY_COMPATIBLE(basetype, transtype)) ! IS_BINARY_COMPATIBLE(basetype, transtype))
elog(ERROR, "AggregateCreate: must not omit initval when transfn is strict and transtype is not compatible with input type"); elog(ERROR, "AggregateCreate: must not omit initval when transfn is strict and transtype is not compatible with input type");
} }
ReleaseSysCache(tup);
/* handle finalfn, if supplied */ /* handle finalfn, if supplied */
if (aggfinalfnName) if (aggfinalfnName)
{ {
fnArgs[0] = transtype; fnArgs[0] = transtype;
fnArgs[1] = 0; fnArgs[1] = 0;
tup = SearchSysCacheTuple(PROCNAME, tup = SearchSysCache(PROCNAME,
PointerGetDatum(aggfinalfnName), PointerGetDatum(aggfinalfnName),
Int32GetDatum(1), Int32GetDatum(1),
PointerGetDatum(fnArgs), PointerGetDatum(fnArgs),
0); 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
func_error("AggregateCreate", aggfinalfnName, 1, fnArgs, NULL); func_error("AggregateCreate", aggfinalfnName, 1, fnArgs, NULL);
finalfn = tup->t_data->t_oid; finalfn = tup->t_data->t_oid;
Assert(OidIsValid(finalfn));
proc = (Form_pg_proc) GETSTRUCT(tup); proc = (Form_pg_proc) GETSTRUCT(tup);
finaltype = proc->prorettype; finaltype = proc->prorettype;
Assert(OidIsValid(finalfn)); ReleaseSysCache(tup);
} }
else else
{ {
@ -237,10 +231,10 @@ AggNameGetInitVal(char *aggName, Oid basetype, bool *isNull)
Assert(PointerIsValid(aggName)); Assert(PointerIsValid(aggName));
Assert(PointerIsValid(isNull)); Assert(PointerIsValid(isNull));
tup = SearchSysCacheTuple(AGGNAME, tup = SearchSysCache(AGGNAME,
PointerGetDatum(aggName), PointerGetDatum(aggName),
ObjectIdGetDatum(basetype), ObjectIdGetDatum(basetype),
0, 0); 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "AggNameGetInitVal: cache lookup failed for aggregate '%s'", elog(ERROR, "AggNameGetInitVal: cache lookup failed for aggregate '%s'",
aggName); aggName);
@ -254,20 +248,24 @@ AggNameGetInitVal(char *aggName, Oid basetype, bool *isNull)
Anum_pg_aggregate_agginitval, Anum_pg_aggregate_agginitval,
isNull); isNull);
if (*isNull) if (*isNull)
{
ReleaseSysCache(tup);
return (Datum) 0; return (Datum) 0;
}
strInitVal = DatumGetCString(DirectFunctionCall1(textout, textInitVal)); strInitVal = DatumGetCString(DirectFunctionCall1(textout, textInitVal));
tup = SearchSysCacheTuple(TYPEOID, ReleaseSysCache(tup);
ObjectIdGetDatum(transtype),
0, 0, 0); tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(transtype),
0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
pfree(strInitVal);
elog(ERROR, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type %u", transtype); elog(ERROR, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type %u", transtype);
}
typinput = ((Form_pg_type) GETSTRUCT(tup))->typinput; typinput = ((Form_pg_type) GETSTRUCT(tup))->typinput;
typelem = ((Form_pg_type) GETSTRUCT(tup))->typelem; typelem = ((Form_pg_type) GETSTRUCT(tup))->typelem;
ReleaseSysCache(tup);
initVal = OidFunctionCall3(typinput, initVal = OidFunctionCall3(typinput,
CStringGetDatum(strInitVal), CStringGetDatum(strInitVal),

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.52 2000/10/22 23:32:38 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.53 2000/11/16 22:30:17 tgl Exp $
* *
* NOTES * NOTES
* these routines moved here from commands/define.c and somewhat cleaned up. * these routines moved here from commands/define.c and somewhat cleaned up.
@ -575,12 +575,11 @@ OperatorDef(char *operatorName,
typeId[1] = rightTypeId; typeId[1] = rightTypeId;
nargs = 2; nargs = 2;
} }
tup = SearchSysCacheTuple(PROCNAME, tup = SearchSysCache(PROCNAME,
PointerGetDatum(procedureName), PointerGetDatum(procedureName),
Int32GetDatum(nargs), Int32GetDatum(nargs),
PointerGetDatum(typeId), PointerGetDatum(typeId),
0); 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
func_error("OperatorDef", procedureName, nargs, typeId, NULL); func_error("OperatorDef", procedureName, nargs, typeId, NULL);
@ -588,27 +587,32 @@ OperatorDef(char *operatorName,
values[Anum_pg_operator_oprresult - 1] = ObjectIdGetDatum(((Form_pg_proc) values[Anum_pg_operator_oprresult - 1] = ObjectIdGetDatum(((Form_pg_proc)
GETSTRUCT(tup))->prorettype); GETSTRUCT(tup))->prorettype);
ReleaseSysCache(tup);
/* ---------------- /* ----------------
* find restriction * find restriction
* ---------------- * ----------------
*/ */
if (restrictionName) if (restrictionName)
{ /* optional */ { /* optional */
Oid restOid;
MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
typeId[0] = OIDOID; /* operator OID */ typeId[0] = OIDOID; /* operator OID */
typeId[1] = OIDOID; /* relation OID */ typeId[1] = OIDOID; /* relation OID */
typeId[2] = INT2OID; /* attribute number */ typeId[2] = INT2OID; /* attribute number */
typeId[3] = 0; /* value - can be any type */ typeId[3] = 0; /* value - can be any type */
typeId[4] = INT4OID; /* flags - left or right selectivity */ typeId[4] = INT4OID; /* flags - left or right selectivity */
tup = SearchSysCacheTuple(PROCNAME,
PointerGetDatum(restrictionName), restOid = GetSysCacheOid(PROCNAME,
Int32GetDatum(5), PointerGetDatum(restrictionName),
PointerGetDatum(typeId), Int32GetDatum(5),
0); PointerGetDatum(typeId),
if (!HeapTupleIsValid(tup)) 0);
if (!OidIsValid(restOid))
func_error("OperatorDef", restrictionName, 5, typeId, NULL); func_error("OperatorDef", restrictionName, 5, typeId, NULL);
values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(tup->t_data->t_oid); values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(restOid);
} }
else else
values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid); values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid);
@ -619,6 +623,8 @@ OperatorDef(char *operatorName,
*/ */
if (joinName) if (joinName)
{ /* optional */ { /* optional */
Oid joinOid;
MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
typeId[0] = OIDOID; /* operator OID */ typeId[0] = OIDOID; /* operator OID */
typeId[1] = OIDOID; /* relation OID 1 */ typeId[1] = OIDOID; /* relation OID 1 */
@ -626,15 +632,15 @@ OperatorDef(char *operatorName,
typeId[3] = OIDOID; /* relation OID 2 */ typeId[3] = OIDOID; /* relation OID 2 */
typeId[4] = INT2OID; /* attribute number 2 */ typeId[4] = INT2OID; /* attribute number 2 */
tup = SearchSysCacheTuple(PROCNAME, joinOid = GetSysCacheOid(PROCNAME,
PointerGetDatum(joinName), PointerGetDatum(joinName),
Int32GetDatum(5), Int32GetDatum(5),
PointerGetDatum(typeId), PointerGetDatum(typeId),
0); 0);
if (!HeapTupleIsValid(tup)) if (!OidIsValid(joinOid))
func_error("OperatorDef", joinName, 5, typeId, NULL); func_error("OperatorDef", joinName, 5, typeId, NULL);
values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(tup->t_data->t_oid); values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(joinOid);
} }
else else
values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid); values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.49 2000/10/07 00:58:15 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.50 2000/11/16 22:30:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -71,7 +71,7 @@ ProcedureCreate(char *procedureName,
Oid toid; Oid toid;
NameData procname; NameData procname;
TupleDesc tupDesc; TupleDesc tupDesc;
Oid retval; Oid retval;
/* ---------------- /* ----------------
* sanity checks * sanity checks
@ -80,15 +80,12 @@ ProcedureCreate(char *procedureName,
Assert(PointerIsValid(prosrc)); Assert(PointerIsValid(prosrc));
Assert(PointerIsValid(probin)); Assert(PointerIsValid(probin));
tup = SearchSysCacheTuple(LANGNAME, languageObjectId = GetSysCacheOid(LANGNAME,
PointerGetDatum(languageName), PointerGetDatum(languageName),
0, 0, 0); 0, 0, 0);
if (!OidIsValid(languageObjectId))
if (!HeapTupleIsValid(tup))
elog(ERROR, "ProcedureCreate: no such language '%s'", languageName); elog(ERROR, "ProcedureCreate: no such language '%s'", languageName);
languageObjectId = tup->t_data->t_oid;
parameterCount = 0; parameterCount = 0;
MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid));
foreach(x, argList) foreach(x, argList)
@ -124,13 +121,12 @@ ProcedureCreate(char *procedureName,
typev[parameterCount++] = toid; typev[parameterCount++] = toid;
} }
tup = SearchSysCacheTuple(PROCNAME, /* Check for duplicate definition */
PointerGetDatum(procedureName), if (SearchSysCacheExists(PROCNAME,
UInt16GetDatum(parameterCount), PointerGetDatum(procedureName),
PointerGetDatum(typev), UInt16GetDatum(parameterCount),
0); PointerGetDatum(typev),
0))
if (HeapTupleIsValid(tup))
elog(ERROR, "ProcedureCreate: procedure %s already exists with same arguments", elog(ERROR, "ProcedureCreate: procedure %s already exists with same arguments",
procedureName); procedureName);
@ -161,12 +157,12 @@ ProcedureCreate(char *procedureName,
prosrctext = DatumGetTextP(DirectFunctionCall1(textin, prosrctext = DatumGetTextP(DirectFunctionCall1(textin,
CStringGetDatum(prosrc))); CStringGetDatum(prosrc)));
tup = SearchSysCacheTuple(PROSRC, retval = GetSysCacheOid(PROSRC,
PointerGetDatum(prosrctext), PointerGetDatum(prosrctext),
0, 0, 0); 0, 0, 0);
pfree(prosrctext); pfree(prosrctext);
if (HeapTupleIsValid(tup)) if (OidIsValid(retval))
return tup->t_data->t_oid; return retval;
#else #else
elog(ERROR, "lookup for procedure by source needs fix (Jan)"); elog(ERROR, "lookup for procedure by source needs fix (Jan)");
#endif /* SETS_FIXED */ #endif /* SETS_FIXED */
@ -351,7 +347,7 @@ checkretval(Oid rettype, List *queryTreeList)
List *tlist; List *tlist;
List *tlistitem; List *tlistitem;
int tlistlen; int tlistlen;
Type typ; Oid typerelid;
Resdom *resnode; Resdom *resnode;
Relation reln; Relation reln;
Oid relid; Oid relid;
@ -375,11 +371,9 @@ checkretval(Oid rettype, List *queryTreeList)
} }
/* by here, the function is declared to return some type */ /* by here, the function is declared to return some type */
if ((typ = typeidType(rettype)) == NULL)
elog(ERROR, "can't find return type %u for function", rettype);
if (cmd != CMD_SELECT) if (cmd != CMD_SELECT)
elog(ERROR, "function declared to return %s, but final query is not a SELECT", typeTypeName(typ)); elog(ERROR, "function declared to return %s, but final query is not a SELECT",
typeidTypeName(rettype));
/* /*
* Count the non-junk entries in the result targetlist. * Count the non-junk entries in the result targetlist.
@ -390,14 +384,17 @@ checkretval(Oid rettype, List *queryTreeList)
* For base-type returns, the target list should have exactly one entry, * For base-type returns, the target list should have exactly one entry,
* and its type should agree with what the user declared. * and its type should agree with what the user declared.
*/ */
if (typeTypeRelid(typ) == InvalidOid) typerelid = typeidTypeRelid(rettype);
if (typerelid == InvalidOid)
{ {
if (tlistlen != 1) if (tlistlen != 1)
elog(ERROR, "function declared to return %s returns multiple columns in final SELECT", typeTypeName(typ)); elog(ERROR, "function declared to return %s returns multiple columns in final SELECT",
typeidTypeName(rettype));
resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom; resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom;
if (resnode->restype != rettype) if (resnode->restype != rettype)
elog(ERROR, "return type mismatch in function: declared to return %s, returns %s", typeTypeName(typ), typeidTypeName(resnode->restype)); elog(ERROR, "return type mismatch in function: declared to return %s, returns %s",
typeidTypeName(rettype), typeidTypeName(resnode->restype));
return; return;
} }
@ -422,12 +419,13 @@ checkretval(Oid rettype, List *queryTreeList)
* declared return type, and be sure that attributes 1 .. n in the target * declared return type, and be sure that attributes 1 .. n in the target
* list match the declared types. * list match the declared types.
*/ */
reln = heap_open(typeTypeRelid(typ), AccessShareLock); reln = heap_open(typerelid, AccessShareLock);
relid = reln->rd_id; relid = reln->rd_id;
relnatts = reln->rd_rel->relnatts; relnatts = reln->rd_rel->relnatts;
if (tlistlen != relnatts) if (tlistlen != relnatts)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)", typeTypeName(typ), relnatts); elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
typeidTypeName(rettype), relnatts);
/* expect attributes 1 .. n in order */ /* expect attributes 1 .. n in order */
i = 0; i = 0;
@ -441,7 +439,7 @@ checkretval(Oid rettype, List *queryTreeList)
tletype = exprType(tle->expr); tletype = exprType(tle->expr);
if (tletype != reln->rd_att->attrs[i]->atttypid) if (tletype != reln->rd_att->attrs[i]->atttypid)
elog(ERROR, "function declared to return %s returns %s instead of %s at column %d", elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
typeTypeName(typ), typeidTypeName(rettype),
typeidTypeName(tletype), typeidTypeName(tletype),
typeidTypeName(reln->rd_att->attrs[i]->atttypid), typeidTypeName(reln->rd_att->attrs[i]->atttypid),
i+1); i+1);
@ -450,7 +448,8 @@ checkretval(Oid rettype, List *queryTreeList)
/* this shouldn't happen, but let's just check... */ /* this shouldn't happen, but let's just check... */
if (i != relnatts) if (i != relnatts)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)", typeTypeName(typ), relnatts); elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
typeidTypeName(rettype), relnatts);
heap_close(reln, AccessShareLock); heap_close(reln, AccessShareLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.55 2000/08/21 17:22:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.56 2000/11/16 22:30:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -388,6 +388,8 @@ TypeCreate(char *typeName,
for (j = 0; j < 4; ++j) for (j = 0; j < 4; ++j)
{ {
Oid procOid;
procname = procs[j]; procname = procs[j];
/* /*
@ -396,13 +398,13 @@ TypeCreate(char *typeName,
*/ */
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
tup = SearchSysCacheTuple(PROCNAME, procOid = GetSysCacheOid(PROCNAME,
PointerGetDatum(procname), PointerGetDatum(procname),
Int32GetDatum(1), Int32GetDatum(1),
PointerGetDatum(argList), PointerGetDatum(argList),
0); 0);
if (!HeapTupleIsValid(tup)) if (!OidIsValid(procOid))
{ {
/* /*
@ -428,17 +430,17 @@ TypeCreate(char *typeName,
argList[1] = OIDOID; argList[1] = OIDOID;
argList[2] = INT4OID; argList[2] = INT4OID;
} }
tup = SearchSysCacheTuple(PROCNAME, procOid = GetSysCacheOid(PROCNAME,
PointerGetDatum(procname), PointerGetDatum(procname),
Int32GetDatum(nargs), Int32GetDatum(nargs),
PointerGetDatum(argList), PointerGetDatum(argList),
0); 0);
} }
if (!HeapTupleIsValid(tup)) if (!OidIsValid(procOid))
func_error("TypeCreate", procname, 1, argList, NULL); func_error("TypeCreate", procname, 1, argList, NULL);
} }
values[i++] = ObjectIdGetDatum(tup->t_data->t_oid); /* 11 - 14 */ values[i++] = ObjectIdGetDatum(procOid); /* 11 - 14 */
} }
/* ---------------- /* ----------------
@ -536,41 +538,31 @@ TypeRename(const char *oldTypeName, const char *newTypeName)
{ {
Relation pg_type_desc; Relation pg_type_desc;
Relation idescs[Num_pg_type_indices]; Relation idescs[Num_pg_type_indices];
HeapTuple oldtup, HeapTuple tuple;
newtup;
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock); pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
oldtup = SearchSysCacheTupleCopy(TYPENAME, tuple = SearchSysCacheCopy(TYPENAME,
PointerGetDatum(oldTypeName), PointerGetDatum(oldTypeName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "TypeRename: type \"%s\" not defined", oldTypeName);
if (!HeapTupleIsValid(oldtup)) if (SearchSysCacheExists(TYPENAME,
{ PointerGetDatum(newTypeName),
heap_close(pg_type_desc, RowExclusiveLock); 0, 0, 0))
elog(ERROR, "TypeRename: type %s not defined", oldTypeName); elog(ERROR, "TypeRename: type \"%s\" already defined", newTypeName);
}
newtup = SearchSysCacheTuple(TYPENAME, namestrcpy(&(((Form_pg_type) GETSTRUCT(tuple))->typname), newTypeName);
PointerGetDatum(newTypeName),
0, 0, 0);
if (HeapTupleIsValid(newtup))
{
heap_freetuple(oldtup);
heap_close(pg_type_desc, RowExclusiveLock);
elog(ERROR, "TypeRename: type %s already defined", newTypeName);
}
namestrcpy(&(((Form_pg_type) GETSTRUCT(oldtup))->typname), newTypeName); heap_update(pg_type_desc, &tuple->t_self, tuple, NULL);
heap_update(pg_type_desc, &oldtup->t_self, oldtup, NULL);
/* update the system catalog indices */ /* update the system catalog indices */
CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs); CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, oldtup); CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tuple);
CatalogCloseIndices(Num_pg_type_indices, idescs); CatalogCloseIndices(Num_pg_type_indices, idescs);
heap_freetuple(oldtup); heap_freetuple(tuple);
heap_close(pg_type_desc, RowExclusiveLock); heap_close(pg_type_desc, RowExclusiveLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.8 2000/10/16 17:08:05 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.9 2000/11/16 22:30:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
@ -58,8 +58,7 @@ static void del_stats(Oid relid, int attcnt, int *attnums);
void void
analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL) analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
{ {
HeapTuple tuple, HeapTuple tuple;
typetuple;
Relation onerel; Relation onerel;
int32 i; int32 i;
int attr_cnt, int attr_cnt,
@ -81,20 +80,26 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
* Race condition -- if the pg_class tuple has gone away since the * Race condition -- if the pg_class tuple has gone away since the
* last time we saw it, we don't need to vacuum it. * last time we saw it, we don't need to vacuum it.
*/ */
tuple = SearchSysCacheTuple(RELOID, tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0);
/* if (!HeapTupleIsValid(tuple))
* We can VACUUM ANALYZE any table except pg_statistic.
* see update_relstats
*/
if (!HeapTupleIsValid(tuple) ||
strcmp(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname),
StatisticRelationName) == 0)
{ {
CommitTransactionCommand(); CommitTransactionCommand();
return; return;
} }
/*
* We can VACUUM ANALYZE any table except pg_statistic.
* see update_relstats
*/
if (strcmp(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname),
StatisticRelationName) == 0)
{
ReleaseSysCache(tuple);
CommitTransactionCommand();
return;
}
ReleaseSysCache(tuple);
onerel = heap_open(relid, AccessShareLock); onerel = heap_open(relid, AccessShareLock);
@ -168,6 +173,7 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
{ {
pgopform = (Form_pg_operator) GETSTRUCT(func_operator); pgopform = (Form_pg_operator) GETSTRUCT(func_operator);
fmgr_info(pgopform->oprcode, &(stats->f_cmpeq)); fmgr_info(pgopform->oprcode, &(stats->f_cmpeq));
ReleaseSysCache(func_operator);
} }
else else
stats->f_cmpeq.fn_addr = NULL; stats->f_cmpeq.fn_addr = NULL;
@ -178,6 +184,7 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
pgopform = (Form_pg_operator) GETSTRUCT(func_operator); pgopform = (Form_pg_operator) GETSTRUCT(func_operator);
fmgr_info(pgopform->oprcode, &(stats->f_cmplt)); fmgr_info(pgopform->oprcode, &(stats->f_cmplt));
stats->op_cmplt = oprid(func_operator); stats->op_cmplt = oprid(func_operator);
ReleaseSysCache(func_operator);
} }
else else
{ {
@ -190,17 +197,19 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
{ {
pgopform = (Form_pg_operator) GETSTRUCT(func_operator); pgopform = (Form_pg_operator) GETSTRUCT(func_operator);
fmgr_info(pgopform->oprcode, &(stats->f_cmpgt)); fmgr_info(pgopform->oprcode, &(stats->f_cmpgt));
ReleaseSysCache(func_operator);
} }
else else
stats->f_cmpgt.fn_addr = NULL; stats->f_cmpgt.fn_addr = NULL;
typetuple = SearchSysCacheTuple(TYPEOID, tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(stats->attr->atttypid), ObjectIdGetDatum(stats->attr->atttypid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(typetuple)) if (HeapTupleIsValid(tuple))
{ {
stats->outfunc = ((Form_pg_type) GETSTRUCT(typetuple))->typoutput; stats->outfunc = ((Form_pg_type) GETSTRUCT(tuple))->typoutput;
stats->typelem = ((Form_pg_type) GETSTRUCT(typetuple))->typelem; stats->typelem = ((Form_pg_type) GETSTRUCT(tuple))->typelem;
ReleaseSysCache(tuple);
} }
else else
{ {

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.70 2000/10/03 03:11:13 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.71 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -193,9 +193,7 @@ void
Async_Listen(char *relname, int pid) Async_Listen(char *relname, int pid)
{ {
Relation lRel; Relation lRel;
TupleDesc tdesc; HeapTuple tuple;
HeapTuple tuple,
newtup;
Datum values[Natts_pg_listener]; Datum values[Natts_pg_listener];
char nulls[Natts_pg_listener]; char nulls[Natts_pg_listener];
int i; int i;
@ -205,13 +203,12 @@ Async_Listen(char *relname, int pid)
elog(DEBUG, "Async_Listen: %s", relname); elog(DEBUG, "Async_Listen: %s", relname);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock); lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
/* Detect whether we are already listening on this relname */ /* Detect whether we are already listening on this relname */
tuple = SearchSysCacheTuple(LISTENREL, Int32GetDatum(pid), if (SearchSysCacheExists(LISTENREL,
PointerGetDatum(relname), Int32GetDatum(pid),
0, 0); PointerGetDatum(relname),
if (tuple != NULL) 0, 0))
{ {
/* No need to scan the rest of the table */ /* No need to scan the rest of the table */
heap_close(lRel, AccessExclusiveLock); heap_close(lRel, AccessExclusiveLock);
@ -235,18 +232,18 @@ Async_Listen(char *relname, int pid)
values[i++] = (Datum) 0; /* no notifies pending */ values[i++] = (Datum) 0; /* no notifies pending */
tupDesc = lRel->rd_att; tupDesc = lRel->rd_att;
newtup = heap_formtuple(tupDesc, values, nulls); tuple = heap_formtuple(tupDesc, values, nulls);
heap_insert(lRel, newtup); heap_insert(lRel, tuple);
if (RelationGetForm(lRel)->relhasindex) if (RelationGetForm(lRel)->relhasindex)
{ {
Relation idescs[Num_pg_listener_indices]; Relation idescs[Num_pg_listener_indices];
CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs); CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, newtup); CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, tuple);
CatalogCloseIndices(Num_pg_listener_indices, idescs); CatalogCloseIndices(Num_pg_listener_indices, idescs);
} }
heap_freetuple(newtup); heap_freetuple(tuple);
heap_close(lRel, AccessExclusiveLock); heap_close(lRel, AccessExclusiveLock);
@ -296,11 +293,15 @@ Async_Unlisten(char *relname, int pid)
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock); lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
/* Note we assume there can be only one matching tuple. */ /* Note we assume there can be only one matching tuple. */
lTuple = SearchSysCacheTuple(LISTENREL, Int32GetDatum(pid), lTuple = SearchSysCache(LISTENREL,
PointerGetDatum(relname), Int32GetDatum(pid),
0, 0); PointerGetDatum(relname),
if (lTuple != NULL) 0, 0);
if (HeapTupleIsValid(lTuple))
{
heap_delete(lRel, &lTuple->t_self, NULL); heap_delete(lRel, &lTuple->t_self, NULL);
ReleaseSysCache(lTuple);
}
heap_close(lRel, AccessExclusiveLock); heap_close(lRel, AccessExclusiveLock);
/* /*

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.59 2000/11/08 22:09:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.60 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -84,15 +84,16 @@ cluster(char *oldrelname, char *oldindexname)
/* /*
* Check that index is in fact an index on the given relation * Check that index is in fact an index on the given relation
*/ */
tuple = SearchSysCacheTuple(INDEXRELID, tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(OIDOldIndex), ObjectIdGetDatum(OIDOldIndex),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "CLUSTER: no pg_index entry for index %u", elog(ERROR, "CLUSTER: no pg_index entry for index %u",
OIDOldIndex); OIDOldIndex);
if (((Form_pg_index) GETSTRUCT(tuple))->indrelid != OIDOldHeap) if (((Form_pg_index) GETSTRUCT(tuple))->indrelid != OIDOldHeap)
elog(ERROR, "CLUSTER: \"%s\" is not an index for table \"%s\"", elog(ERROR, "CLUSTER: \"%s\" is not an index for table \"%s\"",
saveoldindexname, saveoldrelname); saveoldindexname, saveoldrelname);
ReleaseSysCache(tuple);
/* Drop relcache refcnts, but do NOT give up the locks */ /* Drop relcache refcnts, but do NOT give up the locks */
heap_close(OldHeap, NoLock); heap_close(OldHeap, NoLock);
@ -184,17 +185,17 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
* To do this I get the info from pg_index, and add a new index with * To do this I get the info from pg_index, and add a new index with
* a temporary name. * a temporary name.
*/ */
Old_pg_index_Tuple = SearchSysCacheTupleCopy(INDEXRELID, Old_pg_index_Tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(OIDOldIndex), ObjectIdGetDatum(OIDOldIndex),
0, 0, 0); 0, 0, 0);
Assert(Old_pg_index_Tuple); Assert(Old_pg_index_Tuple);
Old_pg_index_Form = (Form_pg_index) GETSTRUCT(Old_pg_index_Tuple); Old_pg_index_Form = (Form_pg_index) GETSTRUCT(Old_pg_index_Tuple);
indexInfo = BuildIndexInfo(Old_pg_index_Tuple); indexInfo = BuildIndexInfo(Old_pg_index_Tuple);
Old_pg_index_relation_Tuple = SearchSysCacheTupleCopy(RELOID, Old_pg_index_relation_Tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(OIDOldIndex), ObjectIdGetDatum(OIDOldIndex),
0, 0, 0); 0, 0, 0);
Assert(Old_pg_index_relation_Tuple); Assert(Old_pg_index_relation_Tuple);
Old_pg_index_relation_Form = (Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple); Old_pg_index_relation_Form = (Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple);
@ -209,6 +210,9 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
setRelhasindex(OIDNewHeap, true); setRelhasindex(OIDNewHeap, true);
ReleaseSysCache(Old_pg_index_Tuple);
ReleaseSysCache(Old_pg_index_relation_Tuple);
index_close(OldIndex); index_close(OldIndex);
heap_close(NewHeap, NoLock); heap_close(NewHeap, NoLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.111 2000/11/14 01:57:30 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.112 2000/11/16 22:30:19 tgl Exp $
* *
* NOTES * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
@ -274,13 +274,13 @@ AlterTableAddColumn(const char *relationName,
attrdesc; attrdesc;
Oid myrelid; Oid myrelid;
HeapTuple reltup; HeapTuple reltup;
HeapTuple newreltup;
HeapTuple attributeTuple; HeapTuple attributeTuple;
Form_pg_attribute attribute; Form_pg_attribute attribute;
FormData_pg_attribute attributeD; FormData_pg_attribute attributeD;
int i; int i;
int minattnum, int minattnum,
maxatts; maxatts;
HeapTuple tup;
Relation idescs[Num_pg_attr_indices]; Relation idescs[Num_pg_attr_indices];
Relation ridescs[Num_pg_class_indices]; Relation ridescs[Num_pg_class_indices];
bool hasindex; bool hasindex;
@ -359,9 +359,9 @@ AlterTableAddColumn(const char *relationName,
rel = heap_openr(RelationRelationName, RowExclusiveLock); rel = heap_openr(RelationRelationName, RowExclusiveLock);
reltup = SearchSysCacheTupleCopy(RELNAME, reltup = SearchSysCache(RELNAME,
PointerGetDatum(relationName), PointerGetDatum(relationName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found", elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
@ -371,10 +371,8 @@ AlterTableAddColumn(const char *relationName,
* XXX is the following check sufficient? * XXX is the following check sufficient?
*/ */
if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION) if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
{
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
relationName); relationName);
}
minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts; minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
maxatts = minattnum + 1; maxatts = minattnum + 1;
@ -407,12 +405,10 @@ AlterTableAddColumn(const char *relationName,
char *typename; char *typename;
int attnelems; int attnelems;
tup = SearchSysCacheTuple(ATTNAME, if (SearchSysCacheExists(ATTNAME,
ObjectIdGetDatum(reltup->t_data->t_oid), ObjectIdGetDatum(reltup->t_data->t_oid),
PointerGetDatum(colDef->colname), PointerGetDatum(colDef->colname),
0, 0); 0, 0))
if (HeapTupleIsValid(tup))
elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"", elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"",
colDef->colname, relationName); colDef->colname, relationName);
@ -430,13 +426,13 @@ AlterTableAddColumn(const char *relationName,
else else
attnelems = 0; attnelems = 0;
typeTuple = SearchSysCacheTuple(TYPENAME, typeTuple = SearchSysCache(TYPENAME,
PointerGetDatum(typename), PointerGetDatum(typename),
0, 0, 0); 0, 0, 0);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
if (!HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename); elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
namestrcpy(&(attribute->attname), colDef->colname); namestrcpy(&(attribute->attname), colDef->colname);
attribute->atttypid = typeTuple->t_data->t_oid; attribute->atttypid = typeTuple->t_data->t_oid;
attribute->attlen = tform->typlen; attribute->attlen = tform->typlen;
@ -453,6 +449,8 @@ AlterTableAddColumn(const char *relationName,
attribute->atthasdef = (colDef->raw_default != NULL || attribute->atthasdef = (colDef->raw_default != NULL ||
colDef->cooked_default != NULL); colDef->cooked_default != NULL);
ReleaseSysCache(typeTuple);
heap_insert(attrdesc, attributeTuple); heap_insert(attrdesc, attributeTuple);
if (hasindex) if (hasindex)
CatalogIndexInsert(idescs, CatalogIndexInsert(idescs,
@ -466,15 +464,21 @@ AlterTableAddColumn(const char *relationName,
heap_close(attrdesc, RowExclusiveLock); heap_close(attrdesc, RowExclusiveLock);
((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts; /*
heap_update(rel, &reltup->t_self, reltup, NULL); * Update number of attributes in pg_class tuple
*/
newreltup = heap_copytuple(reltup);
((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts;
heap_update(rel, &newreltup->t_self, newreltup, NULL);
/* keep catalog indices current */ /* keep catalog indices current */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs); CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, reltup); CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, newreltup);
CatalogCloseIndices(Num_pg_class_indices, ridescs); CatalogCloseIndices(Num_pg_class_indices, ridescs);
heap_freetuple(reltup); heap_freetuple(newreltup);
ReleaseSysCache(reltup);
heap_close(rel, NoLock); heap_close(rel, NoLock);
@ -555,11 +559,10 @@ AlterTableAlterColumn(const char *relationName,
/* /*
* get the number of the attribute * get the number of the attribute
*/ */
tuple = SearchSysCacheTuple(ATTNAME, tuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(myrelid), ObjectIdGetDatum(myrelid),
PointerGetDatum(colName), PointerGetDatum(colName),
0, 0); 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
heap_close(rel, AccessExclusiveLock); heap_close(rel, AccessExclusiveLock);
@ -568,6 +571,7 @@ AlterTableAlterColumn(const char *relationName,
} }
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
ReleaseSysCache(tuple);
if (newDefault) /* SET DEFAULT */ if (newDefault) /* SET DEFAULT */
{ {
@ -595,7 +599,6 @@ AlterTableAlterColumn(const char *relationName,
Relation attr_rel; Relation attr_rel;
ScanKeyData scankeys[3]; ScanKeyData scankeys[3];
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple tuple;
attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock); attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock);
ScanKeyEntryInitialize(&scankeys[0], 0x0, ScanKeyEntryInitialize(&scankeys[0], 0x0,
@ -867,10 +870,11 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
} }
else else
{ {
htup = SearchSysCacheTuple(RELOID, htup = SearchSysCache(RELOID,
ObjectIdGetDatum(index->indexrelid), ObjectIdGetDatum(index->indexrelid),
0, 0, 0); 0, 0, 0);
RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname)); RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
ReleaseSysCache(htup);
} }
break; break;
} }
@ -941,18 +945,19 @@ AlterTableDropColumn(const char *relationName,
if (length(find_all_inheritors(myrelid)) > 1) if (length(find_all_inheritors(myrelid)) > 1)
elog(ERROR, "ALTER TABLE: cannot drop a column on table that is inherited from"); elog(ERROR, "ALTER TABLE: cannot drop a column on table that is inherited from");
/* /*
* lock the pg_class tuple for update * lock the pg_class tuple for update
*/ */
reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName), rel = heap_openr(RelationRelationName, RowExclusiveLock);
0, 0, 0); reltup = SearchSysCache(RELNAME,
PointerGetDatum(relationName),
0, 0, 0);
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found", elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName); relationName);
rel = heap_openr(RelationRelationName, RowExclusiveLock);
classtuple.t_self = reltup->t_self; classtuple.t_self = reltup->t_self;
ReleaseSysCache(reltup);
switch (heap_mark4update(rel, &classtuple, &buffer)) switch (heap_mark4update(rel, &classtuple, &buffer))
{ {
case HeapTupleSelfUpdated: case HeapTupleSelfUpdated:
@ -976,19 +981,21 @@ AlterTableDropColumn(const char *relationName,
attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock); attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock);
/* /*
* Get the target pg_attribute tuple * Get the target pg_attribute tuple and make a modifiable copy
*/ */
tup = SearchSysCacheTupleCopy(ATTNAME, tup = SearchSysCacheCopy(ATTNAME,
ObjectIdGetDatum(reltup->t_data->t_oid), ObjectIdGetDatum(reltup->t_data->t_oid),
PointerGetDatum(colName), 0, 0); PointerGetDatum(colName),
0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"", elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"",
colName, relationName); colName, relationName);
attribute = (Form_pg_attribute) GETSTRUCT(tup); attribute = (Form_pg_attribute) GETSTRUCT(tup);
if (attribute->attnum <= 0)
elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", colName);
attnum = attribute->attnum; attnum = attribute->attnum;
if (attnum <= 0)
elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped",
colName);
attoid = tup->t_data->t_oid; attoid = tup->t_data->t_oid;
/* /*
@ -1226,10 +1233,9 @@ AlterTableAddConstraint(char *relationName,
int count; int count;
List *indexoidlist, List *indexoidlist,
*indexoidscan; *indexoidscan;
Form_pg_index indexStruct = NULL;
Form_pg_attribute *rel_attrs = NULL; Form_pg_attribute *rel_attrs = NULL;
int i; int i;
int found=0; bool found = false;
if (get_temp_rel_by_username(fkconstraint->pktable_name)!=NULL && if (get_temp_rel_by_username(fkconstraint->pktable_name)!=NULL &&
get_temp_rel_by_username(relationName)==NULL) { get_temp_rel_by_username(relationName)==NULL) {
@ -1264,42 +1270,50 @@ AlterTableAddConstraint(char *relationName,
indexoidlist = RelationGetIndexList(pkrel); indexoidlist = RelationGetIndexList(pkrel);
foreach(indexoidscan, indexoidlist) foreach(indexoidscan, indexoidlist)
{ {
Oid indexoid = lfirsti(indexoidscan); Oid indexoid = lfirsti(indexoidscan);
HeapTuple indexTuple; HeapTuple indexTuple;
List *attrl; Form_pg_index indexStruct;
indexTuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(indexoid),
0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
indexoid);
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
if (indexStruct->indisunique) { indexTuple = SearchSysCache(INDEXRELID,
/* go through the fkconstraint->pk_attrs list */ ObjectIdGetDatum(indexoid),
foreach(attrl, fkconstraint->pk_attrs) { 0, 0, 0);
Ident *attr=lfirst(attrl); if (!HeapTupleIsValid(indexTuple))
found=0; elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++) indexoid);
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
if (indexStruct->indisunique)
{
List *attrl;
/* go through the fkconstraint->pk_attrs list */
foreach(attrl, fkconstraint->pk_attrs)
{
Ident *attr=lfirst(attrl);
found = false;
for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
{
int pkattno = indexStruct->indkey[i];
if (pkattno>0)
{ {
int pkattno = indexStruct->indkey[i]; char *name = NameStr(rel_attrs[pkattno-1]->attname);
if (pkattno>0) { if (strcmp(name, attr->name)==0)
char *name = NameStr(rel_attrs[pkattno-1]->attname); {
if (strcmp(name, attr->name)==0) { found = true;
found=1; break;
break;
}
} }
} }
if (!found)
break;
} }
if (!found)
break;
} }
if (found)
break;
indexStruct = NULL;
} }
ReleaseSysCache(indexTuple);
if (found)
break;
}
if (!found) if (!found)
elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found", elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
fkconstraint->pktable_name); fkconstraint->pktable_name);
@ -1309,17 +1323,18 @@ AlterTableAddConstraint(char *relationName,
rel_attrs = rel->rd_att->attrs; rel_attrs = rel->rd_att->attrs;
if (fkconstraint->fk_attrs!=NIL) { if (fkconstraint->fk_attrs!=NIL) {
int found=0;
List *fkattrs; List *fkattrs;
Ident *fkattr; Ident *fkattr;
found = false;
foreach(fkattrs, fkconstraint->fk_attrs) { foreach(fkattrs, fkconstraint->fk_attrs) {
int count=0; int count;
found=0; found = false;
fkattr=lfirst(fkattrs); fkattr=lfirst(fkattrs);
for (; count < rel->rd_att->natts; count++) { for (count = 0; count < rel->rd_att->natts; count++) {
char *name = NameStr(rel->rd_att->attrs[count]->attname); char *name = NameStr(rel->rd_att->attrs[count]->attname);
if (strcmp(name, fkattr->name)==0) { if (strcmp(name, fkattr->name)==0) {
found=1; found = true;
break; break;
} }
} }
@ -1441,20 +1456,22 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
/* /*
* look up the new owner in pg_shadow and get the sysid * look up the new owner in pg_shadow and get the sysid
*/ */
tuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(newOwnerName), tuple = SearchSysCache(SHADOWNAME,
0, 0, 0); PointerGetDatum(newOwnerName),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: user \"%s\" not found", newOwnerName); elog(ERROR, "ALTER TABLE: user \"%s\" not found", newOwnerName);
newOwnerSysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid; newOwnerSysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid;
ReleaseSysCache(tuple);
/* /*
* find the table's entry in pg_class and lock it for writing * find the table's entry in pg_class and make a modifiable copy
*/ */
class_rel = heap_openr(RelationRelationName, RowExclusiveLock); class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTupleCopy(RELNAME, PointerGetDatum(relationName), tuple = SearchSysCacheCopy(RELNAME,
0, 0, 0); PointerGetDatum(relationName),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found", elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName); relationName);
@ -1525,13 +1542,15 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
*/ */
class_rel = heap_openr(RelationRelationName, RowExclusiveLock); class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName), reltup = SearchSysCache(RELNAME,
0, 0, 0); PointerGetDatum(relationName),
0, 0, 0);
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found", elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName); relationName);
classtuple.t_self = reltup->t_self; classtuple.t_self = reltup->t_self;
ReleaseSysCache(reltup);
switch (heap_mark4update(class_rel, &classtuple, &buffer)) switch (heap_mark4update(class_rel, &classtuple, &buffer))
{ {
case HeapTupleSelfUpdated: case HeapTupleSelfUpdated:

View File

@ -276,7 +276,6 @@ DeleteComments(Oid oid)
static void static void
CommentRelation(int reltype, char *relname, char *comment) CommentRelation(int reltype, char *relname, char *comment)
{ {
HeapTuple reltuple; HeapTuple reltuple;
Oid oid; Oid oid;
char relkind; char relkind;
@ -288,17 +287,20 @@ CommentRelation(int reltype, char *relname, char *comment)
/*** Now, attempt to find the oid in the cached version of pg_class ***/ /*** Now, attempt to find the oid in the cached version of pg_class ***/
reltuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname), reltuple = SearchSysCache(RELNAME,
0, 0, 0); PointerGetDatum(relname),
0, 0, 0);
if (!HeapTupleIsValid(reltuple)) if (!HeapTupleIsValid(reltuple))
elog(ERROR, "relation '%s' does not exist", relname); elog(ERROR, "relation '%s' does not exist", relname);
oid = reltuple->t_data->t_oid; oid = reltuple->t_data->t_oid;
/*** Next, verify that the relation type matches the intent ***/
relkind = ((Form_pg_class) GETSTRUCT(reltuple))->relkind; relkind = ((Form_pg_class) GETSTRUCT(reltuple))->relkind;
ReleaseSysCache(reltuple);
/*** Next, verify that the relation type matches the intent ***/
switch (reltype) switch (reltype)
{ {
case (INDEX): case (INDEX):
@ -322,7 +324,6 @@ CommentRelation(int reltype, char *relname, char *comment)
/*** Create the comments using the tuple's oid ***/ /*** Create the comments using the tuple's oid ***/
CreateComments(oid, comment); CreateComments(oid, comment);
} }
/*------------------------------------------------------------------ /*------------------------------------------------------------------
@ -340,9 +341,7 @@ CommentRelation(int reltype, char *relname, char *comment)
static void static void
CommentAttribute(char *relname, char *attrname, char *comment) CommentAttribute(char *relname, char *attrname, char *comment)
{ {
Relation relation; Relation relation;
HeapTuple attrtuple;
Oid oid; Oid oid;
/*** First, check object security ***/ /*** First, check object security ***/
@ -350,15 +349,19 @@ CommentAttribute(char *relname, char *attrname, char *comment)
if (!pg_ownercheck(GetUserId(), relname, RELNAME)) if (!pg_ownercheck(GetUserId(), relname, RELNAME))
elog(ERROR, "you are not permitted to comment on class '%s\'", relname); elog(ERROR, "you are not permitted to comment on class '%s\'", relname);
/*** Now, fetch the attribute oid from the system cache ***/ /* Open the containing relation to ensure it won't go away meanwhile */
relation = heap_openr(relname, AccessShareLock); relation = heap_openr(relname, AccessShareLock);
attrtuple = SearchSysCacheTuple(ATTNAME, ObjectIdGetDatum(relation->rd_id),
PointerGetDatum(attrname), 0, 0); /*** Now, fetch the attribute oid from the system cache ***/
if (!HeapTupleIsValid(attrtuple))
oid = GetSysCacheOid(ATTNAME,
ObjectIdGetDatum(relation->rd_id),
PointerGetDatum(attrname),
0, 0);
if (!OidIsValid(oid))
elog(ERROR, "'%s' is not an attribute of class '%s'", elog(ERROR, "'%s' is not an attribute of class '%s'",
attrname, relname); attrname, relname);
oid = attrtuple->t_data->t_oid;
/*** Call CreateComments() to create/drop the comments ***/ /*** Call CreateComments() to create/drop the comments ***/
@ -412,11 +415,13 @@ CommentDatabase(char *database, char *comment)
/*** Now, fetch user information ***/ /*** Now, fetch user information ***/
userid = GetUserId(); userid = GetUserId();
usertuple = SearchSysCacheTuple(SHADOWSYSID, ObjectIdGetDatum(userid), usertuple = SearchSysCache(SHADOWSYSID,
0, 0, 0); ObjectIdGetDatum(userid),
0, 0, 0);
if (!HeapTupleIsValid(usertuple)) if (!HeapTupleIsValid(usertuple))
elog(ERROR, "invalid user id %u", (unsigned) userid); elog(ERROR, "invalid user id %u", (unsigned) userid);
superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper; superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper;
ReleaseSysCache(usertuple);
/*** Allow if the userid matches the database dba or is a superuser ***/ /*** Allow if the userid matches the database dba or is a superuser ***/
@ -452,8 +457,6 @@ CommentDatabase(char *database, char *comment)
static void static void
CommentRewrite(char *rule, char *comment) CommentRewrite(char *rule, char *comment)
{ {
HeapTuple rewritetuple;
Oid oid; Oid oid;
char *relation; char *relation;
int aclcheck; int aclcheck;
@ -472,17 +475,15 @@ CommentRewrite(char *rule, char *comment)
/*** Next, find the rule's oid ***/ /*** Next, find the rule's oid ***/
rewritetuple = SearchSysCacheTuple(RULENAME, PointerGetDatum(rule), oid = GetSysCacheOid(RULENAME,
0, 0, 0); PointerGetDatum(rule),
if (!HeapTupleIsValid(rewritetuple)) 0, 0, 0);
if (!OidIsValid(oid))
elog(ERROR, "rule '%s' does not exist", rule); elog(ERROR, "rule '%s' does not exist", rule);
oid = rewritetuple->t_data->t_oid;
/*** Call CreateComments() to create/drop the comments ***/ /*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment); CreateComments(oid, comment);
} }
/*------------------------------------------------------------------ /*------------------------------------------------------------------
@ -499,8 +500,6 @@ CommentRewrite(char *rule, char *comment)
static void static void
CommentType(char *type, char *comment) CommentType(char *type, char *comment)
{ {
HeapTuple typetuple;
Oid oid; Oid oid;
/*** First, validate user ***/ /*** First, validate user ***/
@ -515,17 +514,15 @@ CommentType(char *type, char *comment)
/*** Next, find the type's oid ***/ /*** Next, find the type's oid ***/
typetuple = SearchSysCacheTuple(TYPENAME, PointerGetDatum(type), oid = GetSysCacheOid(TYPENAME,
0, 0, 0); PointerGetDatum(type),
if (!HeapTupleIsValid(typetuple)) 0, 0, 0);
if (!OidIsValid(oid))
elog(ERROR, "type '%s' does not exist", type); elog(ERROR, "type '%s' does not exist", type);
oid = typetuple->t_data->t_oid;
/*** Call CreateComments() to create/drop the comments ***/ /*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment); CreateComments(oid, comment);
} }
/*------------------------------------------------------------------ /*------------------------------------------------------------------
@ -543,7 +540,6 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
{ {
TypeName *aggtype = (TypeName *) lfirst(arguments); TypeName *aggtype = (TypeName *) lfirst(arguments);
char *aggtypename = NULL; char *aggtypename = NULL;
HeapTuple aggtuple;
Oid baseoid, Oid baseoid,
oid; oid;
bool defined; bool defined;
@ -580,9 +576,11 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
/*** Now, attempt to find the actual tuple in pg_aggregate ***/ /*** Now, attempt to find the actual tuple in pg_aggregate ***/
aggtuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggregate), oid = GetSysCacheOid(AGGNAME,
ObjectIdGetDatum(baseoid), 0, 0); PointerGetDatum(aggregate),
if (!HeapTupleIsValid(aggtuple)) ObjectIdGetDatum(baseoid),
0, 0);
if (!OidIsValid(oid))
{ {
if (aggtypename) if (aggtypename)
{ {
@ -593,12 +591,9 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
elog(ERROR, "aggregate '%s' does not exist", aggregate); elog(ERROR, "aggregate '%s' does not exist", aggregate);
} }
oid = aggtuple->t_data->t_oid;
/*** Call CreateComments() to create/drop the comments ***/ /*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment); CreateComments(oid, comment);
} }
/*------------------------------------------------------------------ /*------------------------------------------------------------------
@ -615,8 +610,6 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
static void static void
CommentProc(char *function, List *arguments, char *comment) CommentProc(char *function, List *arguments, char *comment)
{ {
HeapTuple argtuple,
functuple;
Oid oid, Oid oid,
argoids[FUNC_MAX_ARGS]; argoids[FUNC_MAX_ARGS];
int i, int i,
@ -640,12 +633,11 @@ CommentProc(char *function, List *arguments, char *comment)
argoids[i] = InvalidOid; argoids[i] = InvalidOid;
else else
{ {
argtuple = SearchSysCacheTuple(TYPENAME, argoids[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam), PointerGetDatum(typnam),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(argtuple)) if (!OidIsValid(argoids[i]))
elog(ERROR, "CommentProc: type '%s' not found", typnam); elog(ERROR, "CommentProc: type '%s' not found", typnam);
argoids[i] = argtuple->t_data->t_oid;
} }
} }
@ -659,14 +651,14 @@ CommentProc(char *function, List *arguments, char *comment)
/*** Now, find the corresponding oid for this procedure ***/ /*** Now, find the corresponding oid for this procedure ***/
functuple = SearchSysCacheTuple(PROCNAME, PointerGetDatum(function), oid = GetSysCacheOid(PROCNAME,
Int32GetDatum(argcount), PointerGetDatum(function),
PointerGetDatum(argoids), 0); Int32GetDatum(argcount),
if (!HeapTupleIsValid(functuple)) PointerGetDatum(argoids),
0);
if (!OidIsValid(oid))
func_error("CommentProc", function, argcount, argoids, NULL); func_error("CommentProc", function, argcount, argoids, NULL);
oid = functuple->t_data->t_oid;
/*** Call CreateComments() to create/drop the comments ***/ /*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment); CreateComments(oid, comment);
@ -738,10 +730,11 @@ CommentOperator(char *opername, List *arguments, char *comment)
/*** Attempt to fetch the operator oid ***/ /*** Attempt to fetch the operator oid ***/
optuple = SearchSysCacheTupleCopy(OPERNAME, PointerGetDatum(opername), optuple = SearchSysCache(OPERNAME,
ObjectIdGetDatum(leftoid), PointerGetDatum(opername),
ObjectIdGetDatum(rightoid), ObjectIdGetDatum(leftoid),
CharGetDatum(oprtype)); ObjectIdGetDatum(rightoid),
CharGetDatum(oprtype));
if (!HeapTupleIsValid(optuple)) if (!HeapTupleIsValid(optuple))
elog(ERROR, "operator '%s' does not exist", opername); elog(ERROR, "operator '%s' does not exist", opername);
@ -764,6 +757,8 @@ CommentOperator(char *opername, List *arguments, char *comment)
if (oid == InvalidOid) if (oid == InvalidOid)
elog(ERROR, "operator '%s' does not have an underlying function", opername); elog(ERROR, "operator '%s' does not have an underlying function", opername);
ReleaseSysCache(optuple);
/*** Call CreateComments() to create/drop the comments ***/ /*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment); CreateComments(oid, comment);

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.123 2000/11/12 00:36:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.124 2000/11/16 22:30:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -48,9 +48,9 @@
static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print); static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print);
static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print); static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print);
static Oid GetOutputFunction(Oid type); static Oid GetOutputFunction(Oid type);
static Oid GetTypeElement(Oid type);
static Oid GetInputFunction(Oid type); static Oid GetInputFunction(Oid type);
static Oid IsTypeByVal(Oid type); static Oid GetTypeElement(Oid type);
static bool IsTypeByVal(Oid type);
static void CopyReadNewline(FILE *fp, int *newline); static void CopyReadNewline(FILE *fp, int *newline);
static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print); static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print);
@ -669,7 +669,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
continue; continue;
} }
#endif /* _DROP_COLUMN_HACK__ */ #endif /* _DROP_COLUMN_HACK__ */
byval[i] = (bool) IsTypeByVal(attr[i]->atttypid); byval[i] = IsTypeByVal(attr[i]->atttypid);
} }
lineno = 0; lineno = 0;
@ -893,65 +893,64 @@ static Oid
GetOutputFunction(Oid type) GetOutputFunction(Oid type)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
Oid result;
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(type), ObjectIdGetDatum(type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
if (HeapTupleIsValid(typeTuple)) elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type);
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput; result = ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput;
ReleaseSysCache(typeTuple);
elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type); return result;
return InvalidOid;
}
static Oid
GetTypeElement(Oid type)
{
HeapTuple typeTuple;
typeTuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(type),
0, 0, 0);
if (HeapTupleIsValid(typeTuple))
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type);
return InvalidOid;
} }
static Oid static Oid
GetInputFunction(Oid type) GetInputFunction(Oid type)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
Oid result;
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(type), ObjectIdGetDatum(type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
if (HeapTupleIsValid(typeTuple)) elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type);
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typinput; result = ((Form_pg_type) GETSTRUCT(typeTuple))->typinput;
ReleaseSysCache(typeTuple);
elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type); return result;
return InvalidOid;
} }
static Oid static Oid
GetTypeElement(Oid type)
{
HeapTuple typeTuple;
Oid result;
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(type),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "GetTypeElement: Cache lookup of type %u failed", type);
result = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
ReleaseSysCache(typeTuple);
return result;
}
static bool
IsTypeByVal(Oid type) IsTypeByVal(Oid type)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
bool result;
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(type), ObjectIdGetDatum(type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
if (HeapTupleIsValid(typeTuple)) elog(ERROR, "IsTypeByVal: Cache lookup of type %u failed", type);
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval; result = ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval;
ReleaseSysCache(typeTuple);
elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type); return result;
return InvalidOid;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.66 2000/11/13 09:16:55 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.67 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -408,11 +408,14 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
* form name, type and constraints * form name, type and constraints
*/ */
attributeName = NameStr(attribute->attname); attributeName = NameStr(attribute->attname);
tuple = SearchSysCacheTuple(TYPEOID, tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(attribute->atttypid), ObjectIdGetDatum(attribute->atttypid),
0, 0, 0); 0, 0, 0);
Assert(HeapTupleIsValid(tuple)); if (!HeapTupleIsValid(tuple))
attributeType = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname); elog(ERROR, "CREATE TABLE: cache lookup failed for type %u",
attribute->atttypid);
attributeType = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname));
ReleaseSysCache(tuple);
/* /*
* check validity * check validity
@ -554,22 +557,25 @@ StoreCatalogInheritance(Oid relationId, List *supers)
idList = NIL; idList = NIL;
foreach(entry, supers) foreach(entry, supers)
{ {
Oid entryOid;
Datum datum[Natts_pg_inherits]; Datum datum[Natts_pg_inherits];
char nullarr[Natts_pg_inherits]; char nullarr[Natts_pg_inherits];
tuple = SearchSysCacheTuple(RELNAME, entryOid = GetSysCacheOid(RELNAME,
PointerGetDatum(strVal(lfirst(entry))), PointerGetDatum(strVal(lfirst(entry))),
0, 0, 0); 0, 0, 0);
AssertArg(HeapTupleIsValid(tuple)); if (!OidIsValid(entryOid))
elog(ERROR, "StoreCatalogInheritance: cache lookup failed for relation \"%s\"",
strVal(lfirst(entry)));
/* /*
* build idList for use below * build idList for use below
*/ */
idList = lappendi(idList, tuple->t_data->t_oid); idList = lappendi(idList, entryOid);
datum[0] = ObjectIdGetDatum(relationId); /* inhrel */ datum[0] = ObjectIdGetDatum(relationId); /* inhrel */
datum[1] = ObjectIdGetDatum(tuple->t_data->t_oid); /* inhparent */ datum[1] = ObjectIdGetDatum(entryOid); /* inhparent */
datum[2] = Int16GetDatum(seqNumber); /* inhseqno */ datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
nullarr[0] = ' '; nullarr[0] = ' ';
nullarr[1] = ' '; nullarr[1] = ' ';
@ -624,11 +630,10 @@ StoreCatalogInheritance(Oid relationId, List *supers)
for (number = 1;; number += 1) for (number = 1;; number += 1)
{ {
tuple = SearchSysCacheTuple(INHRELID, tuple = SearchSysCache(INHRELID,
ObjectIdGetDatum(id), ObjectIdGetDatum(id),
Int16GetDatum(number), Int16GetDatum(number),
0, 0); 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
break; break;
@ -636,6 +641,8 @@ StoreCatalogInheritance(Oid relationId, List *supers)
GETSTRUCT(tuple))->inhparent, GETSTRUCT(tuple))->inhparent,
NIL); NIL);
ReleaseSysCache(tuple);
current = lnext(current); current = lnext(current);
} }
lnext(current) = next; lnext(current) = next;
@ -746,35 +753,28 @@ checkAttrExists(const char *attributeName, const char *attributeType, List *sche
static void static void
setRelhassubclassInRelation(Oid relationId, bool relhassubclass) setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
{ {
Relation relationRelation; Relation relationRelation;
HeapTuple tuple; HeapTuple tuple;
Relation idescs[Num_pg_class_indices]; Relation idescs[Num_pg_class_indices];
/* /*
* Lock a relation given its Oid. Go to the RelationRelation (i.e. * Fetch a modifiable copy of the tuple, modify it, update pg_class.
* pg_relation), find the appropriate tuple, and add the specified */
* lock to it. relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
*/ tuple = SearchSysCacheCopy(RELOID,
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock); ObjectIdGetDatum(relationId),
tuple = SearchSysCacheTupleCopy(RELOID, 0, 0, 0);
ObjectIdGetDatum(relationId), if (!HeapTupleIsValid(tuple))
0, 0, 0) elog(ERROR, "setRelhassubclassInRelation: cache lookup failed for relation %u", relationId);
;
Assert(HeapTupleIsValid(tuple));
((Form_pg_class) GETSTRUCT(tuple))->relhassubclass = relhassubclass; ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass = relhassubclass;
heap_update(relationRelation, &tuple->t_self, tuple, NULL); heap_update(relationRelation, &tuple->t_self, tuple, NULL);
/* keep the catalog indices up to date */ /* keep the catalog indices up to date */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation, tuple CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation, tuple);
); CatalogCloseIndices(Num_pg_class_indices, idescs);
CatalogCloseIndices(Num_pg_class_indices, idescs);
heap_freetuple(tuple); heap_freetuple(tuple);
heap_close(relationRelation, RowExclusiveLock); heap_close(relationRelation, RowExclusiveLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.67 2000/11/14 18:37:41 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.68 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -445,9 +445,9 @@ get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb)
{ {
HeapTuple utup; HeapTuple utup;
utup = SearchSysCacheTuple(SHADOWSYSID, utup = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(use_sysid), ObjectIdGetDatum(use_sysid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(utup)) if (!HeapTupleIsValid(utup))
return false; return false;
@ -457,6 +457,8 @@ get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb)
if (use_createdb) if (use_createdb)
*use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb; *use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
ReleaseSysCache(utup);
return true; return true;
} }

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.47 2000/10/07 00:58:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.48 2000/11/16 22:30:18 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -277,10 +277,9 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
Form_pg_language languageStruct; Form_pg_language languageStruct;
/* Lookup the language in the system cache */ /* Lookup the language in the system cache */
languageTuple = SearchSysCacheTuple(LANGNAME, languageTuple = SearchSysCache(LANGNAME,
PointerGetDatum(languageName), PointerGetDatum(languageName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(languageTuple)) if (!HeapTupleIsValid(languageTuple))
elog(ERROR, elog(ERROR,
"Unrecognized language specified in a CREATE FUNCTION: " "Unrecognized language specified in a CREATE FUNCTION: "
@ -299,12 +298,12 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
* be defined by postgres superusers only * be defined by postgres superusers only
*/ */
if (!languageStruct->lanpltrusted && !superuser()) if (!languageStruct->lanpltrusted && !superuser())
{
elog(ERROR, "Only users with Postgres superuser privilege " elog(ERROR, "Only users with Postgres superuser privilege "
"are permitted to create a function in the '%s' " "are permitted to create a function in the '%s' "
"language.", "language.",
languageName); languageName);
}
ReleaseSysCache(languageTuple);
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.40 2000/11/08 22:09:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.41 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -86,7 +86,6 @@ DefineIndex(char *heapRelationName,
Oid relationId; Oid relationId;
IndexInfo *indexInfo; IndexInfo *indexInfo;
int numberOfAttributes; int numberOfAttributes;
HeapTuple tuple;
List *cnfPred = NIL; List *cnfPred = NIL;
bool lossy = false; bool lossy = false;
List *pl; List *pl;
@ -111,13 +110,12 @@ DefineIndex(char *heapRelationName,
/* /*
* compute access method id * compute access method id
*/ */
tuple = SearchSysCacheTuple(AMNAME, accessMethodId = GetSysCacheOid(AMNAME,
PointerGetDatum(accessMethodName), PointerGetDatum(accessMethodName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!OidIsValid(accessMethodId))
elog(ERROR, "DefineIndex: access method \"%s\" not found", elog(ERROR, "DefineIndex: access method \"%s\" not found",
accessMethodName); accessMethodName);
accessMethodId = tuple->t_data->t_oid;
/* /*
* XXX Hardwired hacks to check for limitations on supported index types. * XXX Hardwired hacks to check for limitations on supported index types.
@ -239,21 +237,22 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
/* /*
* Get index's relation id and access method id from pg_class * Get index's relation id and access method id from pg_class
*/ */
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCache(RELNAME,
PointerGetDatum(indexRelationName), PointerGetDatum(indexRelationName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ExtendIndex: index \"%s\" not found", elog(ERROR, "ExtendIndex: index \"%s\" not found",
indexRelationName); indexRelationName);
indexId = tuple->t_data->t_oid; indexId = tuple->t_data->t_oid;
accessMethodId = ((Form_pg_class) GETSTRUCT(tuple))->relam; accessMethodId = ((Form_pg_class) GETSTRUCT(tuple))->relam;
ReleaseSysCache(tuple);
/* /*
* Extract info from the pg_index tuple for the index * Extract info from the pg_index tuple for the index
*/ */
tuple = SearchSysCacheTuple(INDEXRELID, tuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexId), ObjectIdGetDatum(indexId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ExtendIndex: relation \"%s\" is not an index", elog(ERROR, "ExtendIndex: relation \"%s\" is not an index",
indexRelationName); indexRelationName);
@ -262,6 +261,7 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
relationId = index->indrelid; relationId = index->indrelid;
indexInfo = BuildIndexInfo(tuple); indexInfo = BuildIndexInfo(tuple);
oldPred = indexInfo->ii_Predicate; oldPred = indexInfo->ii_Predicate;
ReleaseSysCache(tuple);
if (oldPred == NULL) if (oldPred == NULL)
elog(ERROR, "ExtendIndex: \"%s\" is not a partial index", elog(ERROR, "ExtendIndex: \"%s\" is not a partial index",
@ -391,16 +391,16 @@ FuncIndexArgs(IndexInfo *indexInfo,
HeapTuple tuple; HeapTuple tuple;
Form_pg_attribute att; Form_pg_attribute att;
tuple = SearchSysCacheTuple(ATTNAME, tuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relId), ObjectIdGetDatum(relId),
PointerGetDatum(arg), PointerGetDatum(arg),
0, 0); 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "DefineIndex: attribute \"%s\" not found", arg); elog(ERROR, "DefineIndex: attribute \"%s\" not found", arg);
att = (Form_pg_attribute) GETSTRUCT(tuple); att = (Form_pg_attribute) GETSTRUCT(tuple);
indexInfo->ii_KeyAttrNumbers[nargs] = att->attnum; indexInfo->ii_KeyAttrNumbers[nargs] = att->attnum;
argTypes[nargs] = att->atttypid; argTypes[nargs] = att->atttypid;
ReleaseSysCache(tuple);
nargs++; nargs++;
} }
@ -465,10 +465,10 @@ NormIndexAttrs(IndexInfo *indexInfo,
if (attribute->name == NULL) if (attribute->name == NULL)
elog(ERROR, "missing attribute for define index"); elog(ERROR, "missing attribute for define index");
atttuple = SearchSysCacheTupleCopy(ATTNAME, atttuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relId), ObjectIdGetDatum(relId),
PointerGetDatum(attribute->name), PointerGetDatum(attribute->name),
0, 0); 0, 0);
if (!HeapTupleIsValid(atttuple)) if (!HeapTupleIsValid(atttuple))
elog(ERROR, "DefineIndex: attribute \"%s\" not found", elog(ERROR, "DefineIndex: attribute \"%s\" not found",
attribute->name); attribute->name);
@ -479,7 +479,7 @@ NormIndexAttrs(IndexInfo *indexInfo,
classOidP[attn] = GetAttrOpClass(attribute, attform->atttypid, classOidP[attn] = GetAttrOpClass(attribute, attform->atttypid,
accessMethodName, accessMethodId); accessMethodName, accessMethodId);
heap_freetuple(atttuple); ReleaseSysCache(atttuple);
attn++; attn++;
} }
} }
@ -507,13 +507,12 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
doTypeCheck = false; doTypeCheck = false;
} }
tuple = SearchSysCacheTuple(CLANAME, opClassId = GetSysCacheOid(CLANAME,
PointerGetDatum(attribute->class), PointerGetDatum(attribute->class),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!OidIsValid(opClassId))
elog(ERROR, "DefineIndex: opclass \"%s\" not found", elog(ERROR, "DefineIndex: opclass \"%s\" not found",
attribute->class); attribute->class);
opClassId = tuple->t_data->t_oid;
/* /*
* Assume the opclass is supported by this index access method * Assume the opclass is supported by this index access method
@ -532,10 +531,8 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
scan = heap_beginscan(relation, false, SnapshotNow, 2, entry); scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
if (! HeapTupleIsValid(tuple = heap_getnext(scan, 0))) if (! HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{
elog(ERROR, "DefineIndex: opclass \"%s\" not supported by access method \"%s\"", elog(ERROR, "DefineIndex: opclass \"%s\" not supported by access method \"%s\"",
attribute->class, accessMethodName); attribute->class, accessMethodName);
}
oprId = ((Form_pg_amop) GETSTRUCT(tuple))->amopopr; oprId = ((Form_pg_amop) GETSTRUCT(tuple))->amopopr;
@ -557,9 +554,9 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
*/ */
if (doTypeCheck) if (doTypeCheck)
{ {
tuple = SearchSysCacheTuple(OPEROID, tuple = SearchSysCache(OPEROID,
ObjectIdGetDatum(oprId), ObjectIdGetDatum(oprId),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tuple); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tuple);
@ -570,6 +567,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
! IS_BINARY_COMPATIBLE(attrType, opInputType)) ! IS_BINARY_COMPATIBLE(attrType, opInputType))
elog(ERROR, "DefineIndex: opclass \"%s\" does not accept datatype \"%s\"", elog(ERROR, "DefineIndex: opclass \"%s\" does not accept datatype \"%s\"",
attribute->class, typeidTypeName(attrType)); attribute->class, typeidTypeName(attrType));
ReleaseSysCache(tuple);
} }
} }
@ -580,15 +578,18 @@ static char *
GetDefaultOpClass(Oid atttypid) GetDefaultOpClass(Oid atttypid)
{ {
HeapTuple tuple; HeapTuple tuple;
char *result;
tuple = SearchSysCacheTuple(CLADEFTYPE, tuple = SearchSysCache(CLADEFTYPE,
ObjectIdGetDatum(atttypid), ObjectIdGetDatum(atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
return NULL; return NULL;
return DatumGetCString(DirectFunctionCall1(nameout, result = pstrdup(NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname));
NameGetDatum(&((Form_pg_opclass) GETSTRUCT(tuple))->opcname)));
ReleaseSysCache(tuple);
return result;
} }
/* /*
@ -605,21 +606,19 @@ RemoveIndex(char *name)
{ {
HeapTuple tuple; HeapTuple tuple;
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCache(RELNAME,
PointerGetDatum(name), PointerGetDatum(name),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "index \"%s\" does not exist", name); elog(ERROR, "index \"%s\" does not exist", name);
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX) if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
{
elog(ERROR, "relation \"%s\" is of type \"%c\"", elog(ERROR, "relation \"%s\" is of type \"%c\"",
name, name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
((Form_pg_class) GETSTRUCT(tuple))->relkind);
}
index_drop(tuple->t_data->t_oid); index_drop(tuple->t_data->t_oid);
ReleaseSysCache(tuple);
} }
/* /*
@ -644,22 +643,20 @@ ReindexIndex(const char *name, bool force /* currently unused */ )
if (IsTransactionBlock()) if (IsTransactionBlock())
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block"); elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCache(RELNAME,
PointerGetDatum(name), PointerGetDatum(name),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "index \"%s\" does not exist", name); elog(ERROR, "index \"%s\" does not exist", name);
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX) if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
{
elog(ERROR, "relation \"%s\" is of type \"%c\"", elog(ERROR, "relation \"%s\" is of type \"%c\"",
name, name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
((Form_pg_class) GETSTRUCT(tuple))->relkind);
}
if (!reindex_index(tuple->t_data->t_oid, force)) if (!reindex_index(tuple->t_data->t_oid, force))
elog(NOTICE, "index \"%s\" wasn't reindexed", name); elog(NOTICE, "index \"%s\" wasn't reindexed", name);
ReleaseSysCache(tuple);
} }
/* /*
@ -684,22 +681,20 @@ ReindexTable(const char *name, bool force)
if (IsTransactionBlock()) if (IsTransactionBlock())
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block"); elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCache(RELNAME,
PointerGetDatum(name), PointerGetDatum(name),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "table \"%s\" does not exist", name); elog(ERROR, "table \"%s\" does not exist", name);
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION) if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION)
{
elog(ERROR, "relation \"%s\" is of type \"%c\"", elog(ERROR, "relation \"%s\" is of type \"%c\"",
name, name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
((Form_pg_class) GETSTRUCT(tuple))->relkind);
}
if (!reindex_relation(tuple->t_data->t_oid, force)) if (!reindex_relation(tuple->t_data->t_oid, force))
elog(NOTICE, "table \"%s\" wasn't reindexed", name); elog(NOTICE, "table \"%s\" wasn't reindexed", name);
ReleaseSysCache(tuple);
} }
/* /*

View File

@ -48,7 +48,6 @@ void
CreateProceduralLanguage(CreatePLangStmt *stmt) CreateProceduralLanguage(CreatePLangStmt *stmt)
{ {
char languageName[NAMEDATALEN]; char languageName[NAMEDATALEN];
HeapTuple langTup;
HeapTuple procTup; HeapTuple procTup;
Oid typev[FUNC_MAX_ARGS]; Oid typev[FUNC_MAX_ARGS];
@ -77,10 +76,9 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
*/ */
case_translate_language_name(stmt->plname, languageName); case_translate_language_name(stmt->plname, languageName);
langTup = SearchSysCacheTuple(LANGNAME, if (SearchSysCacheExists(LANGNAME,
PointerGetDatum(languageName), PointerGetDatum(languageName),
0, 0, 0); 0, 0, 0))
if (HeapTupleIsValid(langTup))
elog(ERROR, "Language %s already exists", languageName); elog(ERROR, "Language %s already exists", languageName);
/* ---------------- /* ----------------
@ -89,21 +87,17 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
* ---------------- * ----------------
*/ */
memset(typev, 0, sizeof(typev)); memset(typev, 0, sizeof(typev));
procTup = SearchSysCacheTuple(PROCNAME, procTup = SearchSysCache(PROCNAME,
PointerGetDatum(stmt->plhandler), PointerGetDatum(stmt->plhandler),
Int32GetDatum(0), Int32GetDatum(0),
PointerGetDatum(typev), PointerGetDatum(typev),
0); 0);
if (!HeapTupleIsValid(procTup)) if (!HeapTupleIsValid(procTup))
{
elog(ERROR, "PL handler function %s() doesn't exist", elog(ERROR, "PL handler function %s() doesn't exist",
stmt->plhandler); stmt->plhandler);
}
if (((Form_pg_proc) GETSTRUCT(procTup))->prorettype != InvalidOid) if (((Form_pg_proc) GETSTRUCT(procTup))->prorettype != InvalidOid)
{
elog(ERROR, "PL handler function %s() isn't of return type Opaque", elog(ERROR, "PL handler function %s() isn't of return type Opaque",
stmt->plhandler); stmt->plhandler);
}
/* ---------------- /* ----------------
* Insert the new language into pg_language * Insert the new language into pg_language
@ -123,6 +117,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
values[i++] = DirectFunctionCall1(textin, values[i++] = DirectFunctionCall1(textin,
CStringGetDatum(stmt->plcompiler)); CStringGetDatum(stmt->plcompiler));
ReleaseSysCache(procTup);
rel = heap_openr(LanguageRelationName, RowExclusiveLock); rel = heap_openr(LanguageRelationName, RowExclusiveLock);
tupDesc = rel->rd_att; tupDesc = rel->rd_att;
@ -173,9 +169,9 @@ DropProceduralLanguage(DropPLangStmt *stmt)
rel = heap_openr(LanguageRelationName, RowExclusiveLock); rel = heap_openr(LanguageRelationName, RowExclusiveLock);
langTup = SearchSysCacheTupleCopy(LANGNAME, langTup = SearchSysCacheCopy(LANGNAME,
PointerGetDatum(languageName), PointerGetDatum(languageName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(langTup)) if (!HeapTupleIsValid(langTup))
elog(ERROR, "Language %s doesn't exist", languageName); elog(ERROR, "Language %s doesn't exist", languageName);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.54 2000/10/16 17:08:05 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.55 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -73,11 +73,11 @@ RemoveOperator(char *operatorName, /* operator name */
relation = heap_openr(OperatorRelationName, RowExclusiveLock); relation = heap_openr(OperatorRelationName, RowExclusiveLock);
tup = SearchSysCacheTupleCopy(OPERNAME, tup = SearchSysCacheCopy(OPERNAME,
PointerGetDatum(operatorName), PointerGetDatum(operatorName),
ObjectIdGetDatum(typeId1), ObjectIdGetDatum(typeId1),
ObjectIdGetDatum(typeId2), ObjectIdGetDatum(typeId2),
CharGetDatum(oprtype)); CharGetDatum(oprtype));
if (HeapTupleIsValid(tup)) if (HeapTupleIsValid(tup))
{ {
@ -254,14 +254,11 @@ RemoveType(char *typeName) /* type name to be removed */
relation = heap_openr(TypeRelationName, RowExclusiveLock); relation = heap_openr(TypeRelationName, RowExclusiveLock);
tup = SearchSysCacheTuple(TYPENAME, tup = SearchSysCache(TYPENAME,
PointerGetDatum(typeName), PointerGetDatum(typeName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
heap_close(relation, RowExclusiveLock);
elog(ERROR, "RemoveType: type '%s' does not exist", typeName); elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
}
typeOid = tup->t_data->t_oid; typeOid = tup->t_data->t_oid;
@ -271,19 +268,20 @@ RemoveType(char *typeName) /* type name to be removed */
heap_delete(relation, &tup->t_self, NULL); heap_delete(relation, &tup->t_self, NULL);
/* Now, Delete the "array of" that type */ ReleaseSysCache(tup);
/* Also, delete the "array of" that type */
shadow_type = makeArrayTypeName(typeName); shadow_type = makeArrayTypeName(typeName);
tup = SearchSysCacheTuple(TYPENAME, tup = SearchSysCache(TYPENAME,
PointerGetDatum(shadow_type), PointerGetDatum(shadow_type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{
heap_close(relation, RowExclusiveLock);
elog(ERROR, "RemoveType: type '%s' does not exist", shadow_type); elog(ERROR, "RemoveType: type '%s' does not exist", shadow_type);
}
heap_delete(relation, &tup->t_self, NULL); heap_delete(relation, &tup->t_self, NULL);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
} }
@ -321,12 +319,11 @@ RemoveFunction(char *functionName, /* function name to be removed */
argList[i] = InvalidOid; argList[i] = InvalidOid;
else else
{ {
tup = SearchSysCacheTuple(TYPENAME, argList[i] = GetSysCacheOid(TYPENAME,
PointerGetDatum(typnam), PointerGetDatum(typnam),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!OidIsValid(argList[i]))
elog(ERROR, "RemoveFunction: type '%s' not found", typnam); elog(ERROR, "RemoveFunction: type '%s' not found", typnam);
argList[i] = tup->t_data->t_oid;
} }
} }
@ -337,11 +334,12 @@ RemoveFunction(char *functionName, /* function name to be removed */
} }
relation = heap_openr(ProcedureRelationName, RowExclusiveLock); relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
tup = SearchSysCacheTuple(PROCNAME,
PointerGetDatum(functionName), tup = SearchSysCache(PROCNAME,
Int32GetDatum(nargs), PointerGetDatum(functionName),
PointerGetDatum(argList), Int32GetDatum(nargs),
0); PointerGetDatum(argList),
0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
func_error("RemoveFunction", functionName, nargs, argList, NULL); func_error("RemoveFunction", functionName, nargs, argList, NULL);
@ -359,6 +357,8 @@ RemoveFunction(char *functionName, /* function name to be removed */
heap_delete(relation, &tup->t_self, NULL); heap_delete(relation, &tup->t_self, NULL);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
} }
@ -370,7 +370,6 @@ RemoveAggregate(char *aggName, char *aggType)
Oid basetypeID = InvalidOid; Oid basetypeID = InvalidOid;
bool defined; bool defined;
/* /*
* if a basetype is passed in, then attempt to find an aggregate for * if a basetype is passed in, then attempt to find an aggregate for
* that specific type. * that specific type.
@ -405,10 +404,11 @@ RemoveAggregate(char *aggName, char *aggType)
} }
relation = heap_openr(AggregateRelationName, RowExclusiveLock); relation = heap_openr(AggregateRelationName, RowExclusiveLock);
tup = SearchSysCacheTuple(AGGNAME,
PointerGetDatum(aggName), tup = SearchSysCache(AGGNAME,
ObjectIdGetDatum(basetypeID), PointerGetDatum(aggName),
0, 0); ObjectIdGetDatum(basetypeID),
0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{ {
@ -431,5 +431,7 @@ RemoveAggregate(char *aggName, char *aggType)
heap_delete(relation, &tup->t_self, NULL); heap_delete(relation, &tup->t_self, NULL);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.52 2000/11/08 22:09:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.53 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -58,8 +58,7 @@ renameatt(char *relname,
Relation targetrelation; Relation targetrelation;
Relation attrelation; Relation attrelation;
HeapTuple reltup, HeapTuple reltup,
oldatttup, atttup;
newatttup;
Oid relid; Oid relid;
/* /*
@ -113,9 +112,9 @@ renameatt(char *relname,
if (childrelid == relid) if (childrelid == relid)
continue; continue;
reltup = SearchSysCacheTuple(RELOID, reltup = SearchSysCache(RELOID,
ObjectIdGetDatum(childrelid), ObjectIdGetDatum(childrelid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
{ {
elog(ERROR, "renameatt: can't find catalog entry for inheriting class with oid %u", elog(ERROR, "renameatt: can't find catalog entry for inheriting class with oid %u",
@ -125,6 +124,7 @@ renameatt(char *relname,
StrNCpy(childname, StrNCpy(childname,
NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname), NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname),
NAMEDATALEN); NAMEDATALEN);
ReleaseSysCache(reltup);
/* note we need not recurse again! */ /* note we need not recurse again! */
renameatt(childname, oldattname, newattname, 0); renameatt(childname, oldattname, newattname, 0);
} }
@ -132,42 +132,38 @@ renameatt(char *relname,
attrelation = heap_openr(AttributeRelationName, RowExclusiveLock); attrelation = heap_openr(AttributeRelationName, RowExclusiveLock);
oldatttup = SearchSysCacheTupleCopy(ATTNAME, atttup = SearchSysCacheCopy(ATTNAME,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
PointerGetDatum(oldattname), PointerGetDatum(oldattname),
0, 0); 0, 0);
if (!HeapTupleIsValid(oldatttup)) if (!HeapTupleIsValid(atttup))
elog(ERROR, "renameatt: attribute \"%s\" does not exist", oldattname); elog(ERROR, "renameatt: attribute \"%s\" does not exist", oldattname);
if (((Form_pg_attribute) GETSTRUCT(oldatttup))->attnum < 0) if (((Form_pg_attribute) GETSTRUCT(atttup))->attnum < 0)
elog(ERROR, "renameatt: system attribute \"%s\" not renamed", oldattname); elog(ERROR, "renameatt: system attribute \"%s\" not renamed", oldattname);
newatttup = SearchSysCacheTuple(ATTNAME,
ObjectIdGetDatum(relid),
PointerGetDatum(newattname),
0, 0);
/* should not already exist */ /* should not already exist */
if (HeapTupleIsValid(newatttup)) if (SearchSysCacheExists(ATTNAME,
{ ObjectIdGetDatum(relid),
heap_freetuple(oldatttup); PointerGetDatum(newattname),
0, 0))
elog(ERROR, "renameatt: attribute \"%s\" exists", newattname); elog(ERROR, "renameatt: attribute \"%s\" exists", newattname);
}
StrNCpy(NameStr(((Form_pg_attribute) GETSTRUCT(oldatttup))->attname), StrNCpy(NameStr(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
newattname, NAMEDATALEN); newattname, NAMEDATALEN);
heap_update(attrelation, &oldatttup->t_self, oldatttup, NULL); heap_update(attrelation, &atttup->t_self, atttup, NULL);
/* keep system catalog indices current */ /* keep system catalog indices current */
{ {
Relation irelations[Num_pg_attr_indices]; Relation irelations[Num_pg_attr_indices];
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations); CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, oldatttup); CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, atttup);
CatalogCloseIndices(Num_pg_attr_indices, irelations); CatalogCloseIndices(Num_pg_attr_indices, irelations);
} }
heap_freetuple(oldatttup); heap_freetuple(atttup);
heap_close(attrelation, RowExclusiveLock); heap_close(attrelation, RowExclusiveLock);
} }
@ -179,7 +175,7 @@ renamerel(const char *oldrelname, const char *newrelname)
{ {
Relation targetrelation; Relation targetrelation;
Relation relrelation; /* for RELATION relation */ Relation relrelation; /* for RELATION relation */
HeapTuple oldreltup; HeapTuple reltup;
Oid reloid; Oid reloid;
char relkind; char relkind;
Relation irelations[Num_pg_class_indices]; Relation irelations[Num_pg_class_indices];
@ -238,27 +234,27 @@ renamerel(const char *oldrelname, const char *newrelname)
*/ */
relrelation = heap_openr(RelationRelationName, RowExclusiveLock); relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
oldreltup = SearchSysCacheTupleCopy(RELNAME, reltup = SearchSysCacheCopy(RELNAME,
PointerGetDatum(oldrelname), PointerGetDatum(oldrelname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(oldreltup)) if (!HeapTupleIsValid(reltup))
elog(ERROR, "renamerel: relation \"%s\" does not exist", oldrelname); elog(ERROR, "renamerel: relation \"%s\" does not exist", oldrelname);
if (RelnameFindRelid(newrelname) != InvalidOid) if (RelnameFindRelid(newrelname) != InvalidOid)
elog(ERROR, "renamerel: relation \"%s\" exists", newrelname); elog(ERROR, "renamerel: relation \"%s\" exists", newrelname);
/* /*
* Update pg_class tuple with new relname. (Scribbling on oldreltup * Update pg_class tuple with new relname. (Scribbling on reltup
* is OK because it's a copy...) * is OK because it's a copy...)
*/ */
StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(oldreltup))->relname), StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname),
newrelname, NAMEDATALEN); newrelname, NAMEDATALEN);
heap_update(relrelation, &oldreltup->t_self, oldreltup, NULL); heap_update(relrelation, &reltup->t_self, reltup, NULL);
/* keep the system catalog indices current */ /* keep the system catalog indices current */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations); CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations);
CatalogIndexInsert(irelations, Num_pg_class_indices, relrelation, oldreltup); CatalogIndexInsert(irelations, Num_pg_class_indices, relrelation, reltup);
CatalogCloseIndices(Num_pg_class_indices, irelations); CatalogCloseIndices(Num_pg_class_indices, irelations);
heap_close(relrelation, NoLock); heap_close(relrelation, NoLock);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.79 2000/11/08 22:09:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.80 2000/11/16 22:30:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -154,11 +154,11 @@ CreateTrigger(CreateTrigStmt *stmt)
* Find and validate the trigger function. * Find and validate the trigger function.
*/ */
MemSet(fargtypes, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(fargtypes, 0, FUNC_MAX_ARGS * sizeof(Oid));
tuple = SearchSysCacheTuple(PROCNAME, tuple = SearchSysCache(PROCNAME,
PointerGetDatum(stmt->funcname), PointerGetDatum(stmt->funcname),
Int32GetDatum(0), Int32GetDatum(0),
PointerGetDatum(fargtypes), PointerGetDatum(fargtypes),
0); 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "CreateTrigger: function %s() does not exist", elog(ERROR, "CreateTrigger: function %s() does not exist",
stmt->funcname); stmt->funcname);
@ -167,6 +167,8 @@ CreateTrigger(CreateTrigStmt *stmt)
stmt->funcname); stmt->funcname);
funcoid = tuple->t_data->t_oid; funcoid = tuple->t_data->t_oid;
funclang = ((Form_pg_proc) GETSTRUCT(tuple))->prolang; funclang = ((Form_pg_proc) GETSTRUCT(tuple))->prolang;
ReleaseSysCache(tuple);
if (funclang != ClanguageId && if (funclang != ClanguageId &&
funclang != NEWClanguageId && funclang != NEWClanguageId &&
funclang != INTERNALlanguageId && funclang != INTERNALlanguageId &&
@ -174,14 +176,15 @@ CreateTrigger(CreateTrigStmt *stmt)
{ {
HeapTuple langTup; HeapTuple langTup;
langTup = SearchSysCacheTuple(LANGOID, langTup = SearchSysCache(LANGOID,
ObjectIdGetDatum(funclang), ObjectIdGetDatum(funclang),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(langTup)) if (!HeapTupleIsValid(langTup))
elog(ERROR, "CreateTrigger: cache lookup for PL %u failed", elog(ERROR, "CreateTrigger: cache lookup for PL %u failed",
funclang); funclang);
if (((Form_pg_language) GETSTRUCT(langTup))->lanispl == false) if (((Form_pg_language) GETSTRUCT(langTup))->lanispl == false)
elog(ERROR, "CreateTrigger: only builtin, C and PL functions are supported"); elog(ERROR, "CreateTrigger: only builtin, C and PL functions are supported");
ReleaseSysCache(langTup);
} }
/* /*
@ -268,9 +271,9 @@ CreateTrigger(CreateTrigStmt *stmt)
* rebuild relcache entries. * rebuild relcache entries.
*/ */
pgrel = heap_openr(RelationRelationName, RowExclusiveLock); pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTupleCopy(RELNAME, tuple = SearchSysCacheCopy(RELNAME,
PointerGetDatum(stmt->relname), PointerGetDatum(stmt->relname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "CreateTrigger: relation %s not found in pg_class", elog(ERROR, "CreateTrigger: relation %s not found in pg_class",
stmt->relname); stmt->relname);
@ -353,9 +356,9 @@ DropTrigger(DropTrigStmt *stmt)
* rebuild relcache entries. * rebuild relcache entries.
*/ */
pgrel = heap_openr(RelationRelationName, RowExclusiveLock); pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTupleCopy(RELNAME, tuple = SearchSysCacheCopy(RELNAME,
PointerGetDatum(stmt->relname), PointerGetDatum(stmt->relname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "DropTrigger: relation %s not found in pg_class", elog(ERROR, "DropTrigger: relation %s not found in pg_class",
stmt->relname); stmt->relname);
@ -426,9 +429,9 @@ RelationRemoveTriggers(Relation rel)
Relation ridescs[Num_pg_class_indices]; Relation ridescs[Num_pg_class_indices];
pgrel = heap_openr(RelationRelationName, RowExclusiveLock); pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
tup = SearchSysCacheTupleCopy(RELOID, tup = SearchSysCacheCopy(RELOID,
RelationGetRelid(rel), RelationGetRelid(rel),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class", elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class",
RelationGetRelid(rel)); RelationGetRelid(rel));

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.69 2000/10/19 03:55:51 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.70 2000/11/16 22:30:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -363,9 +363,9 @@ AlterUser(AlterUserStmt *stmt)
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
tuple = SearchSysCacheTuple(SHADOWNAME, tuple = SearchSysCache(SHADOWNAME,
PointerGetDatum(stmt->user), PointerGetDatum(stmt->user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, AccessExclusiveLock);
@ -470,10 +470,13 @@ AlterUser(AlterUserStmt *stmt)
CatalogOpenIndices(Num_pg_shadow_indices, CatalogOpenIndices(Num_pg_shadow_indices,
Name_pg_shadow_indices, idescs); Name_pg_shadow_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_shadow_indices, pg_shadow_rel, CatalogIndexInsert(idescs, Num_pg_shadow_indices, pg_shadow_rel,
tuple); new_tuple);
CatalogCloseIndices(Num_pg_shadow_indices, idescs); CatalogCloseIndices(Num_pg_shadow_indices, idescs);
} }
ReleaseSysCache(tuple);
heap_freetuple(new_tuple);
/* /*
* Write the updated pg_shadow data to the flat password file. * Write the updated pg_shadow data to the flat password file.
*/ */
@ -525,9 +528,9 @@ DropUser(DropUserStmt *stmt)
int32 usesysid; int32 usesysid;
const char *user = strVal(lfirst(item)); const char *user = strVal(lfirst(item));
tuple = SearchSysCacheTuple(SHADOWNAME, tuple = SearchSysCache(SHADOWNAME,
PointerGetDatum(user), PointerGetDatum(user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, AccessExclusiveLock);
@ -579,6 +582,8 @@ DropUser(DropUserStmt *stmt)
*/ */
heap_delete(pg_shadow_rel, &tuple->t_self, NULL); heap_delete(pg_shadow_rel, &tuple->t_self, NULL);
ReleaseSysCache(tuple);
/* /*
* Remove user from groups * Remove user from groups
* *
@ -633,24 +638,21 @@ CheckPgUserAclNotNull()
{ {
HeapTuple htup; HeapTuple htup;
htup = SearchSysCacheTuple(RELNAME, htup = SearchSysCache(RELNAME,
PointerGetDatum(ShadowRelationName), PointerGetDatum(ShadowRelationName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup))
{ elog(ERROR, "CheckPgUserAclNotNull: \"%s\" not found",
/* BIG problem */
elog(ERROR, "IsPgUserAclNull: \"%s\" not found",
ShadowRelationName); ShadowRelationName);
}
if (heap_attisnull(htup, Anum_pg_class_relacl)) if (heap_attisnull(htup, Anum_pg_class_relacl))
{
elog(ERROR, elog(ERROR,
"To use passwords, you have to revoke permissions on %s " "To use passwords, you have to revoke permissions on %s "
"so normal users cannot read the passwords. " "so normal users cannot read the passwords. "
"Try 'REVOKE ALL ON \"%s\" FROM PUBLIC'.", "Try 'REVOKE ALL ON \"%s\" FROM PUBLIC'.",
ShadowRelationName, ShadowRelationName); ShadowRelationName, ShadowRelationName);
}
ReleaseSysCache(htup);
} }
@ -716,24 +718,21 @@ CreateGroup(CreateGroupStmt *stmt)
/* /*
* Translate the given user names to ids * Translate the given user names to ids
*/ */
foreach(item, stmt->initUsers) foreach(item, stmt->initUsers)
{ {
const char *groupuser = strVal(lfirst(item)); const char *groupuser = strVal(lfirst(item));
Value *v; Value *v;
tuple = SearchSysCacheTuple(SHADOWNAME, tuple = SearchSysCache(SHADOWNAME,
PointerGetDatum(groupuser), PointerGetDatum(groupuser),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
heap_close(pg_group_rel, AccessExclusiveLock);
elog(ERROR, "CREATE GROUP: user \"%s\" does not exist", groupuser); elog(ERROR, "CREATE GROUP: user \"%s\" does not exist", groupuser);
}
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
if (!member(v, newlist)) if (!member(v, newlist))
newlist = lcons(v, newlist); newlist = lcons(v, newlist);
ReleaseSysCache(tuple);
} }
/* build an array to insert */ /* build an array to insert */
@ -817,20 +816,19 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
pg_group_dsc = RelationGetDescr(pg_group_rel); pg_group_dsc = RelationGetDescr(pg_group_rel);
/* /*
* Verify that group exists. If we find a tuple, will take that the * Fetch existing tuple for group.
* rest of the way and make our modifications on it.
*/ */
if (!HeapTupleIsValid(group_tuple = SearchSysCacheTupleCopy(GRONAME, PointerGetDatum(stmt->name), 0, 0, 0))) group_tuple = SearchSysCache(GRONAME,
{ PointerGetDatum(stmt->name),
heap_close(pg_group_rel, AccessExclusiveLock); 0, 0, 0);
if (!HeapTupleIsValid(group_tuple))
elog(ERROR, "%s: group \"%s\" does not exist", tag, stmt->name); elog(ERROR, "%s: group \"%s\" does not exist", tag, stmt->name);
}
AssertState(stmt->action == +1 || stmt->action == -1);
/* /*
* Now decide what to do. * Now decide what to do.
*/ */
AssertState(stmt->action == +1 || stmt->action == -1);
if (stmt->action == +1) /* add users, might also be invoked by if (stmt->action == +1) /* add users, might also be invoked by
* create user */ * create user */
{ {
@ -876,15 +874,14 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
if (strcmp(tag, "ALTER GROUP") == 0) if (strcmp(tag, "ALTER GROUP") == 0)
{ {
/* Get the uid of the proposed user to add. */ /* Get the uid of the proposed user to add. */
tuple = SearchSysCacheTuple(SHADOWNAME, tuple = SearchSysCache(SHADOWNAME,
PointerGetDatum(strVal(lfirst(item))), PointerGetDatum(strVal(lfirst(item))),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ elog(ERROR, "%s: user \"%s\" does not exist",
heap_close(pg_group_rel, AccessExclusiveLock); tag, strVal(lfirst(item)));
elog(ERROR, "%s: user \"%s\" does not exist", tag, strVal(lfirst(item)));
}
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
ReleaseSysCache(tuple);
} }
else if (strcmp(tag, "CREATE USER") == 0) else if (strcmp(tag, "CREATE USER") == 0)
{ {
@ -999,15 +996,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
if (!is_dropuser) if (!is_dropuser)
{ {
/* Get the uid of the proposed user to drop. */ /* Get the uid of the proposed user to drop. */
tuple = SearchSysCacheTuple(SHADOWNAME, tuple = SearchSysCache(SHADOWNAME,
PointerGetDatum(strVal(lfirst(item))), PointerGetDatum(strVal(lfirst(item))),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{
heap_close(pg_group_rel, AccessExclusiveLock);
elog(ERROR, "ALTER GROUP: user \"%s\" does not exist", strVal(lfirst(item))); elog(ERROR, "ALTER GROUP: user \"%s\" does not exist", strVal(lfirst(item)));
}
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid); v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
ReleaseSysCache(tuple);
} }
else else
{ {
@ -1056,9 +1051,9 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
} /* endif group not null */ } /* endif group not null */
} /* endif alter group drop user */ } /* endif alter group drop user */
heap_close(pg_group_rel, AccessExclusiveLock); ReleaseSysCache(group_tuple);
pfree(group_tuple); heap_close(pg_group_rel, AccessExclusiveLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.172 2000/11/16 05:50:59 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.173 2000/11/16 22:30:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
@ -356,7 +356,6 @@ getrels(NameData *VacRelP)
static void static void
vacuum_rel(Oid relid, bool analyze, bool is_toastrel) vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
{ {
HeapTuple tuple;
Relation onerel; Relation onerel;
VacPageListData vacuum_pages; /* List of pages to vacuum and/or clean VacPageListData vacuum_pages; /* List of pages to vacuum and/or clean
* indices */ * indices */
@ -384,10 +383,9 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
* Race condition -- if the pg_class tuple has gone away since the * Race condition -- if the pg_class tuple has gone away since the
* last time we saw it, we don't need to vacuum it. * last time we saw it, we don't need to vacuum it.
*/ */
tuple = SearchSysCacheTuple(RELOID, if (!SearchSysCacheExists(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0))
if (!HeapTupleIsValid(tuple))
{ {
if (!is_toastrel) if (!is_toastrel)
CommitTransactionCommand(); CommitTransactionCommand();
@ -2237,17 +2235,17 @@ update_relstats(Oid relid, int num_pages, int num_tuples, bool hasindex,
*/ */
rd = heap_openr(RelationRelationName, RowExclusiveLock); rd = heap_openr(RelationRelationName, RowExclusiveLock);
ctup = SearchSysCacheTupleCopy(RELOID, ctup = SearchSysCache(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(ctup)) if (!HeapTupleIsValid(ctup))
elog(ERROR, "pg_class entry for relid %u vanished during vacuuming", elog(ERROR, "pg_class entry for relid %u vanished during vacuuming",
relid); relid);
/* get the buffer cache tuple */ /* get the buffer cache tuple */
rtup.t_self = ctup->t_self; rtup.t_self = ctup->t_self;
ReleaseSysCache(ctup);
heap_fetch(rd, SnapshotNow, &rtup, &buffer); heap_fetch(rd, SnapshotNow, &rtup, &buffer);
heap_freetuple(ctup);
/* overwrite the existing statistics in the tuple */ /* overwrite the existing statistics in the tuple */
pgcform = (Form_pg_class) GETSTRUCT(&rtup); pgcform = (Form_pg_class) GETSTRUCT(&rtup);
@ -2481,13 +2479,14 @@ get_index_desc(Relation onerel, int nindices, Relation *Irel)
for (i = 0; i < nindices; i++) for (i = 0; i < nindices; i++)
{ {
cachetuple = SearchSysCacheTuple(INDEXRELID, cachetuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(RelationGetRelid(Irel[i])), ObjectIdGetDatum(RelationGetRelid(Irel[i])),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(cachetuple)) if (!HeapTupleIsValid(cachetuple))
elog(ERROR, "get_index_desc: index %u not found", elog(ERROR, "get_index_desc: index %u not found",
RelationGetRelid(Irel[i])); RelationGetRelid(Irel[i]));
indexInfo[i] = BuildIndexInfo(cachetuple); indexInfo[i] = BuildIndexInfo(cachetuple);
ReleaseSysCache(cachetuple);
} }
return indexInfo; return indexInfo;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.68 2000/11/12 00:36:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.69 2000/11/16 22:30:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -740,9 +740,9 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo)
* Get the pg_index tuple for the index * Get the pg_index tuple for the index
* ---------------- * ----------------
*/ */
indexTuple = SearchSysCacheTuple(INDEXRELID, indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexOid), ObjectIdGetDatum(indexOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "ExecOpenIndices: index %u not found", indexOid); elog(ERROR, "ExecOpenIndices: index %u not found", indexOid);
@ -752,6 +752,8 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo)
*/ */
ii = BuildIndexInfo(indexTuple); ii = BuildIndexInfo(indexTuple);
ReleaseSysCache(indexTuple);
relationDescs[i] = indexDesc; relationDescs[i] = indexDesc;
indexInfoArray[i] = ii; indexInfoArray[i] = ii;
i++; i++;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.40 2000/11/12 00:36:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.41 2000/11/16 22:30:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -183,14 +183,11 @@ init_sql_fcache(FmgrInfo *finfo)
/* ---------------- /* ----------------
* get the procedure tuple corresponding to the given function Oid * get the procedure tuple corresponding to the given function Oid
*
* NB: use SearchSysCacheTupleCopy to ensure tuple lives long enough
* ---------------- * ----------------
*/ */
procedureTuple = SearchSysCacheTupleCopy(PROCOID, procedureTuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(foid), ObjectIdGetDatum(foid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procedureTuple)) if (!HeapTupleIsValid(procedureTuple))
elog(ERROR, "init_sql_fcache: Cache lookup failed for procedure %u", elog(ERROR, "init_sql_fcache: Cache lookup failed for procedure %u",
foid); foid);
@ -201,10 +198,9 @@ init_sql_fcache(FmgrInfo *finfo)
* get the return type from the procedure tuple * get the return type from the procedure tuple
* ---------------- * ----------------
*/ */
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procedureStruct->prorettype), ObjectIdGetDatum(procedureStruct->prorettype),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "init_sql_fcache: Cache lookup failed for type %u", elog(ERROR, "init_sql_fcache: Cache lookup failed for type %u",
procedureStruct->prorettype); procedureStruct->prorettype);
@ -286,7 +282,8 @@ init_sql_fcache(FmgrInfo *finfo)
pfree(src); pfree(src);
heap_freetuple(procedureTuple); ReleaseSysCache(typeTuple);
ReleaseSysCache(procedureTuple);
finfo->fn_extra = (void *) fcache; finfo->fn_extra = (void *) fcache;
} }

View File

@ -34,7 +34,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.71 2000/08/24 03:29:03 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.72 2000/11/16 22:30:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -51,6 +51,7 @@
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_oper.h" #include "parser/parse_oper.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/tuplesort.h" #include "utils/tuplesort.h"
#include "utils/datum.h" #include "utils/datum.h"
@ -105,7 +106,7 @@ typedef struct AggStatePerAggData
* We need the len and byval info for the agg's input, result, and * We need the len and byval info for the agg's input, result, and
* transition data types in order to know how to copy/delete values. * transition data types in order to know how to copy/delete values.
*/ */
int inputtypeLen, int16 inputtypeLen,
resulttypeLen, resulttypeLen,
transtypeLen; transtypeLen;
bool inputtypeByVal, bool inputtypeByVal,
@ -827,7 +828,6 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
char *aggname = aggref->aggname; char *aggname = aggref->aggname;
HeapTuple aggTuple; HeapTuple aggTuple;
Form_pg_aggregate aggform; Form_pg_aggregate aggform;
Type typeInfo;
Oid transfn_oid, Oid transfn_oid,
finalfn_oid; finalfn_oid;
@ -837,23 +837,23 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
/* Fill in the peraggstate data */ /* Fill in the peraggstate data */
peraggstate->aggref = aggref; peraggstate->aggref = aggref;
aggTuple = SearchSysCacheTupleCopy(AGGNAME, aggTuple = SearchSysCache(AGGNAME,
PointerGetDatum(aggname), PointerGetDatum(aggname),
ObjectIdGetDatum(aggref->basetype), ObjectIdGetDatum(aggref->basetype),
0, 0); 0, 0);
if (!HeapTupleIsValid(aggTuple)) if (!HeapTupleIsValid(aggTuple))
elog(ERROR, "ExecAgg: cache lookup failed for aggregate %s(%s)", elog(ERROR, "ExecAgg: cache lookup failed for aggregate %s(%s)",
aggname, aggname,
typeidTypeName(aggref->basetype)); aggref->basetype ?
typeidTypeName(aggref->basetype) : (char *) "");
aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple); aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
typeInfo = typeidType(aggform->aggfinaltype); get_typlenbyval(aggform->aggfinaltype,
peraggstate->resulttypeLen = typeLen(typeInfo); &peraggstate->resulttypeLen,
peraggstate->resulttypeByVal = typeByVal(typeInfo); &peraggstate->resulttypeByVal);
get_typlenbyval(aggform->aggtranstype,
typeInfo = typeidType(aggform->aggtranstype); &peraggstate->transtypeLen,
peraggstate->transtypeLen = typeLen(typeInfo); &peraggstate->transtypeByVal);
peraggstate->transtypeByVal = typeByVal(typeInfo);
peraggstate->initValue = peraggstate->initValue =
AggNameGetInitVal(aggname, AggNameGetInitVal(aggname,
@ -901,23 +901,22 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
Form_pg_operator pgopform; Form_pg_operator pgopform;
peraggstate->inputType = inputType; peraggstate->inputType = inputType;
typeInfo = typeidType(inputType); get_typlenbyval(inputType,
peraggstate->inputtypeLen = typeLen(typeInfo); &peraggstate->inputtypeLen,
peraggstate->inputtypeByVal = typeByVal(typeInfo); &peraggstate->inputtypeByVal);
eq_operator = oper("=", inputType, inputType, true); eq_operator = oper("=", inputType, inputType, true);
if (!HeapTupleIsValid(eq_operator)) if (!HeapTupleIsValid(eq_operator))
{
elog(ERROR, "Unable to identify an equality operator for type '%s'", elog(ERROR, "Unable to identify an equality operator for type '%s'",
typeidTypeName(inputType)); typeidTypeName(inputType));
}
pgopform = (Form_pg_operator) GETSTRUCT(eq_operator); pgopform = (Form_pg_operator) GETSTRUCT(eq_operator);
fmgr_info(pgopform->oprcode, &(peraggstate->equalfn)); fmgr_info(pgopform->oprcode, &(peraggstate->equalfn));
ReleaseSysCache(eq_operator);
peraggstate->sortOperator = any_ordering_op(inputType); peraggstate->sortOperator = any_ordering_op(inputType);
peraggstate->sortstate = NULL; peraggstate->sortstate = NULL;
} }
heap_freetuple(aggTuple); ReleaseSysCache(aggTuple);
} }
return TRUE; return TRUE;

View File

@ -15,7 +15,7 @@
* locate group boundaries. * locate group boundaries.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.38 2000/08/24 03:29:03 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.39 2000/11/16 22:30:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -28,6 +28,8 @@
#include "executor/nodeGroup.h" #include "executor/nodeGroup.h"
#include "parser/parse_oper.h" #include "parser/parse_oper.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
static TupleTableSlot *ExecGroupEveryTuple(Group *node); static TupleTableSlot *ExecGroupEveryTuple(Group *node);
static TupleTableSlot *ExecGroupOneTuple(Group *node); static TupleTableSlot *ExecGroupOneTuple(Group *node);
@ -498,12 +500,11 @@ execTuplesMatchPrepare(TupleDesc tupdesc,
eq_operator = oper("=", typid, typid, true); eq_operator = oper("=", typid, typid, true);
if (!HeapTupleIsValid(eq_operator)) if (!HeapTupleIsValid(eq_operator))
{
elog(ERROR, "Unable to identify an equality operator for type '%s'", elog(ERROR, "Unable to identify an equality operator for type '%s'",
typeidTypeName(typid)); typeidTypeName(typid));
}
pgopform = (Form_pg_operator) GETSTRUCT(eq_operator); pgopform = (Form_pg_operator) GETSTRUCT(eq_operator);
fmgr_info(pgopform->oprcode, &eqfunctions[i]); fmgr_info(pgopform->oprcode, &eqfunctions[i]);
ReleaseSysCache(eq_operator);
} }
return eqfunctions; return eqfunctions;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* *
* $Id: nodeHash.c,v 1.52 2000/08/24 03:29:03 tgl Exp $ * $Id: nodeHash.c,v 1.53 2000/11/16 22:30:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -29,8 +29,8 @@
#include "executor/nodeHashjoin.h" #include "executor/nodeHashjoin.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_type.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/lsyscache.h"
static int hashFunc(Datum key, int len, bool byVal); static int hashFunc(Datum key, int len, bool byVal);
@ -237,7 +237,6 @@ ExecHashTableCreate(Hash *node)
int totalbuckets; int totalbuckets;
int bucketsize; int bucketsize;
int i; int i;
Type typeInfo;
MemoryContext oldcxt; MemoryContext oldcxt;
/* ---------------- /* ----------------
@ -353,9 +352,9 @@ ExecHashTableCreate(Hash *node)
* Get info about the datatype of the hash key. * Get info about the datatype of the hash key.
* ---------------- * ----------------
*/ */
typeInfo = typeidType(exprType(node->hashkey)); get_typlenbyval(exprType(node->hashkey),
hashtable->typByVal = typeByVal(typeInfo); &hashtable->typLen,
hashtable->typLen = typeLen(typeInfo); &hashtable->typByVal);
/* ---------------- /* ----------------
* Create temporary memory contexts in which to keep the hashtable * Create temporary memory contexts in which to keep the hashtable
@ -546,7 +545,9 @@ ExecHashGetBucket(HashJoinTable hashtable,
} }
else else
{ {
bucketno = hashFunc(keyval, hashtable->typLen, hashtable->typByVal) bucketno = hashFunc(keyval,
(int) hashtable->typLen,
hashtable->typByVal)
% hashtable->totalbuckets; % hashtable->totalbuckets;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.38 2000/09/12 21:06:48 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.39 2000/11/16 22:30:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -147,26 +147,29 @@ MJFormSkipQual(List *qualList, char *replaceopname)
* if we search with the actual operand types. * if we search with the actual operand types.
* ---------------- * ----------------
*/ */
optup = get_operator_tuple(op->opno); optup = SearchSysCache(OPEROID,
ObjectIdGetDatum(op->opno),
0, 0, 0);
if (!HeapTupleIsValid(optup)) /* shouldn't happen */ if (!HeapTupleIsValid(optup)) /* shouldn't happen */
elog(ERROR, "MJFormSkipQual: operator %u not found", op->opno); elog(ERROR, "MJFormSkipQual: operator %u not found", op->opno);
opform = (Form_pg_operator) GETSTRUCT(optup); opform = (Form_pg_operator) GETSTRUCT(optup);
oprleft = opform->oprleft; oprleft = opform->oprleft;
oprright = opform->oprright; oprright = opform->oprright;
ReleaseSysCache(optup);
/* ---------------- /* ----------------
* Now look up the matching "<" or ">" operator. If there isn't one, * Now look up the matching "<" or ">" operator. If there isn't one,
* whoever marked the "=" operator mergejoinable was a loser. * whoever marked the "=" operator mergejoinable was a loser.
* ---------------- * ----------------
*/ */
optup = SearchSysCacheTuple(OPERNAME, optup = SearchSysCache(OPERNAME,
PointerGetDatum(replaceopname), PointerGetDatum(replaceopname),
ObjectIdGetDatum(oprleft), ObjectIdGetDatum(oprleft),
ObjectIdGetDatum(oprright), ObjectIdGetDatum(oprright),
CharGetDatum('b')); CharGetDatum('b'));
if (!HeapTupleIsValid(optup)) if (!HeapTupleIsValid(optup))
elog(ERROR, elog(ERROR,
"MJFormSkipQual: mergejoin operator %u has no matching %s op", "MJFormSkipQual: mergejoin operator %u has no matching %s op",
op->opno, replaceopname); op->opno, replaceopname);
opform = (Form_pg_operator) GETSTRUCT(optup); opform = (Form_pg_operator) GETSTRUCT(optup);
@ -177,6 +180,7 @@ MJFormSkipQual(List *qualList, char *replaceopname)
op->opno = optup->t_data->t_oid; op->opno = optup->t_data->t_oid;
op->opid = opform->oprcode; op->opid = opform->oprcode;
op->op_fcache = NULL; op->op_fcache = NULL;
ReleaseSysCache(optup);
} }
return qualCopy; return qualCopy;

View File

@ -3,7 +3,7 @@
* spi.c * spi.c
* Server Programming Interface * Server Programming Interface
* *
* $Id: spi.c,v 1.48 2000/10/26 21:35:15 tgl Exp $ * $Id: spi.c,v 1.49 2000/11/16 22:30:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -447,6 +447,7 @@ char *
SPI_gettype(TupleDesc tupdesc, int fnumber) SPI_gettype(TupleDesc tupdesc, int fnumber)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
char *result;
SPI_result = 0; SPI_result = 0;
if (tupdesc->natts < fnumber || fnumber <= 0) if (tupdesc->natts < fnumber || fnumber <= 0)
@ -455,9 +456,9 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
return NULL; return NULL;
} }
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid), ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
{ {
@ -465,7 +466,9 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
return NULL; return NULL;
} }
return pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname)); result = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
ReleaseSysCache(typeTuple);
return result;
} }
Oid Oid

View File

@ -2,7 +2,6 @@
* *
* dllist.c * dllist.c
* this is a simple doubly linked list implementation * this is a simple doubly linked list implementation
* replaces the old simplelists stuff
* the elements of the lists are void* * the elements of the lists are void*
* *
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
@ -10,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.18 2000/06/08 22:37:05 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.19 2000/11/16 22:30:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -33,25 +32,33 @@ DLNewList(void)
{ {
Dllist *l; Dllist *l;
l = malloc(sizeof(Dllist)); l = (Dllist *) malloc(sizeof(Dllist));
l->dll_head = 0; l->dll_head = 0;
l->dll_tail = 0; l->dll_tail = 0;
return l; return l;
} }
/* free up a list and all the nodes in it --- but *not* whatever the nodes void
DLInitList(Dllist *list)
{
list->dll_head = 0;
list->dll_tail = 0;
}
/*
* free up a list and all the nodes in it --- but *not* whatever the nodes
* might point to! * might point to!
*/ */
void void
DLFreeList(Dllist *l) DLFreeList(Dllist *list)
{ {
Dlelem *curr; Dlelem *curr;
while ((curr = DLRemHead(l)) != 0) while ((curr = DLRemHead(list)) != 0)
free(curr); free(curr);
free(l); free(list);
} }
Dlelem * Dlelem *
@ -59,7 +66,7 @@ DLNewElem(void *val)
{ {
Dlelem *e; Dlelem *e;
e = malloc(sizeof(Dlelem)); e = (Dlelem *) malloc(sizeof(Dlelem));
e->dle_next = 0; e->dle_next = 0;
e->dle_prev = 0; e->dle_prev = 0;
e->dle_val = val; e->dle_val = val;
@ -67,62 +74,21 @@ DLNewElem(void *val)
return e; return e;
} }
void
DLInitElem(Dlelem *e, void *val)
{
e->dle_next = 0;
e->dle_prev = 0;
e->dle_val = val;
e->dle_list = 0;
}
void void
DLFreeElem(Dlelem *e) DLFreeElem(Dlelem *e)
{ {
free(e); free(e);
} }
Dlelem *
DLGetHead(Dllist *l)
{
return l ? l->dll_head : 0;
}
/* get the value stored in the first element */
#ifdef NOT_USED
void *
DLGetHeadVal(Dllist *l)
{
Dlelem *e = DLGetHead(l);
return e ? e->dle_val : 0;
}
#endif
Dlelem *
DLGetTail(Dllist *l)
{
return l ? l->dll_tail : 0;
}
/* get the value stored in the last element */
#ifdef NOT_USED
void *
DLGetTailVal(Dllist *l)
{
Dlelem *e = DLGetTail(l);
return e ? e->dle_val : 0;
}
#endif
#ifdef NOT_USED
Dlelem *
DLGetPred(Dlelem *e) /* get predecessor */
{
return e ? e->dle_prev : 0;
}
#endif
Dlelem *
DLGetSucc(Dlelem *e) /* get successor */
{
return e ? e->dle_next : 0;
}
void void
DLRemove(Dlelem *e) DLRemove(Dlelem *e)
{ {
@ -131,16 +97,16 @@ DLRemove(Dlelem *e)
if (e->dle_prev) if (e->dle_prev)
e->dle_prev->dle_next = e->dle_next; e->dle_prev->dle_next = e->dle_next;
else else
/* must be the head element */
{ {
/* must be the head element */
Assert(e == l->dll_head); Assert(e == l->dll_head);
l->dll_head = e->dle_next; l->dll_head = e->dle_next;
} }
if (e->dle_next) if (e->dle_next)
e->dle_next->dle_prev = e->dle_prev; e->dle_next->dle_prev = e->dle_prev;
else else
/* must be the tail element */
{ {
/* must be the tail element */
Assert(e == l->dll_tail); Assert(e == l->dll_tail);
l->dll_tail = e->dle_prev; l->dll_tail = e->dle_prev;
} }
@ -194,12 +160,12 @@ DLRemHead(Dllist *l)
l->dll_head = result->dle_next; l->dll_head = result->dle_next;
result->dle_next = 0;
result->dle_list = 0;
if (result == l->dll_tail) /* if the head is also the tail */ if (result == l->dll_tail) /* if the head is also the tail */
l->dll_tail = 0; l->dll_tail = 0;
result->dle_next = 0;
result->dle_list = 0;
return result; return result;
} }
@ -217,12 +183,12 @@ DLRemTail(Dllist *l)
l->dll_tail = result->dle_prev; l->dll_tail = result->dle_prev;
result->dle_prev = 0;
result->dle_list = 0;
if (result == l->dll_head) /* if the tail is also the head */ if (result == l->dll_head) /* if the tail is also the head */
l->dll_head = 0; l->dll_head = 0;
result->dle_prev = 0;
result->dle_list = 0;
return result; return result;
} }
@ -241,8 +207,8 @@ DLMoveToFront(Dlelem *e)
if (e->dle_next) if (e->dle_next)
e->dle_next->dle_prev = e->dle_prev; e->dle_next->dle_prev = e->dle_prev;
else else
/* must be the tail element */
{ {
/* must be the tail element */
Assert(e == l->dll_tail); Assert(e == l->dll_tail);
l->dll_tail = e->dle_prev; l->dll_tail = e->dle_prev;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.22 2000/08/08 15:41:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.23 2000/11/16 22:30:23 tgl Exp $
* *
* NOTES * NOTES
* Creator functions in POSTGRES 4.2 are generated automatically. Most of * Creator functions in POSTGRES 4.2 are generated automatically. Most of
@ -20,7 +20,10 @@
* Andrew Yu Oct 20, 1994 file creation * Andrew Yu Oct 20, 1994 file creation
*/ */
#include "postgres.h" #include "postgres.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "utils/lsyscache.h"
/* /*
* makeOper - * makeOper -
@ -143,6 +146,26 @@ makeConst(Oid consttype,
return cnst; return cnst;
} }
/*
* makeNullConst -
* creates a Const node representing a NULL of the specified type
*/
Const *
makeNullConst(Oid consttype)
{
int16 typLen;
bool typByVal;
get_typlenbyval(consttype, &typLen, &typByVal);
return makeConst(consttype,
(int) typLen,
(Datum) 0,
true,
typByVal,
false,
false);
}
/* /*
* makeAttr - * makeAttr -
* creates an Attr node * creates an Attr node

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.133 2000/11/16 05:51:00 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.134 2000/11/16 22:30:23 tgl Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
@ -1236,8 +1236,8 @@ _outJoinInfo(StringInfo str, JoinInfo *node)
static void static void
_outDatum(StringInfo str, Datum value, Oid type) _outDatum(StringInfo str, Datum value, Oid type)
{ {
int16 typeLength;
bool byValue; bool byValue;
int typeLength;
Size length; Size length;
char *s; char *s;
int i; int i;
@ -1246,8 +1246,7 @@ _outDatum(StringInfo str, Datum value, Oid type)
* find some information about the type and the "real" length of the * find some information about the type and the "real" length of the
* datum. * datum.
*/ */
byValue = get_typbyval(type); get_typlenbyval(type, &typeLength, &byValue);
typeLength = get_typlen(type);
length = datumGetSize(value, byValue, typeLength); length = datumGetSize(value, byValue, typeLength);
if (byValue) if (byValue)

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.97 2000/09/29 18:21:32 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.98 2000/11/16 22:30:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -808,9 +808,9 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
bool indexkey_on_left) bool indexkey_on_left)
{ {
Oid expr_op = ((Oper *) clause->oper)->opno; Oid expr_op = ((Oper *) clause->oper)->opno;
Oid commuted_op; Oid commuted_op,
Operator oldop, new_op;
newop; Operator oldoptup;
Form_pg_operator oldopform; Form_pg_operator oldopform;
char *opname; char *opname;
Oid ltype, Oid ltype,
@ -835,13 +835,16 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
* Get the nominal input types of the given operator and the actual * Get the nominal input types of the given operator and the actual
* type (before binary-compatible relabeling) of the index key. * type (before binary-compatible relabeling) of the index key.
*/ */
oldop = get_operator_tuple(expr_op); oldoptup = SearchSysCache(OPEROID,
if (! HeapTupleIsValid(oldop)) ObjectIdGetDatum(expr_op),
0, 0, 0);
if (! HeapTupleIsValid(oldoptup))
return InvalidOid; /* probably can't happen */ return InvalidOid; /* probably can't happen */
oldopform = (Form_pg_operator) GETSTRUCT(oldop); oldopform = (Form_pg_operator) GETSTRUCT(oldoptup);
opname = NameStr(oldopform->oprname); opname = pstrdup(NameStr(oldopform->oprname));
ltype = oldopform->oprleft; ltype = oldopform->oprleft;
rtype = oldopform->oprright; rtype = oldopform->oprright;
ReleaseSysCache(oldoptup);
if (indexkey_on_left) if (indexkey_on_left)
{ {
@ -875,13 +878,11 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
* (In theory this might find a non-semantically-comparable operator, * (In theory this might find a non-semantically-comparable operator,
* but in practice that seems pretty unlikely for binary-compatible types.) * but in practice that seems pretty unlikely for binary-compatible types.)
*/ */
newop = oper(opname, indexkeytype, indexkeytype, TRUE); new_op = oper_oid(opname, indexkeytype, indexkeytype, true);
if (HeapTupleIsValid(newop)) if (OidIsValid(new_op))
{ {
Oid new_expr_op = oprid(newop); if (new_op != expr_op)
if (new_expr_op != expr_op)
{ {
/* /*
@ -889,14 +890,14 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
* name; now does it match the index? * name; now does it match the index?
*/ */
if (indexkey_on_left) if (indexkey_on_left)
commuted_op = new_expr_op; commuted_op = new_op;
else else
commuted_op = get_commutator(new_expr_op); commuted_op = get_commutator(new_op);
if (commuted_op == InvalidOid) if (commuted_op == InvalidOid)
return InvalidOid; return InvalidOid;
if (op_class(commuted_op, opclass, relam)) if (op_class(commuted_op, opclass, relam))
return new_expr_op; return new_op;
} }
} }
@ -2079,16 +2080,11 @@ prefix_quals(Var *leftop, Oid expr_op,
static Oid static Oid
find_operator(const char *opname, Oid datatype) find_operator(const char *opname, Oid datatype)
{ {
HeapTuple optup; return GetSysCacheOid(OPERNAME,
PointerGetDatum(opname),
optup = SearchSysCacheTuple(OPERNAME, ObjectIdGetDatum(datatype),
PointerGetDatum(opname), ObjectIdGetDatum(datatype),
ObjectIdGetDatum(datatype), CharGetDatum('b'));
ObjectIdGetDatum(datatype),
CharGetDatum('b'));
if (!HeapTupleIsValid(optup))
return InvalidOid;
return optup->t_data->t_oid;
} }
/* /*

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.100 2000/11/12 00:36:58 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.101 2000/11/16 22:30:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -396,17 +396,19 @@ create_indexscan_plan(Query *root,
HeapTuple indexTuple; HeapTuple indexTuple;
Form_pg_index index; Form_pg_index index;
indexTuple = SearchSysCacheTuple(INDEXRELID, indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(lfirsti(ixid)), ObjectIdGetDatum(lfirsti(ixid)),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "create_plan: index %u not found", lfirsti(ixid)); elog(ERROR, "create_plan: index %u not found", lfirsti(ixid));
index = (Form_pg_index) GETSTRUCT(indexTuple); index = (Form_pg_index) GETSTRUCT(indexTuple);
if (index->indislossy) if (index->indislossy)
{ {
lossy = true; lossy = true;
ReleaseSysCache(indexTuple);
break; break;
} }
ReleaseSysCache(indexTuple);
} }
/* /*
@ -904,18 +906,19 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path)
Form_pg_index index; Form_pg_index index;
/* Get the relam from the index's pg_class entry */ /* Get the relam from the index's pg_class entry */
indexTuple = SearchSysCacheTuple(RELOID, indexTuple = SearchSysCache(RELOID,
ObjectIdGetDatum(indexid), ObjectIdGetDatum(indexid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "fix_indxqual_references: index %u not found in pg_class", elog(ERROR, "fix_indxqual_references: index %u not found in pg_class",
indexid); indexid);
relam = ((Form_pg_class) GETSTRUCT(indexTuple))->relam; relam = ((Form_pg_class) GETSTRUCT(indexTuple))->relam;
ReleaseSysCache(indexTuple);
/* Need the index's pg_index entry for other stuff */ /* Need the index's pg_index entry for other stuff */
indexTuple = SearchSysCacheTuple(INDEXRELID, indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexid), ObjectIdGetDatum(indexid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "fix_indxqual_references: index %u not found in pg_index", elog(ERROR, "fix_indxqual_references: index %u not found in pg_index",
indexid); indexid);
@ -927,6 +930,8 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path)
relam, relam,
index)); index));
ReleaseSysCache(indexTuple);
indexids = lnext(indexids); indexids = lnext(indexids);
} }
return fixed_quals; return fixed_quals;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.51 2000/09/29 18:21:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.52 2000/11/16 22:30:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -31,6 +31,7 @@
#include "parser/parse_oper.h" #include "parser/parse_oper.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/syscache.h"
static void mark_baserels_for_outer_join(Query *root, Relids rels, static void mark_baserels_for_outer_join(Query *root, Relids rels,
@ -636,6 +637,8 @@ process_implied_equality(Query *root, Node *item1, Node *item2,
BOOLOID); /* operator result type */ BOOLOID); /* operator result type */
clause->args = makeList2(item1, item2); clause->args = makeList2(item1, item2);
ReleaseSysCache(eq_operator);
/* /*
* Note: we mark the qual "pushed down" to ensure that it can never be * Note: we mark the qual "pushed down" to ensure that it can never be
* taken for an original JOIN/ON clause. We also claim it is an outer- * taken for an original JOIN/ON clause. We also claim it is an outer-

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.44 2000/10/26 21:36:09 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.45 2000/11/16 22:30:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -23,7 +23,7 @@
#include "optimizer/subselect.h" #include "optimizer/subselect.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_oper.h" #include "parser/parse_oper.h"
#include "utils/lsyscache.h" #include "utils/syscache.h"
Index PlannerQueryLevel; /* level of current query */ Index PlannerQueryLevel; /* level of current query */
@ -271,8 +271,11 @@ make_subplan(SubLink *slink)
pfree(var); /* var is only needed for new_param */ pfree(var); /* var is only needed for new_param */
Assert(IsA(oper, Oper)); Assert(IsA(oper, Oper));
tup = get_operator_tuple(oper->opno); tup = SearchSysCache(OPEROID,
Assert(HeapTupleIsValid(tup)); ObjectIdGetDatum(oper->opno),
0, 0, 0);
if (! HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for operator %u", oper->opno);
opform = (Form_pg_operator) GETSTRUCT(tup); opform = (Form_pg_operator) GETSTRUCT(tup);
/* /*
@ -283,6 +286,8 @@ make_subplan(SubLink *slink)
exprType(lefthand), opform->oprleft); exprType(lefthand), opform->oprleft);
right = make_operand("", (Node *) prm, right = make_operand("", (Node *) prm,
prm->paramtype, opform->oprright); prm->paramtype, opform->oprright);
ReleaseSysCache(tup);
newoper = lappend(newoper, newoper = lappend(newoper,
make_opclause(oper, make_opclause(oper,
(Var *) left, (Var *) left,
@ -401,15 +406,14 @@ make_subplan(SubLink *slink)
Node *left, Node *left,
*right; *right;
/* con = makeNullConst(te->resdom->restype);
* XXX really ought to fill in constlen and constbyval
* correctly, but right now ExecEvalExpr won't look at them...
*/
con = makeConst(te->resdom->restype, 0, 0, true, 0, 0, 0);
Assert(IsA(oper, Oper)); Assert(IsA(oper, Oper));
tup = get_operator_tuple(oper->opno); tup = SearchSysCache(OPEROID,
Assert(HeapTupleIsValid(tup)); ObjectIdGetDatum(oper->opno),
0, 0, 0);
if (! HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for operator %u", oper->opno);
opform = (Form_pg_operator) GETSTRUCT(tup); opform = (Form_pg_operator) GETSTRUCT(tup);
/* /*
@ -420,6 +424,8 @@ make_subplan(SubLink *slink)
exprType(lefthand), opform->oprleft); exprType(lefthand), opform->oprleft);
right = make_operand("", (Node *) con, right = make_operand("", (Node *) con,
con->consttype, opform->oprright); con->consttype, opform->oprright);
ReleaseSysCache(tup);
newoper = lappend(newoper, newoper = lappend(newoper,
make_opclause(oper, make_opclause(oper,
(Var *) left, (Var *) left,

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.39 2000/10/05 19:11:30 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.40 2000/11/16 22:30:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -238,14 +238,7 @@ expand_targetlist(List *tlist, int command_type,
#ifdef _DROP_COLUMN_HACK__ #ifdef _DROP_COLUMN_HACK__
if (COLUMN_IS_DROPPED(att_tup)) if (COLUMN_IS_DROPPED(att_tup))
{ temp_var = (Var *) makeNullConst(atttype);
temp_var = (Var *) makeConst(atttype, 0,
PointerGetDatum(NULL),
true,
false,
false, /* not a set */
false);
}
else else
#endif /* _DROP_COLUMN_HACK__ */ #endif /* _DROP_COLUMN_HACK__ */
temp_var = makeVar(result_relation, temp_var = makeVar(result_relation,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.77 2000/10/05 19:11:32 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.78 2000/11/16 22:30:26 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -28,7 +28,6 @@
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h" #include "optimizer/var.h"
#include "parser/parse_type.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "utils/datum.h" #include "utils/datum.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
@ -995,7 +994,8 @@ get_rels_atts(Node *clause,
void void
CommuteClause(Expr *clause) CommuteClause(Expr *clause)
{ {
HeapTuple heapTup; Oid opoid;
HeapTuple optup;
Form_pg_operator commuTup; Form_pg_operator commuTup;
Oper *commu; Oper *commu;
Node *temp; Node *temp;
@ -1004,19 +1004,22 @@ CommuteClause(Expr *clause)
length(clause->args) != 2) length(clause->args) != 2)
elog(ERROR, "CommuteClause: applied to non-binary-operator clause"); elog(ERROR, "CommuteClause: applied to non-binary-operator clause");
heapTup = (HeapTuple) opoid = ((Oper *) clause->oper)->opno;
get_operator_tuple(get_commutator(((Oper *) clause->oper)->opno));
if (heapTup == (HeapTuple) NULL) optup = SearchSysCache(OPEROID,
elog(ERROR, "CommuteClause: no commutator for operator %u", ObjectIdGetDatum(get_commutator(opoid)),
((Oper *) clause->oper)->opno); 0, 0, 0);
if (!HeapTupleIsValid(optup))
elog(ERROR, "CommuteClause: no commutator for operator %u", opoid);
commuTup = (Form_pg_operator) GETSTRUCT(heapTup); commuTup = (Form_pg_operator) GETSTRUCT(optup);
commu = makeOper(heapTup->t_data->t_oid, commu = makeOper(optup->t_data->t_oid,
commuTup->oprcode, commuTup->oprcode,
commuTup->oprresult); commuTup->oprresult);
ReleaseSysCache(optup);
/* /*
* re-form the clause in-place! * re-form the clause in-place!
*/ */
@ -1434,9 +1437,11 @@ simplify_op_or_func(Expr *expr, List *args)
Oid result_typeid; Oid result_typeid;
HeapTuple func_tuple; HeapTuple func_tuple;
Form_pg_proc funcform; Form_pg_proc funcform;
Type resultType; bool proiscachable;
bool proisstrict;
bool proretset;
int16 resultTypLen;
bool resultTypByVal; bool resultTypByVal;
int resultTypLen;
Expr *newexpr; Expr *newexpr;
ExprContext *econtext; ExprContext *econtext;
Datum const_val; Datum const_val;
@ -1491,36 +1496,37 @@ simplify_op_or_func(Expr *expr, List *args)
* we could use func_iscachable() here, but we need several fields * we could use func_iscachable() here, but we need several fields
* out of the func tuple, so might as well just look it up once. * out of the func tuple, so might as well just look it up once.
*/ */
func_tuple = SearchSysCacheTuple(PROCOID, func_tuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcid), ObjectIdGetDatum(funcid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(func_tuple)) if (!HeapTupleIsValid(func_tuple))
elog(ERROR, "Function OID %u does not exist", funcid); elog(ERROR, "Function OID %u does not exist", funcid);
funcform = (Form_pg_proc) GETSTRUCT(func_tuple); funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
if (!funcform->proiscachable) proiscachable = funcform->proiscachable;
proisstrict = funcform->proisstrict;
proretset = funcform->proretset;
ReleaseSysCache(func_tuple);
if (!proiscachable)
return NULL; return NULL;
/* /*
* Also check to make sure it doesn't return a set. * Also check to make sure it doesn't return a set.
*/ */
if (funcform->proretset) if (proretset)
return NULL; return NULL;
/* /*
* Now that we know if the function is strict, we can finish the * Now that we know if the function is strict, we can finish the
* checks for simplifiable inputs that we started above. * checks for simplifiable inputs that we started above.
*/ */
if (funcform->proisstrict && has_null_input) if (proisstrict && has_null_input)
{ {
/* /*
* It's strict and has NULL input, so must produce NULL output. * It's strict and has NULL input, so must produce NULL output.
* Return a NULL constant of the right type. * Return a NULL constant of the right type.
*/ */
resultType = typeidType(result_typeid); return (Expr *) makeNullConst(result_typeid);
return (Expr *) makeConst(result_typeid, typeLen(resultType),
(Datum) 0, true,
typeByVal(resultType),
false, false);
} }
/* /*
@ -1548,9 +1554,7 @@ simplify_op_or_func(Expr *expr, List *args)
newexpr->args = args; newexpr->args = args;
/* Get info needed about result datatype */ /* Get info needed about result datatype */
resultType = typeidType(result_typeid); get_typlenbyval(result_typeid, &resultTypLen, &resultTypByVal);
resultTypByVal = typeByVal(resultType);
resultTypLen = typeLen(resultType);
/* /*
* It is OK to pass a dummy econtext because none of the ExecEvalExpr() * It is OK to pass a dummy econtext because none of the ExecEvalExpr()

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.61 2000/09/29 18:21:23 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.62 2000/11/16 22:30:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -48,9 +48,9 @@ relation_info(Oid relationObjectId,
HeapTuple relationTuple; HeapTuple relationTuple;
Form_pg_class relation; Form_pg_class relation;
relationTuple = SearchSysCacheTuple(RELOID, relationTuple = SearchSysCache(RELOID,
ObjectIdGetDatum(relationObjectId), ObjectIdGetDatum(relationObjectId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(relationTuple)) if (!HeapTupleIsValid(relationTuple))
elog(ERROR, "relation_info: Relation %u not found", elog(ERROR, "relation_info: Relation %u not found",
relationObjectId); relationObjectId);
@ -62,6 +62,7 @@ relation_info(Oid relationObjectId,
*hasindex = (relation->relhasindex) ? true : false; *hasindex = (relation->relhasindex) ? true : false;
*pages = relation->relpages; *pages = relation->relpages;
*tuples = relation->reltuples; *tuples = relation->reltuples;
ReleaseSysCache(relationTuple);
} }
/* /*
@ -100,9 +101,9 @@ find_secondary_indexes(Oid relationObjectId)
Oid relam; Oid relam;
uint16 amorderstrategy; uint16 amorderstrategy;
indexTuple = SearchSysCacheTupleCopy(INDEXRELID, indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexoid), ObjectIdGetDatum(indexoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "find_secondary_indexes: index %u not found", elog(ERROR, "find_secondary_indexes: index %u not found",
indexoid); indexoid);
@ -162,20 +163,22 @@ find_secondary_indexes(Oid relationObjectId)
Form_pg_amop amop; Form_pg_amop amop;
amopTuple = amopTuple =
SearchSysCacheTuple(AMOPSTRATEGY, SearchSysCache(AMOPSTRATEGY,
ObjectIdGetDatum(relam), ObjectIdGetDatum(relam),
ObjectIdGetDatum(index->indclass[i]), ObjectIdGetDatum(index->indclass[i]),
UInt16GetDatum(amorderstrategy), UInt16GetDatum(amorderstrategy),
0); 0);
if (!HeapTupleIsValid(amopTuple)) if (!HeapTupleIsValid(amopTuple))
elog(ERROR, "find_secondary_indexes: no amop %u %u %d", elog(ERROR, "find_secondary_indexes: no amop %u %u %d",
relam, index->indclass[i], (int) amorderstrategy); relam, index->indclass[i],
(int) amorderstrategy);
amop = (Form_pg_amop) GETSTRUCT(amopTuple); amop = (Form_pg_amop) GETSTRUCT(amopTuple);
info->ordering[i] = amop->amopopr; info->ordering[i] = amop->amopopr;
ReleaseSysCache(amopTuple);
} }
} }
heap_freetuple(indexTuple); ReleaseSysCache(indexTuple);
indexinfos = lcons(info, indexinfos); indexinfos = lcons(info, indexinfos);
} }
@ -315,13 +318,16 @@ find_inheritance_children(Oid inhparent)
bool bool
has_subclass(Oid relationId) has_subclass(Oid relationId)
{ {
HeapTuple tuple = HeapTuple tuple;
SearchSysCacheTuple(RELOID, bool result;
ObjectIdGetDatum(relationId),
0, 0, 0);
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(relationId),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "has_subclass: Relation %u not found", elog(ERROR, "has_subclass: Relation %u not found", relationId);
relationId);
return ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass; result = ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass;
ReleaseSysCache(tuple);
return result;
} }

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: analyze.c,v 1.165 2000/11/08 22:09:58 tgl Exp $ * $Id: analyze.c,v 1.166 2000/11/16 22:30:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -2598,9 +2598,8 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
Form_pg_attribute *pkrel_attrs; Form_pg_attribute *pkrel_attrs;
List *indexoidlist, List *indexoidlist,
*indexoidscan; *indexoidscan;
Form_pg_index indexStruct = NULL;
int i; int i;
int found=0; bool found = false;
/* ---------- /* ----------
* Open the referenced table and get the attributes list * Open the referenced table and get the attributes list
@ -2616,7 +2615,7 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
* Get the list of index OIDs for the table from the relcache, * Get the list of index OIDs for the table from the relcache,
* and look up each one in the pg_index syscache for each unique * and look up each one in the pg_index syscache for each unique
* one, and then compare the attributes we were given to those * one, and then compare the attributes we were given to those
* defined. * defined.
* ---------- * ----------
*/ */
indexoidlist = RelationGetIndexList(pkrel); indexoidlist = RelationGetIndexList(pkrel);
@ -2625,27 +2624,34 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
{ {
Oid indexoid = lfirsti(indexoidscan); Oid indexoid = lfirsti(indexoidscan);
HeapTuple indexTuple; HeapTuple indexTuple;
List *attrl; Form_pg_index indexStruct;
indexTuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(indexoid), indexTuple = SearchSysCache(INDEXRELID,
0, 0, 0); ObjectIdGetDatum(indexoid),
0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found", elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
indexoid); indexoid);
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple); indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
if (indexStruct->indisunique) { if (indexStruct->indisunique)
{
List *attrl;
/* go through the fkconstraint->pk_attrs list */ /* go through the fkconstraint->pk_attrs list */
foreach(attrl, fkconstraint->pk_attrs) { foreach(attrl, fkconstraint->pk_attrs)
{
Ident *attr=lfirst(attrl); Ident *attr=lfirst(attrl);
found=0; found = false;
for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++) for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
{ {
int pkattno = indexStruct->indkey[i]; int pkattno = indexStruct->indkey[i];
if (pkattno>0) { if (pkattno>0)
{
char *name = NameStr(pkrel_attrs[pkattno - 1]->attname); char *name = NameStr(pkrel_attrs[pkattno - 1]->attname);
if (strcmp(name, attr->name)==0) { if (strcmp(name, attr->name)==0)
found=1; {
found = true;
break; break;
} }
} }
@ -2654,9 +2660,9 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
break; break;
} }
} }
ReleaseSysCache(indexTuple);
if (found) if (found)
break; break;
indexStruct = NULL;
} }
if (!found) if (!found)
elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found", elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
@ -2681,6 +2687,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint)
Form_pg_attribute *pkrel_attrs; Form_pg_attribute *pkrel_attrs;
List *indexoidlist, List *indexoidlist,
*indexoidscan; *indexoidscan;
HeapTuple indexTuple = NULL;
Form_pg_index indexStruct = NULL; Form_pg_index indexStruct = NULL;
int i; int i;
@ -2705,17 +2712,17 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint)
foreach(indexoidscan, indexoidlist) foreach(indexoidscan, indexoidlist)
{ {
Oid indexoid = lfirsti(indexoidscan); Oid indexoid = lfirsti(indexoidscan);
HeapTuple indexTuple;
indexTuple = SearchSysCacheTuple(INDEXRELID, indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexoid), ObjectIdGetDatum(indexoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found", elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
indexoid); indexoid);
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple); indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
if (indexStruct->indisprimary) if (indexStruct->indisprimary)
break; break;
ReleaseSysCache(indexTuple);
indexStruct = NULL; indexStruct = NULL;
} }
@ -2747,6 +2754,8 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint)
fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr); fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr);
} }
ReleaseSysCache(indexTuple);
heap_close(pkrel, AccessShareLock); heap_close(pkrel, AccessShareLock);
} }
@ -2861,6 +2870,7 @@ static void
transformColumnType(ParseState *pstate, ColumnDef *column) transformColumnType(ParseState *pstate, ColumnDef *column)
{ {
TypeName *typename = column->typename; TypeName *typename = column->typename;
Type ctype = typenameType(typename->name);
/* /*
* If the column doesn't have an explicitly specified typmod, check to * If the column doesn't have an explicitly specified typmod, check to
@ -2871,7 +2881,7 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
*/ */
if (typename->typmod == -1) if (typename->typmod == -1)
{ {
switch (typeTypeId(typenameType(typename->name))) switch (typeTypeId(ctype))
{ {
case BPCHAROID: case BPCHAROID:
/* "char" -> "char(1)" */ /* "char" -> "char(1)" */
@ -2891,11 +2901,13 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
* XXX this is a hangover from ancient Berkeley code that probably * XXX this is a hangover from ancient Berkeley code that probably
* doesn't work anymore anyway. * doesn't work anymore anyway.
*/ */
if (typeTypeRelid(typenameType(typename->name)) != InvalidOid) if (typeTypeRelid(ctype) != InvalidOid)
{ {
/* (Eventually add in here that the set can only /* (Eventually add in here that the set can only
* contain one element.) * contain one element.)
*/ */
typename->setof = true; typename->setof = true;
} }
ReleaseSysCache(ctype);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.42 2000/09/29 18:21:36 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.43 2000/11/16 22:30:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -190,18 +190,18 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
List *args, bool agg_star, bool agg_distinct, List *args, bool agg_star, bool agg_distinct,
int precedence) int precedence)
{ {
HeapTuple theAggTuple; HeapTuple aggtuple;
Form_pg_aggregate aggform; Form_pg_aggregate aggform;
Aggref *aggref; Aggref *aggref;
theAggTuple = SearchSysCacheTuple(AGGNAME, aggtuple = SearchSysCache(AGGNAME,
PointerGetDatum(aggname), PointerGetDatum(aggname),
ObjectIdGetDatum(basetype), ObjectIdGetDatum(basetype),
0, 0); 0, 0);
/* shouldn't happen --- caller should have checked already */ /* shouldn't happen --- caller should have checked already */
if (!HeapTupleIsValid(theAggTuple)) if (!HeapTupleIsValid(aggtuple))
agg_error("ParseAgg", aggname, basetype); agg_error("ParseAgg", aggname, basetype);
aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple); aggform = (Form_pg_aggregate) GETSTRUCT(aggtuple);
/* /*
* There used to be a really ugly hack for count(*) here. * There used to be a really ugly hack for count(*) here.
@ -225,6 +225,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
aggref->aggstar = agg_star; aggref->aggstar = agg_star;
aggref->aggdistinct = agg_distinct; aggref->aggdistinct = agg_distinct;
ReleaseSysCache(aggtuple);
pstate->p_hasAggs = true; pstate->p_hasAggs = true;
return aggref; return aggref;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.72 2000/11/12 00:37:00 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.73 2000/11/16 22:30:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -953,9 +953,7 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist); grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
grpcl->sortop = oprid(oper("<", grpcl->sortop = any_ordering_op(tle->resdom->restype);
tle->resdom->restype,
tle->resdom->restype, false));
glist = lappend(glist, grpcl); glist = lappend(glist, grpcl);
} }
@ -1151,9 +1149,10 @@ addTargetToSortList(TargetEntry *tle, List *sortlist, List *targetlist,
sortcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist); sortcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
if (opname) if (opname)
sortcl->sortop = oprid(oper(opname, sortcl->sortop = oper_oid(opname,
tle->resdom->restype, tle->resdom->restype,
tle->resdom->restype, false)); tle->resdom->restype,
false);
else else
sortcl->sortop = any_ordering_op(tle->resdom->restype); sortcl->sortop = any_ordering_op(tle->resdom->restype);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.48 2000/11/09 04:14:32 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.49 2000/11/16 22:30:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -84,6 +84,8 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
pfree(val); pfree(val);
} }
ReleaseSysCache(targetType);
result = (Node *) newcon; result = (Node *) newcon;
} }
else if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId)) else if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId))
@ -124,9 +126,8 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
* conversion function. * conversion function.
*/ */
FuncCall *n = makeNode(FuncCall); FuncCall *n = makeNode(FuncCall);
Type targetType = typeidType(targetTypeId);
n->funcname = typeTypeName(targetType); n->funcname = typeidTypeName(targetTypeId);
n->args = lcons(node, NIL); n->args = lcons(node, NIL);
n->agg_star = false; n->agg_star = false;
n->agg_distinct = false; n->agg_distinct = false;
@ -136,7 +137,7 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
/* safety check that we got the right thing */ /* safety check that we got the right thing */
if (exprType(result) != targetTypeId) if (exprType(result) != targetTypeId)
elog(ERROR, "coerce_type: conversion function %s produced %s", elog(ERROR, "coerce_type: conversion function %s produced %s",
typeTypeName(targetType), typeidTypeName(targetTypeId),
typeidTypeName(exprType(result))); typeidTypeName(exprType(result)));
/* /*
@ -233,17 +234,21 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
oid_array[0] = inputTypeId; oid_array[0] = inputTypeId;
ftup = SearchSysCacheTuple(PROCNAME, ftup = SearchSysCache(PROCNAME,
PointerGetDatum(typeidTypeName(targetTypeId)), PointerGetDatum(typeidTypeName(targetTypeId)),
Int32GetDatum(1), Int32GetDatum(1),
PointerGetDatum(oid_array), PointerGetDatum(oid_array),
0); 0);
if (!HeapTupleIsValid(ftup)) if (!HeapTupleIsValid(ftup))
return false; return false;
/* Make sure the function's result type is as expected, too */ /* Make sure the function's result type is as expected, too */
pform = (Form_pg_proc) GETSTRUCT(ftup); pform = (Form_pg_proc) GETSTRUCT(ftup);
if (pform->prorettype != targetTypeId) if (pform->prorettype != targetTypeId)
{
ReleaseSysCache(ftup);
return false; return false;
}
ReleaseSysCache(ftup);
} }
return true; return true;
@ -272,7 +277,6 @@ coerce_type_typmod(ParseState *pstate, Node *node,
{ {
char *funcname; char *funcname;
Oid oid_array[FUNC_MAX_ARGS]; Oid oid_array[FUNC_MAX_ARGS];
HeapTuple ftup;
/* /*
* We assume that only typmod values greater than 0 indicate a forced * We assume that only typmod values greater than 0 indicate a forced
@ -288,13 +292,11 @@ coerce_type_typmod(ParseState *pstate, Node *node,
oid_array[1] = INT4OID; oid_array[1] = INT4OID;
/* attempt to find with arguments exactly as specified... */ /* attempt to find with arguments exactly as specified... */
ftup = SearchSysCacheTuple(PROCNAME, if (SearchSysCacheExists(PROCNAME,
PointerGetDatum(funcname), PointerGetDatum(funcname),
Int32GetDatum(2), Int32GetDatum(2),
PointerGetDatum(oid_array), PointerGetDatum(oid_array),
0); 0))
if (HeapTupleIsValid(ftup))
{ {
A_Const *cons = makeNode(A_Const); A_Const *cons = makeNode(A_Const);
FuncCall *func = makeNode(FuncCall); FuncCall *func = makeNode(FuncCall);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.87 2000/11/16 17:27:10 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.88 2000/11/16 22:30:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -386,7 +386,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
optup = oper(op, optup = oper(op,
exprType(lexpr), exprType(lexpr),
exprType(tent->expr), exprType(tent->expr),
FALSE); false);
opform = (Form_pg_operator) GETSTRUCT(optup); opform = (Form_pg_operator) GETSTRUCT(optup);
if (opform->oprresult != BOOLOID) if (opform->oprresult != BOOLOID)
@ -399,6 +399,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
InvalidOid, /* opid */ InvalidOid, /* opid */
opform->oprresult); opform->oprresult);
sublink->oper = lappend(sublink->oper, newop); sublink->oper = lappend(sublink->oper, newop);
ReleaseSysCache(optup);
} }
if (left_list != NIL) if (left_list != NIL)
elog(ERROR, "Subselect has too few fields"); elog(ERROR, "Subselect has too few fields");
@ -740,7 +741,8 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
{ {
Func *func; Func *func;
Const *second_arg; Const *second_arg;
HeapTuple tup; HeapTuple procTuple;
HeapTuple typeTuple;
Form_pg_proc procStruct; Form_pg_proc procStruct;
Form_pg_type typeStruct; Form_pg_type typeStruct;
@ -771,12 +773,12 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
/* /*
* Lookup the function in pg_proc * Lookup the function in pg_proc
*/ */
tup = SearchSysCacheTuple(PROCOID, procTuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(func->funcid), ObjectIdGetDatum(func->funcid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(procTuple))
elog(ERROR, "cache lookup for proc %u failed", func->funcid); elog(ERROR, "cache lookup for proc %u failed", func->funcid);
procStruct = (Form_pg_proc) GETSTRUCT(tup); procStruct = (Form_pg_proc) GETSTRUCT(procTuple);
/* /*
* It must be a function with two arguments where the first is of the * It must be a function with two arguments where the first is of the
@ -787,29 +789,39 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
procStruct->prorettype != procStruct->proargtypes[0] || procStruct->prorettype != procStruct->proargtypes[0] ||
procStruct->proargtypes[1] != INT4OID || procStruct->proargtypes[1] != INT4OID ||
procStruct->prorettype != ((Expr *) expr)->typeOid) procStruct->prorettype != ((Expr *) expr)->typeOid)
{
ReleaseSysCache(procTuple);
return false; return false;
}
/* /*
* Furthermore, the name of the function must be the same as the * Furthermore, the name of the function must be the same as the
* argument/result type's name. * argument/result type's name.
*/ */
tup = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->prorettype), ObjectIdGetDatum(procStruct->prorettype),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "cache lookup for type %u failed", elog(ERROR, "cache lookup for type %u failed",
procStruct->prorettype); procStruct->prorettype);
typeStruct = (Form_pg_type) GETSTRUCT(tup); typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
if (strncmp(NameStr(procStruct->proname), if (strncmp(NameStr(procStruct->proname),
NameStr(typeStruct->typname), NameStr(typeStruct->typname),
NAMEDATALEN) != 0) NAMEDATALEN) != 0)
{
ReleaseSysCache(procTuple);
ReleaseSysCache(typeTuple);
return false; return false;
}
/* /*
* OK, it is indeed a length-coercion function. * OK, it is indeed a length-coercion function.
*/ */
if (coercedTypmod != NULL) if (coercedTypmod != NULL)
*coercedTypmod = DatumGetInt32(second_arg->constvalue); *coercedTypmod = DatumGetInt32(second_arg->constvalue);
ReleaseSysCache(procTuple);
ReleaseSysCache(typeTuple);
return true; return true;
} }
@ -865,6 +877,8 @@ parser_typecast_constant(Value *expr, TypeName *typename)
if (string_palloced) if (string_palloced)
pfree(const_string); pfree(const_string);
ReleaseSysCache(tp);
return (Node *) con; return (Node *) con;
} }
@ -881,11 +895,9 @@ parser_typecast_expression(ParseState *pstate,
Node *expr, TypeName *typename) Node *expr, TypeName *typename)
{ {
Oid inputType = exprType(expr); Oid inputType = exprType(expr);
Type tp;
Oid targetType; Oid targetType;
tp = typenameType(TypeNameToInternalName(typename)); targetType = typenameTypeId(TypeNameToInternalName(typename));
targetType = typeTypeId(tp);
if (inputType == InvalidOid) if (inputType == InvalidOid)
return expr; /* do nothing if NULL input */ return expr; /* do nothing if NULL input */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.93 2000/11/11 19:49:26 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.94 2000/11/16 22:30:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -354,19 +354,19 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
CandidateList candidates; CandidateList candidates;
/* try for exact match first... */ /* try for exact match first... */
if (SearchSysCacheTuple(AGGNAME, if (SearchSysCacheExists(AGGNAME,
PointerGetDatum(funcname), PointerGetDatum(funcname),
ObjectIdGetDatum(basetype), ObjectIdGetDatum(basetype),
0, 0)) 0, 0))
return (Node *) ParseAgg(pstate, funcname, basetype, return (Node *) ParseAgg(pstate, funcname, basetype,
fargs, agg_star, agg_distinct, fargs, agg_star, agg_distinct,
precedence); precedence);
/* check for aggregate-that-accepts-any-type (eg, COUNT) */ /* check for aggregate-that-accepts-any-type (eg, COUNT) */
if (SearchSysCacheTuple(AGGNAME, if (SearchSysCacheExists(AGGNAME,
PointerGetDatum(funcname), PointerGetDatum(funcname),
ObjectIdGetDatum(0), ObjectIdGetDatum(0),
0, 0)) 0, 0))
return (Node *) ParseAgg(pstate, funcname, 0, return (Node *) ParseAgg(pstate, funcname, 0,
fargs, agg_star, agg_distinct, fargs, agg_star, agg_distinct,
precedence); precedence);
@ -450,7 +450,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
if (rte->relname == NULL) if (rte->relname == NULL)
elog(ERROR, elog(ERROR,
"function applied to tuple is not supported for subSELECTs"); "function applied to tuple is not supported for subSELECTs");
toid = typeTypeId(typenameType(rte->relname)); toid = typenameTypeId(rte->relname);
/* replace it in the arg list */ /* replace it in the arg list */
lfirst(i) = makeVar(vnum, 0, toid, -1, sublevels_up); lfirst(i) = makeVar(vnum, 0, toid, -1, sublevels_up);
@ -531,15 +531,14 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
*/ */
if (nargs == 1) if (nargs == 1)
{ {
Type tp; Oid targetType;
tp = SearchSysCacheTuple(TYPENAME, targetType = GetSysCacheOid(TYPENAME,
PointerGetDatum(funcname), PointerGetDatum(funcname),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (OidIsValid(targetType))
{ {
Oid sourceType = oid_array[0]; Oid sourceType = oid_array[0];
Oid targetType = typeTypeId(tp);
Node *arg1 = lfirst(fargs); Node *arg1 = lfirst(fargs);
if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) || if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) ||
@ -573,6 +572,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
if (typeTypeFlag(tp) == 'c') if (typeTypeFlag(tp) == 'c')
elog(ERROR, "No such attribute or function '%s'", elog(ERROR, "No such attribute or function '%s'",
funcname); funcname);
ReleaseSysCache(tp);
} }
/* Else generate a detailed complaint */ /* Else generate a detailed complaint */
@ -1037,11 +1037,11 @@ func_get_detail(char *funcname,
HeapTuple ftup; HeapTuple ftup;
/* attempt to find with arguments exactly as specified... */ /* attempt to find with arguments exactly as specified... */
ftup = SearchSysCacheTuple(PROCNAME, ftup = SearchSysCache(PROCNAME,
PointerGetDatum(funcname), PointerGetDatum(funcname),
Int32GetDatum(nargs), Int32GetDatum(nargs),
PointerGetDatum(argtypes), PointerGetDatum(argtypes),
0); 0);
if (HeapTupleIsValid(ftup)) if (HeapTupleIsValid(ftup))
{ {
@ -1085,11 +1085,11 @@ func_get_detail(char *funcname,
if (ncandidates == 1) if (ncandidates == 1)
{ {
*true_typeids = current_function_typeids->args; *true_typeids = current_function_typeids->args;
ftup = SearchSysCacheTuple(PROCNAME, ftup = SearchSysCache(PROCNAME,
PointerGetDatum(funcname), PointerGetDatum(funcname),
Int32GetDatum(nargs), Int32GetDatum(nargs),
PointerGetDatum(*true_typeids), PointerGetDatum(*true_typeids),
0); 0);
Assert(HeapTupleIsValid(ftup)); Assert(HeapTupleIsValid(ftup));
break; break;
} }
@ -1107,12 +1107,13 @@ func_get_detail(char *funcname,
if (*true_typeids != NULL) if (*true_typeids != NULL)
{ {
/* was able to choose a best candidate */ /* was able to choose a best candidate */
ftup = SearchSysCacheTuple(PROCNAME, ftup = SearchSysCache(PROCNAME,
PointerGetDatum(funcname), PointerGetDatum(funcname),
Int32GetDatum(nargs), Int32GetDatum(nargs),
PointerGetDatum(*true_typeids), PointerGetDatum(*true_typeids),
0); 0);
Assert(HeapTupleIsValid(ftup)); Assert(HeapTupleIsValid(ftup));
break;
} }
/* /*
@ -1143,6 +1144,7 @@ func_get_detail(char *funcname,
*funcid = ftup->t_data->t_oid; *funcid = ftup->t_data->t_oid;
*rettype = pform->prorettype; *rettype = pform->prorettype;
*retset = pform->proretset; *retset = pform->proretset;
ReleaseSysCache(ftup);
return true; return true;
} }
return false; return false;
@ -1284,7 +1286,7 @@ find_inheritors(Oid relid, Oid **supervec)
relid = lfirsti(elt); relid = lfirsti(elt);
rd = heap_open(relid, NoLock); rd = heap_open(relid, NoLock);
trelid = typeTypeId(typenameType(RelationGetRelationName(rd))); trelid = typenameTypeId(RelationGetRelationName(rd));
heap_close(rd, NoLock); heap_close(rd, NoLock);
*relidvec++ = trelid; *relidvec++ = trelid;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.48 2000/10/31 10:22:11 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.49 2000/11/16 22:30:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -67,7 +67,6 @@ make_operand(char *opname,
Oid target_typeId) Oid target_typeId)
{ {
Node *result; Node *result;
Type target_type = typeidType(target_typeId);
if (tree != NULL) if (tree != NULL)
{ {
@ -80,15 +79,7 @@ make_operand(char *opname,
else else
{ {
/* otherwise, this is a NULL value */ /* otherwise, this is a NULL value */
Const *con = makeNode(Const); result = (Node *) makeNullConst(target_typeId);
con->consttype = target_typeId;
con->constlen = typeLen(target_type);
con->constvalue = (Datum) NULL;
con->constisnull = true;
con->constbyval = typeByVal(target_type);
con->constisset = false;
result = (Node *) con;
} }
return result; return result;
@ -137,7 +128,7 @@ make_op(char *opname, Node *ltree, Node *rtree)
/* otherwise, binary operator */ /* otherwise, binary operator */
else else
{ {
tup = oper(opname, ltypeId, rtypeId, FALSE); tup = oper(opname, ltypeId, rtypeId, false);
opform = (Form_pg_operator) GETSTRUCT(tup); opform = (Form_pg_operator) GETSTRUCT(tup);
left = make_operand(opname, ltree, ltypeId, opform->oprleft); left = make_operand(opname, ltree, ltypeId, opform->oprleft);
right = make_operand(opname, rtree, rtypeId, opform->oprright); right = make_operand(opname, rtree, rtypeId, opform->oprright);
@ -159,6 +150,8 @@ make_op(char *opname, Node *ltree, Node *rtree)
else else
result->args = makeList2(left, right); result->args = makeList2(left, right);
ReleaseSysCache(tup);
return result; return result;
} /* make_op() */ } /* make_op() */
@ -183,10 +176,10 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno)
HeapTuple tp; HeapTuple tp;
Form_pg_attribute att_tup; Form_pg_attribute att_tup;
tp = SearchSysCacheTuple(ATTNUM, tp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(rte->relid), ObjectIdGetDatum(rte->relid),
Int16GetDatum(attrno), Int16GetDatum(attrno),
0, 0); 0, 0);
/* this shouldn't happen... */ /* this shouldn't happen... */
if (!HeapTupleIsValid(tp)) if (!HeapTupleIsValid(tp))
elog(ERROR, "Relation %s does not have attribute %d", elog(ERROR, "Relation %s does not have attribute %d",
@ -194,6 +187,7 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno)
att_tup = (Form_pg_attribute) GETSTRUCT(tp); att_tup = (Form_pg_attribute) GETSTRUCT(tp);
vartypeid = att_tup->atttypid; vartypeid = att_tup->atttypid;
type_mod = att_tup->atttypmod; type_mod = att_tup->atttypmod;
ReleaseSysCache(tp);
} }
else else
{ {
@ -249,7 +243,8 @@ transformArraySubscripts(ParseState *pstate,
Oid typearray, Oid typearray,
typeelement, typeelement,
typeresult; typeresult;
HeapTuple type_tuple; HeapTuple type_tuple_array,
type_tuple_element;
Form_pg_type type_struct_array, Form_pg_type type_struct_array,
type_struct_element; type_struct_element;
bool isSlice = forceSlice; bool isSlice = forceSlice;
@ -261,13 +256,13 @@ transformArraySubscripts(ParseState *pstate,
/* Get the type tuple for the array */ /* Get the type tuple for the array */
typearray = exprType(arrayBase); typearray = exprType(arrayBase);
type_tuple = SearchSysCacheTuple(TYPEOID, type_tuple_array = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typearray), ObjectIdGetDatum(typearray),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(type_tuple)) if (!HeapTupleIsValid(type_tuple_array))
elog(ERROR, "transformArraySubscripts: Cache lookup failed for array type %u", elog(ERROR, "transformArraySubscripts: Cache lookup failed for array type %u",
typearray); typearray);
type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple); type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array);
typeelement = type_struct_array->typelem; typeelement = type_struct_array->typelem;
if (typeelement == InvalidOid) if (typeelement == InvalidOid)
@ -275,13 +270,13 @@ transformArraySubscripts(ParseState *pstate,
NameStr(type_struct_array->typname)); NameStr(type_struct_array->typname));
/* Get the type tuple for the array element type */ /* Get the type tuple for the array element type */
type_tuple = SearchSysCacheTuple(TYPEOID, type_tuple_element = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeelement), ObjectIdGetDatum(typeelement),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(type_tuple)) if (!HeapTupleIsValid(type_tuple_element))
elog(ERROR, "transformArraySubscripts: Cache lookup failed for array element type %u", elog(ERROR, "transformArraySubscripts: Cache lookup failed for array element type %u",
typeelement); typeelement);
type_struct_element = (Form_pg_type) GETSTRUCT(type_tuple); type_struct_element = (Form_pg_type) GETSTRUCT(type_tuple_element);
/* /*
* A list containing only single subscripts refers to a single array * A list containing only single subscripts refers to a single array
@ -398,6 +393,9 @@ transformArraySubscripts(ParseState *pstate,
aref->refexpr = arrayBase; aref->refexpr = arrayBase;
aref->refassgnexpr = assignFrom; aref->refassgnexpr = assignFrom;
ReleaseSysCache(type_tuple_array);
ReleaseSysCache(type_tuple_element);
return aref; return aref;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.43 2000/11/11 19:49:26 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.44 2000/11/16 22:30:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -38,25 +38,21 @@ static void op_error(char *op, Oid arg1, Oid arg2);
static void unary_op_error(char *op, Oid arg, bool is_left_op); static void unary_op_error(char *op, Oid arg, bool is_left_op);
/* Select an ordering operator for the given datatype */
Oid Oid
any_ordering_op(Oid restype) any_ordering_op(Oid restype)
{ {
Operator order_op;
Oid order_opid; Oid order_opid;
order_op = oper("<", restype, restype, TRUE); order_opid = oper_oid("<", restype, restype, true);
if (!HeapTupleIsValid(order_op)) if (!OidIsValid(order_opid))
{
elog(ERROR, "Unable to identify an ordering operator '%s' for type '%s'" elog(ERROR, "Unable to identify an ordering operator '%s' for type '%s'"
"\n\tUse an explicit ordering operator or modify the query", "\n\tUse an explicit ordering operator or modify the query",
"<", typeidTypeName(restype)); "<", typeidTypeName(restype));
}
order_opid = oprid(order_op);
return order_opid; return order_opid;
} }
/* given operator, return the operator OID */ /* given operator tuple, return the operator OID */
Oid Oid
oprid(Operator op) oprid(Operator op)
{ {
@ -502,9 +498,10 @@ oper_select_candidate(int nargs,
/* oper_exact() /* oper_exact()
* Given operator, and arguments, return oper struct or NULL. * Given operator, types of arg1 and arg2, return oper struct or NULL.
* Inputs: *
* arg1, arg2: Type IDs * NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/ */
static Operator static Operator
oper_exact(char *op, Oid arg1, Oid arg2) oper_exact(char *op, Oid arg1, Oid arg2)
@ -517,20 +514,21 @@ oper_exact(char *op, Oid arg1, Oid arg2)
else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid)) else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
arg2 = arg1; arg2 = arg1;
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(arg1), ObjectIdGetDatum(arg1),
ObjectIdGetDatum(arg2), ObjectIdGetDatum(arg2),
CharGetDatum('b')); CharGetDatum('b'));
return (Operator) tup; return (Operator) tup;
} /* oper_exact() */ }
/* oper_inexact() /* oper_inexact()
* Given operator, types of arg1, and arg2, return oper struct or NULL. * Given operator, types of arg1 and arg2, return oper struct or NULL.
* Inputs: *
* arg1, arg2: Type IDs * NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/ */
static Operator static Operator
oper_inexact(char *op, Oid arg1, Oid arg2) oper_inexact(char *op, Oid arg1, Oid arg2)
@ -556,11 +554,11 @@ oper_inexact(char *op, Oid arg1, Oid arg2)
/* Or found exactly one? Then proceed... */ /* Or found exactly one? Then proceed... */
else if (ncandidates == 1) else if (ncandidates == 1)
{ {
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(candidates->args[0]), ObjectIdGetDatum(candidates->args[0]),
ObjectIdGetDatum(candidates->args[1]), ObjectIdGetDatum(candidates->args[1]),
CharGetDatum('b')); CharGetDatum('b'));
Assert(HeapTupleIsValid(tup)); Assert(HeapTupleIsValid(tup));
} }
@ -572,43 +570,68 @@ oper_inexact(char *op, Oid arg1, Oid arg2)
targetOids = oper_select_candidate(2, inputOids, candidates); targetOids = oper_select_candidate(2, inputOids, candidates);
if (targetOids != NULL) if (targetOids != NULL)
{ {
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(targetOids[0]), ObjectIdGetDatum(targetOids[0]),
ObjectIdGetDatum(targetOids[1]), ObjectIdGetDatum(targetOids[1]),
CharGetDatum('b')); CharGetDatum('b'));
} }
else else
tup = NULL; tup = NULL;
} }
return (Operator) tup; return (Operator) tup;
} /* oper_inexact() */ }
/* oper() /* oper() -- search for a binary operator
* Given operator, types of arg1, and arg2, return oper struct. * Given operator name, types of arg1 and arg2, return oper struct.
* Inputs: *
* arg1, arg2: Type IDs * If no matching operator found, return NULL if noError is true,
* raise an error if it is false.
*
* NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/ */
Operator Operator
oper(char *opname, Oid ltypeId, Oid rtypeId, bool noWarnings) oper(char *opname, Oid ltypeId, Oid rtypeId, bool noError)
{ {
HeapTuple tup; HeapTuple tup;
/* check for exact match on this operator... */ /* check for exact match on this operator... */
if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId))) if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId)))
{ return (Operator) tup;
}
/* try to find a match on likely candidates... */ /* try to find a match on likely candidates... */
else if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId))) if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId)))
{ return (Operator) tup;
}
else if (!noWarnings) if (!noError)
op_error(opname, ltypeId, rtypeId); op_error(opname, ltypeId, rtypeId);
return (Operator) tup; return (Operator) NULL;
} /* oper() */ }
/* oper_oid() -- get OID of a binary operator
*
* This is a convenience routine that extracts only the operator OID
* from the result of oper(). InvalidOid is returned if the lookup
* fails and noError is true.
*/
Oid
oper_oid(char *op, Oid arg1, Oid arg2, bool noError)
{
Operator optup;
Oid result;
optup = oper(op, arg1, arg2, noError);
if (optup != NULL)
{
result = oprid(optup);
ReleaseSysCache(optup);
return result;
}
return InvalidOid;
}
/* unary_oper_get_candidates() /* unary_oper_get_candidates()
* given opname, find all possible types for which * given opname, find all possible types for which
@ -671,8 +694,13 @@ unary_oper_get_candidates(char *opname,
} /* unary_oper_get_candidates() */ } /* unary_oper_get_candidates() */
/* Given unary right-side operator (operator on right), return oper struct */ /* Given unary right operator (operator on right), return oper struct
/* arg-- type id */ *
* Always raises error on failure.
*
* NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/
Operator Operator
right_oper(char *op, Oid arg) right_oper(char *op, Oid arg)
{ {
@ -682,11 +710,11 @@ right_oper(char *op, Oid arg)
Oid *targetOid; Oid *targetOid;
/* Try for exact match */ /* Try for exact match */
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(arg), ObjectIdGetDatum(arg),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
CharGetDatum('r')); CharGetDatum('r'));
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{ {
@ -696,21 +724,21 @@ right_oper(char *op, Oid arg)
unary_op_error(op, arg, FALSE); unary_op_error(op, arg, FALSE);
else if (ncandidates == 1) else if (ncandidates == 1)
{ {
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(candidates->args[0]), ObjectIdGetDatum(candidates->args[0]),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
CharGetDatum('r')); CharGetDatum('r'));
} }
else else
{ {
targetOid = oper_select_candidate(1, &arg, candidates); targetOid = oper_select_candidate(1, &arg, candidates);
if (targetOid != NULL) if (targetOid != NULL)
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(targetOid[0]), ObjectIdGetDatum(targetOid[0]),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
CharGetDatum('r')); CharGetDatum('r'));
} }
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
@ -721,8 +749,13 @@ right_oper(char *op, Oid arg)
} /* right_oper() */ } /* right_oper() */
/* Given unary left-side operator (operator on left), return oper struct */ /* Given unary left operator (operator on left), return oper struct
/* arg--type id */ *
* Always raises error on failure.
*
* NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/
Operator Operator
left_oper(char *op, Oid arg) left_oper(char *op, Oid arg)
{ {
@ -732,11 +765,11 @@ left_oper(char *op, Oid arg)
Oid *targetOid; Oid *targetOid;
/* Try for exact match */ /* Try for exact match */
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
ObjectIdGetDatum(arg), ObjectIdGetDatum(arg),
CharGetDatum('l')); CharGetDatum('l'));
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
{ {
@ -746,21 +779,21 @@ left_oper(char *op, Oid arg)
unary_op_error(op, arg, TRUE); unary_op_error(op, arg, TRUE);
else if (ncandidates == 1) else if (ncandidates == 1)
{ {
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
ObjectIdGetDatum(candidates->args[0]), ObjectIdGetDatum(candidates->args[0]),
CharGetDatum('l')); CharGetDatum('l'));
} }
else else
{ {
targetOid = oper_select_candidate(1, &arg, candidates); targetOid = oper_select_candidate(1, &arg, candidates);
if (targetOid != NULL) if (targetOid != NULL)
tup = SearchSysCacheTuple(OPERNAME, tup = SearchSysCache(OPERNAME,
PointerGetDatum(op), PointerGetDatum(op),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
ObjectIdGetDatum(targetOid[0]), ObjectIdGetDatum(targetOid[0]),
CharGetDatum('l')); CharGetDatum('l'));
} }
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
@ -778,24 +811,17 @@ left_oper(char *op, Oid arg)
static void static void
op_error(char *op, Oid arg1, Oid arg2) op_error(char *op, Oid arg1, Oid arg2)
{ {
Type tp1 = NULL, if (!typeidIsValid(arg1))
tp2 = NULL;
if (typeidIsValid(arg1))
tp1 = typeidType(arg1);
else
elog(ERROR, "Left hand side of operator '%s' has an unknown type" elog(ERROR, "Left hand side of operator '%s' has an unknown type"
"\n\tProbably a bad attribute name", op); "\n\tProbably a bad attribute name", op);
if (typeidIsValid(arg2)) if (!typeidIsValid(arg2))
tp2 = typeidType(arg2);
else
elog(ERROR, "Right hand side of operator %s has an unknown type" elog(ERROR, "Right hand side of operator %s has an unknown type"
"\n\tProbably a bad attribute name", op); "\n\tProbably a bad attribute name", op);
elog(ERROR, "Unable to identify an operator '%s' for types '%s' and '%s'" elog(ERROR, "Unable to identify an operator '%s' for types '%s' and '%s'"
"\n\tYou will have to retype this query using an explicit cast", "\n\tYou will have to retype this query using an explicit cast",
op, typeTypeName(tp1), typeTypeName(tp2)); op, typeidTypeName(arg1), typeidTypeName(arg2));
} }
/* unary_op_error() /* unary_op_error()
@ -805,20 +831,14 @@ op_error(char *op, Oid arg1, Oid arg2)
static void static void
unary_op_error(char *op, Oid arg, bool is_left_op) unary_op_error(char *op, Oid arg, bool is_left_op)
{ {
Type tp1 = NULL; if (!typeidIsValid(arg))
if (typeidIsValid(arg))
tp1 = typeidType(arg);
else
{
elog(ERROR, "Argument of %s operator '%s' has an unknown type" elog(ERROR, "Argument of %s operator '%s' has an unknown type"
"\n\tProbably a bad attribute name", "\n\tProbably a bad attribute name",
(is_left_op ? "left" : "right"), (is_left_op ? "left" : "right"),
op); op);
}
elog(ERROR, "Unable to identify a %s operator '%s' for type '%s'" elog(ERROR, "Unable to identify a %s operator '%s' for type '%s'"
"\n\tYou may need to add parentheses or an explicit cast", "\n\tYou may need to add parentheses or an explicit cast",
(is_left_op ? "left" : "right"), (is_left_op ? "left" : "right"),
op, typeTypeName(tp1)); op, typeidTypeName(arg));
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.32 2000/06/08 22:37:18 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.33 2000/11/16 22:30:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -28,63 +28,45 @@
bool bool
typeidIsValid(Oid id) typeidIsValid(Oid id)
{ {
return (SearchSysCacheTuple(TYPEOID, return SearchSysCacheExists(TYPEOID,
ObjectIdGetDatum(id), ObjectIdGetDatum(id),
0, 0, 0) != NULL); 0, 0, 0);
}
/* return a type name, given a typeid */
char *
typeidTypeName(Oid id)
{
HeapTuple tup;
Form_pg_type typetuple;
if (!(tup = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(id),
0, 0, 0)))
{
elog(ERROR, "Unable to locate type oid %u in catalog", id);
return NULL;
}
typetuple = (Form_pg_type) GETSTRUCT(tup);
/* pstrdup here because result may need to outlive the syscache entry */
return pstrdup(NameStr(typetuple->typname));
} }
/* return a Type structure, given a type id */ /* return a Type structure, given a type id */
/* NB: caller must ReleaseSysCache the type tuple when done with it */
Type Type
typeidType(Oid id) typeidType(Oid id)
{ {
HeapTuple tup; HeapTuple tup;
if (!(tup = SearchSysCacheTuple(TYPEOID, tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(id), ObjectIdGetDatum(id),
0, 0, 0))) 0, 0, 0);
{ if (!HeapTupleIsValid(tup))
elog(ERROR, "Unable to locate type oid %u in catalog", id); elog(ERROR, "Unable to locate type oid %u in catalog", id);
return NULL;
}
return (Type) tup; return (Type) tup;
} }
/* return a Type structure, given type name */ /* return a Type structure, given type name */
/* NB: caller must ReleaseSysCache the type tuple when done with it */
Type Type
typenameType(char *s) typenameType(char *s)
{ {
HeapTuple tup; HeapTuple tup;
if (s == NULL) if (s == NULL)
elog(ERROR, "type(): Null type"); elog(ERROR, "typenameType: Null typename");
if (!(tup = SearchSysCacheTuple(TYPENAME, tup = SearchSysCache(TYPENAME,
PointerGetDatum(s), PointerGetDatum(s),
0, 0, 0))) 0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "Unable to locate type name '%s' in catalog", s); elog(ERROR, "Unable to locate type name '%s' in catalog", s);
return (Type) tup; return (Type) tup;
} }
/* given type, return the type OID */ /* given type (as type struct), return the type OID */
Oid Oid
typeTypeId(Type tp) typeTypeId(Type tp)
{ {
@ -134,61 +116,6 @@ typeTypeFlag(Type t)
return typ->typtype; return typ->typtype;
} }
/* Given a type structure and a string, returns the internal form of
that string */
Datum
stringTypeDatum(Type tp, char *string, int32 atttypmod)
{
Oid op;
Oid typelem;
op = ((Form_pg_type) GETSTRUCT(tp))->typinput;
typelem = ((Form_pg_type) GETSTRUCT(tp))->typelem; /* XXX - used for
* array_in */
return OidFunctionCall3(op,
CStringGetDatum(string),
ObjectIdGetDatum(typelem),
Int32GetDatum(atttypmod));
}
/* Given a type id, returns the out-conversion function of the type */
#ifdef NOT_USED
Oid
typeidOutfunc(Oid type_id)
{
HeapTuple typeTuple;
Form_pg_type type;
Oid outfunc;
typeTuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(type_id),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "typeidOutfunc: Invalid type - oid = %u", type_id);
type = (Form_pg_type) GETSTRUCT(typeTuple);
outfunc = type->typoutput;
return outfunc;
}
#endif
Oid
typeidTypeRelid(Oid type_id)
{
HeapTuple typeTuple;
Form_pg_type type;
typeTuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(type_id),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "typeidTypeRelid: Invalid type - oid = %u", type_id);
type = (Form_pg_type) GETSTRUCT(typeTuple);
return type->typrelid;
}
Oid Oid
typeTypeRelid(Type typ) typeTypeRelid(Type typ)
{ {
@ -211,36 +138,6 @@ typeTypElem(Type typ)
} }
#endif #endif
#ifdef NOT_USED
/* Given the attribute type of an array return the attribute type of
an element of the array */
Oid
GetArrayElementType(Oid typearray)
{
HeapTuple type_tuple;
Form_pg_type type_struct_array;
type_tuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(typearray),
0, 0, 0);
if (!HeapTupleIsValid(type_tuple))
elog(ERROR, "GetArrayElementType: Cache lookup failed for type %u",
typearray);
/* get the array type struct from the type tuple */
type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple);
if (type_struct_array->typelem == InvalidOid)
{
elog(ERROR, "GetArrayElementType: type %s is not an array",
NameStr(type_struct_array->typname));
}
return type_struct_array->typelem;
}
#endif
#ifdef NOT_USED #ifdef NOT_USED
/* Given a type structure, return the in-conversion function of the type */ /* Given a type structure, return the in-conversion function of the type */
Oid Oid
@ -266,3 +163,99 @@ typeOutfunc(Type typ)
return typtup->typoutput; return typtup->typoutput;
} }
#endif #endif
/* Given a type structure and a string, returns the internal form of
that string */
Datum
stringTypeDatum(Type tp, char *string, int32 atttypmod)
{
Oid op;
Oid typelem;
op = ((Form_pg_type) GETSTRUCT(tp))->typinput;
typelem = ((Form_pg_type) GETSTRUCT(tp))->typelem; /* XXX - used for
* array_in */
return OidFunctionCall3(op,
CStringGetDatum(string),
ObjectIdGetDatum(typelem),
Int32GetDatum(atttypmod));
}
/* Given a type id, returns the out-conversion function of the type */
#ifdef NOT_USED
Oid
typeidOutfunc(Oid type_id)
{
HeapTuple typeTuple;
Form_pg_type type;
Oid outfunc;
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(type_id),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "typeidOutfunc: Invalid type - oid = %u", type_id);
type = (Form_pg_type) GETSTRUCT(typeTuple);
outfunc = type->typoutput;
ReleaseSysCache(typeTuple);
return outfunc;
}
#endif
/* return a type name, given a typeid */
char *
typeidTypeName(Oid id)
{
HeapTuple tup;
Form_pg_type typetuple;
char *result;
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(id),
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "Unable to locate type oid %u in catalog", id);
typetuple = (Form_pg_type) GETSTRUCT(tup);
/*
* pstrdup here because result may need to outlive the syscache entry
* (eg, it might end up as part of a parse tree that will outlive
* the current transaction...)
*/
result = pstrdup(NameStr(typetuple->typname));
ReleaseSysCache(tup);
return result;
}
/* given a typeid, return the type's typrelid (associated relation, if any) */
Oid
typeidTypeRelid(Oid type_id)
{
HeapTuple typeTuple;
Form_pg_type type;
Oid result;
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(type_id),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "typeidTypeRelid: Invalid type - oid = %u", type_id);
type = (Form_pg_type) GETSTRUCT(typeTuple);
result = type->typrelid;
ReleaseSysCache(typeTuple);
return result;
}
/* given a type name, return the type's typeid */
Oid
typenameTypeId(char *s)
{
Type typ = typenameType(s);
Oid result;
result = typ->t_data->t_oid;
ReleaseSysCache(typ);
return result;
}

View File

@ -7,12 +7,13 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.50 2000/10/05 19:11:34 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.51 2000/11/16 22:30:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
@ -555,20 +556,6 @@ AddNotQual(Query *parsetree, Node *qual)
} }
/* Build a NULL constant expression of the given type */
static Node *
make_null(Oid type)
{
Const *c = makeNode(Const);
c->consttype = type;
c->constlen = get_typlen(type);
c->constvalue = PointerGetDatum(NULL);
c->constisnull = true;
c->constbyval = get_typbyval(type);
return (Node *) c;
}
/* Find a targetlist entry by resno */ /* Find a targetlist entry by resno */
static Node * static Node *
FindMatchingNew(List *tlist, int attno) FindMatchingNew(List *tlist, int attno)
@ -656,7 +643,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
else else
{ {
/* Otherwise replace unmatched var with a null */ /* Otherwise replace unmatched var with a null */
return make_null(var->vartype); return (Node *) makeNullConst(var->vartype);
} }
} }
else else
@ -796,7 +783,7 @@ HandleRIRAttributeRule_mutator(Node *node,
{ /* HACK: disallow SET variables */ { /* HACK: disallow SET variables */
*context->modified = TRUE; *context->modified = TRUE;
*context->badsql = TRUE; *context->badsql = TRUE;
return make_null(var->vartype); return (Node *) makeNullConst(var->vartype);
} }
else else
{ {
@ -813,7 +800,7 @@ HandleRIRAttributeRule_mutator(Node *node,
n = FindMatchingTLEntry(context->targetlist, n = FindMatchingTLEntry(context->targetlist,
name_to_look_for); name_to_look_for);
if (n == NULL) if (n == NULL)
return make_null(var->vartype); return (Node *) makeNullConst(var->vartype);
/* Make a copy of the tlist item to return */ /* Make a copy of the tlist item to return */
n = copyObject(n); n = copyObject(n);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.40 2000/09/29 18:21:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.41 2000/11/16 22:30:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -35,21 +35,26 @@ RewriteGetRuleEventRel(char *rulename)
{ {
HeapTuple htup; HeapTuple htup;
Oid eventrel; Oid eventrel;
char *result;
htup = SearchSysCacheTuple(RULENAME, htup = SearchSysCache(RULENAME,
PointerGetDatum(rulename), PointerGetDatum(rulename),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup))
elog(ERROR, "Rule or view \"%s\" not found", elog(ERROR, "Rule or view \"%s\" not found",
((strncmp(rulename, "_RET", 4) == 0) ? (rulename + 4) : rulename)); ((strncmp(rulename, "_RET", 4) == 0) ? (rulename + 4) : rulename));
eventrel = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class; eventrel = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class;
htup = SearchSysCacheTuple(RELOID, ReleaseSysCache(htup);
PointerGetDatum(eventrel),
0, 0, 0); htup = SearchSysCache(RELOID,
PointerGetDatum(eventrel),
0, 0, 0);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup))
elog(ERROR, "Relation %u not found", eventrel); elog(ERROR, "Relation %u not found", eventrel);
return NameStr(((Form_pg_class) GETSTRUCT(htup))->relname); result = pstrdup(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
ReleaseSysCache(htup);
return result;
} }
/* /*
@ -75,9 +80,9 @@ RemoveRewriteRule(char *ruleName)
/* /*
* Find the tuple for the target rule. * Find the tuple for the target rule.
*/ */
tuple = SearchSysCacheTupleCopy(RULENAME, tuple = SearchSysCacheCopy(RULENAME,
PointerGetDatum(ruleName), PointerGetDatum(ruleName),
0, 0, 0); 0, 0, 0);
/* /*
* complain if no rule with such name existed * complain if no rule with such name existed

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.44 2000/09/29 18:21:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.45 2000/11/16 22:30:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -18,19 +18,15 @@
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "rewrite/rewriteSupport.h" #include "rewrite/rewriteSupport.h"
#include "utils/catcache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
int bool
IsDefinedRewriteRule(char *ruleName) IsDefinedRewriteRule(char *ruleName)
{ {
HeapTuple tuple; return SearchSysCacheExists(RULENAME,
tuple = SearchSysCacheTuple(RULENAME,
PointerGetDatum(ruleName), PointerGetDatum(ruleName),
0, 0, 0); 0, 0, 0);
return HeapTupleIsValid(tuple);
} }
/* /*
@ -59,10 +55,11 @@ SetRelationRuleStatus(Oid relationId, bool relHasRules,
* Find the tuple to update in pg_class, using syscache for the lookup. * Find the tuple to update in pg_class, using syscache for the lookup.
*/ */
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock); relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTupleCopy(RELOID, tuple = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(relationId), ObjectIdGetDatum(relationId),
0, 0, 0); 0, 0, 0);
Assert(HeapTupleIsValid(tuple)); if (!HeapTupleIsValid(tuple))
elog(ERROR, "SetRelationRuleStatus: cache lookup failed for relation %u", relationId);
/* Do the update */ /* Do the update */
((Form_pg_class) GETSTRUCT(tuple))->relhasrules = relHasRules; ((Form_pg_class) GETSTRUCT(tuple))->relhasrules = relHasRules;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.44 2000/10/24 20:59:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.45 2000/11/16 22:30:30 tgl Exp $
* *
* NOTES * NOTES
* This cruft is the server side of PQfn. * This cruft is the server side of PQfn.
@ -202,14 +202,12 @@ update_fp_info(Oid func_id, struct fp_info * fip)
MemSet((char *) fip, 0, (int) sizeof(struct fp_info)); MemSet((char *) fip, 0, (int) sizeof(struct fp_info));
fip->funcid = InvalidOid; fip->funcid = InvalidOid;
func_htp = SearchSysCacheTuple(PROCOID, func_htp = SearchSysCache(PROCOID,
ObjectIdGetDatum(func_id), ObjectIdGetDatum(func_id),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(func_htp)) if (!HeapTupleIsValid(func_htp))
{
elog(ERROR, "update_fp_info: cache lookup for function %u failed", elog(ERROR, "update_fp_info: cache lookup for function %u failed",
func_id); func_id);
}
pp = (Form_pg_proc) GETSTRUCT(func_htp); pp = (Form_pg_proc) GETSTRUCT(func_htp);
rettype = pp->prorettype; rettype = pp->prorettype;
argtypes = pp->proargtypes; argtypes = pp->proargtypes;
@ -220,38 +218,38 @@ update_fp_info(Oid func_id, struct fp_info * fip)
{ {
if (OidIsValid(argtypes[i])) if (OidIsValid(argtypes[i]))
{ {
type_htp = SearchSysCacheTuple(TYPEOID, type_htp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(argtypes[i]), ObjectIdGetDatum(argtypes[i]),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(type_htp)) if (!HeapTupleIsValid(type_htp))
{
elog(ERROR, "update_fp_info: bad argument type %u for %u", elog(ERROR, "update_fp_info: bad argument type %u for %u",
argtypes[i], func_id); argtypes[i], func_id);
}
tp = (Form_pg_type) GETSTRUCT(type_htp); tp = (Form_pg_type) GETSTRUCT(type_htp);
fip->argbyval[i] = tp->typbyval; fip->argbyval[i] = tp->typbyval;
fip->arglen[i] = tp->typlen; fip->arglen[i] = tp->typlen;
ReleaseSysCache(type_htp);
} /* else it had better be VAR_LENGTH_ARG */ } /* else it had better be VAR_LENGTH_ARG */
} }
if (OidIsValid(rettype)) if (OidIsValid(rettype))
{ {
type_htp = SearchSysCacheTuple(TYPEOID, type_htp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(rettype), ObjectIdGetDatum(rettype),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(type_htp)) if (!HeapTupleIsValid(type_htp))
{
elog(ERROR, "update_fp_info: bad return type %u for %u", elog(ERROR, "update_fp_info: bad return type %u for %u",
rettype, func_id); rettype, func_id);
}
tp = (Form_pg_type) GETSTRUCT(type_htp); tp = (Form_pg_type) GETSTRUCT(type_htp);
fip->retbyval = tp->typbyval; fip->retbyval = tp->typbyval;
fip->retlen = tp->typlen; fip->retlen = tp->typlen;
ReleaseSysCache(type_htp);
} /* else it had better by VAR_LENGTH_RESULT */ } /* else it had better by VAR_LENGTH_RESULT */
fip->xid = GetCurrentTransactionId(); fip->xid = GetCurrentTransactionId();
fip->cid = GetCurrentCommandId(); fip->cid = GetCurrentCommandId();
ReleaseSysCache(func_htp);
/* /*
* This must be last! * This must be last!
*/ */

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.102 2000/11/14 18:37:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.103 2000/11/16 22:30:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -102,9 +102,9 @@ CheckDropPermissions(char *name, char rightkind)
break; break;
Assert(rentry->kind != '\0'); Assert(rentry->kind != '\0');
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCache(RELNAME,
PointerGetDatum(name), PointerGetDatum(name),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "%s \"%s\" does not exist", rentry->name, name); elog(ERROR, "%s \"%s\" does not exist", rentry->name, name);
@ -120,6 +120,8 @@ CheckDropPermissions(char *name, char rightkind)
if (!allowSystemTableMods && IsSystemRelationName(name)) if (!allowSystemTableMods && IsSystemRelationName(name))
elog(ERROR, "%s \"%s\" is a system %s", elog(ERROR, "%s \"%s\" is a system %s",
rentry->name, name, rentry->name); rentry->name, name, rentry->name);
ReleaseSysCache(tuple);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.52 2000/11/03 19:01:36 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.53 2000/11/16 22:30:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -174,12 +174,13 @@ aclparse(char *s, AclItem *aip, unsigned *modechg)
switch (aip->ai_idtype) switch (aip->ai_idtype)
{ {
case ACL_IDTYPE_UID: case ACL_IDTYPE_UID:
htup = SearchSysCacheTuple(SHADOWNAME, htup = SearchSysCache(SHADOWNAME,
PointerGetDatum(name), PointerGetDatum(name),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup))
elog(ERROR, "aclparse: non-existent user \"%s\"", name); elog(ERROR, "aclparse: non-existent user \"%s\"", name);
aip->ai_id = ((Form_pg_shadow) GETSTRUCT(htup))->usesysid; aip->ai_id = ((Form_pg_shadow) GETSTRUCT(htup))->usesysid;
ReleaseSysCache(htup);
break; break;
case ACL_IDTYPE_GID: case ACL_IDTYPE_GID:
aip->ai_id = get_grosysid(name); aip->ai_id = get_grosysid(name);
@ -272,9 +273,9 @@ aclitemout(PG_FUNCTION_ARGS)
switch (aip->ai_idtype) switch (aip->ai_idtype)
{ {
case ACL_IDTYPE_UID: case ACL_IDTYPE_UID:
htup = SearchSysCacheTuple(SHADOWSYSID, htup = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(aip->ai_id), ObjectIdGetDatum(aip->ai_id),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup))
{ {
/* Generate numeric UID if we don't find an entry */ /* Generate numeric UID if we don't find an entry */
@ -286,9 +287,12 @@ aclitemout(PG_FUNCTION_ARGS)
pfree(tmp); pfree(tmp);
} }
else else
{
strncat(p, (char *) &((Form_pg_shadow) strncat(p, (char *) &((Form_pg_shadow)
GETSTRUCT(htup))->usename, GETSTRUCT(htup))->usename,
sizeof(NameData)); sizeof(NameData));
ReleaseSysCache(htup);
}
break; break;
case ACL_IDTYPE_GID: case ACL_IDTYPE_GID:
strcat(p, "group "); strcat(p, "group ");

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.65 2000/11/14 23:28:13 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.66 2000/11/16 22:30:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1590,9 +1590,9 @@ system_cache_lookup(Oid element_type,
HeapTuple typeTuple; HeapTuple typeTuple;
Form_pg_type typeStruct; Form_pg_type typeStruct;
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(element_type), ObjectIdGetDatum(element_type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "array_out: Cache lookup failed for type %u", elog(ERROR, "array_out: Cache lookup failed for type %u",
element_type); element_type);
@ -1607,6 +1607,7 @@ system_cache_lookup(Oid element_type,
*proc = typeStruct->typinput; *proc = typeStruct->typinput;
else else
*proc = typeStruct->typoutput; *proc = typeStruct->typoutput;
ReleaseSysCache(typeTuple);
} }
/* /*

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.5 2000/08/26 21:53:41 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.6 2000/11/16 22:30:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -98,9 +98,9 @@ format_type_internal(Oid type_oid, int32 typemod)
if (type_oid == InvalidOid) if (type_oid == InvalidOid)
return pstrdup("-"); return pstrdup("-");
tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(type_oid), tuple = SearchSysCache(TYPEOID,
0, 0, 0); ObjectIdGetDatum(type_oid),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
return pstrdup("???"); return pstrdup("???");
@ -108,9 +108,11 @@ format_type_internal(Oid type_oid, int32 typemod)
typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen; typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen;
if (array_base_type != 0 && typlen < 0) if (array_base_type != 0 && typlen < 0)
{ {
tuple = SearchSysCacheTuple(TYPEOID, /* Switch our attention to the array element type */
ObjectIdGetDatum(array_base_type), ReleaseSysCache(tuple);
0, 0, 0); tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(array_base_type),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
return pstrdup("???[]"); return pstrdup("???[]");
is_array = true; is_array = true;
@ -211,6 +213,8 @@ format_type_internal(Oid type_oid, int32 typemod)
if (is_array) if (is_array)
buf = psnprintf(strlen(buf) + 3, "%s[]", buf); buf = psnprintf(strlen(buf) + 3, "%s[]", buf);
ReleaseSysCache(tuple);
return buf; return buf;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.58 2000/07/09 21:30:12 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.59 2000/11/16 22:30:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -55,13 +55,12 @@ regprocin(PG_FUNCTION_ARGS)
if (pro_name_or_oid[0] >= '0' && if (pro_name_or_oid[0] >= '0' &&
pro_name_or_oid[0] <= '9') pro_name_or_oid[0] <= '9')
{ {
proctup = SearchSysCacheTuple(PROCOID, result = (RegProcedure)
DirectFunctionCall1(oidin, GetSysCacheOid(PROCOID,
DirectFunctionCall1(oidin,
CStringGetDatum(pro_name_or_oid)), CStringGetDatum(pro_name_or_oid)),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(proctup)) if (!RegProcedureIsValid(result))
result = (RegProcedure) proctup->t_data->t_oid;
else
elog(ERROR, "No procedure with oid %s", pro_name_or_oid); elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
} }
else else
@ -176,9 +175,9 @@ regprocout(PG_FUNCTION_ARGS)
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
{ {
proctup = SearchSysCacheTuple(PROCOID, proctup = SearchSysCache(PROCOID,
ObjectIdGetDatum(proid), ObjectIdGetDatum(proid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(proctup)) if (HeapTupleIsValid(proctup))
{ {
@ -186,6 +185,7 @@ regprocout(PG_FUNCTION_ARGS)
s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname); s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname);
StrNCpy(result, s, NAMEDATALEN); StrNCpy(result, s, NAMEDATALEN);
ReleaseSysCache(proctup);
} }
else else
{ {

View File

@ -6,7 +6,7 @@
* *
* 1999 Jan Wieck * 1999 Jan Wieck
* *
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.17 2000/09/25 22:34:20 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.18 2000/11/16 22:30:31 tgl Exp $
* *
* ---------- * ----------
*/ */
@ -3300,24 +3300,26 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
HeapTuple opr_tup; HeapTuple opr_tup;
Form_pg_operator opr_struct; Form_pg_operator opr_struct;
opr_tup = SearchSysCacheTuple(OPERNAME, opr_tup = SearchSysCache(OPERNAME,
PointerGetDatum("="), PointerGetDatum("="),
ObjectIdGetDatum(typeid), ObjectIdGetDatum(typeid),
ObjectIdGetDatum(typeid), ObjectIdGetDatum(typeid),
CharGetDatum('b')); CharGetDatum('b'));
if (!HeapTupleIsValid(opr_tup)) if (!HeapTupleIsValid(opr_tup))
elog(ERROR, "ri_AttributesEqual(): cannot find '=' operator " elog(ERROR, "ri_AttributesEqual(): cannot find '=' operator "
"for type %u", typeid); "for type %u", typeid);
opr_struct = (Form_pg_operator) GETSTRUCT(opr_tup); opr_struct = (Form_pg_operator) GETSTRUCT(opr_tup);
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache, entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
(char *) &typeid, HASH_ENTER, &found); (char *) &typeid,
HASH_ENTER,
&found);
if (entry == NULL) if (entry == NULL)
elog(FATAL, "can't insert into RI operator cache"); elog(FATAL, "can't insert into RI operator cache");
entry->typeid = typeid; entry->typeid = typeid;
fmgr_info(opr_struct->oprcode, &(entry->oprfmgrinfo)); fmgr_info(opr_struct->oprcode, &(entry->oprfmgrinfo));
ReleaseSysCache(opr_tup);
} }
/* ---------- /* ----------

View File

@ -3,7 +3,7 @@
* back to source text * back to source text
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.68 2000/11/05 00:15:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.69 2000/11/16 22:30:31 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
@ -374,8 +374,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
* Fetch the pg_index tuple by the Oid of the index * Fetch the pg_index tuple by the Oid of the index
* ---------- * ----------
*/ */
ht_idx = SearchSysCacheTuple(INDEXRELID, ht_idx = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexrelid), 0, 0, 0); ObjectIdGetDatum(indexrelid),
0, 0, 0);
if (!HeapTupleIsValid(ht_idx)) if (!HeapTupleIsValid(ht_idx))
elog(ERROR, "syscache lookup for index %u failed", indexrelid); elog(ERROR, "syscache lookup for index %u failed", indexrelid);
idxrec = (Form_pg_index) GETSTRUCT(ht_idx); idxrec = (Form_pg_index) GETSTRUCT(ht_idx);
@ -384,8 +385,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
* Fetch the pg_class tuple of the index relation * Fetch the pg_class tuple of the index relation
* ---------- * ----------
*/ */
ht_idxrel = SearchSysCacheTuple(RELOID, ht_idxrel = SearchSysCache(RELOID,
ObjectIdGetDatum(idxrec->indexrelid), 0, 0, 0); ObjectIdGetDatum(idxrec->indexrelid),
0, 0, 0);
if (!HeapTupleIsValid(ht_idxrel)) if (!HeapTupleIsValid(ht_idxrel))
elog(ERROR, "syscache lookup for relid %u failed", idxrec->indexrelid); elog(ERROR, "syscache lookup for relid %u failed", idxrec->indexrelid);
idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel); idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
@ -394,8 +396,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
* Fetch the pg_class tuple of the indexed relation * Fetch the pg_class tuple of the indexed relation
* ---------- * ----------
*/ */
ht_indrel = SearchSysCacheTuple(RELOID, ht_indrel = SearchSysCache(RELOID,
ObjectIdGetDatum(idxrec->indrelid), 0, 0, 0); ObjectIdGetDatum(idxrec->indrelid),
0, 0, 0);
if (!HeapTupleIsValid(ht_indrel)) if (!HeapTupleIsValid(ht_indrel))
elog(ERROR, "syscache lookup for relid %u failed", idxrec->indrelid); elog(ERROR, "syscache lookup for relid %u failed", idxrec->indrelid);
indrelrec = (Form_pg_class) GETSTRUCT(ht_indrel); indrelrec = (Form_pg_class) GETSTRUCT(ht_indrel);
@ -484,12 +487,13 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
HeapTuple proctup; HeapTuple proctup;
Form_pg_proc procStruct; Form_pg_proc procStruct;
proctup = SearchSysCacheTuple(PROCOID, proctup = SearchSysCache(PROCOID,
ObjectIdGetDatum(idxrec->indproc), 0, 0, 0); ObjectIdGetDatum(idxrec->indproc),
0, 0, 0);
if (!HeapTupleIsValid(proctup)) if (!HeapTupleIsValid(proctup))
elog(ERROR, "cache lookup for proc %u failed", idxrec->indproc); elog(ERROR, "cache lookup for proc %u failed", idxrec->indproc);
procStruct = (Form_pg_proc) GETSTRUCT(proctup); procStruct = (Form_pg_proc) GETSTRUCT(proctup);
appendStringInfo(&buf, "%s(%s) ", appendStringInfo(&buf, "%s(%s) ",
quote_identifier(pstrdup(NameStr(procStruct->proname))), quote_identifier(pstrdup(NameStr(procStruct->proname))),
keybuf.data); keybuf.data);
@ -508,6 +512,7 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, "%s", appendStringInfo(&buf, "%s",
quote_identifier(SPI_getvalue(spi_tup, spi_ttc, quote_identifier(SPI_getvalue(spi_tup, spi_ttc,
spi_fno))); spi_fno)));
ReleaseSysCache(proctup);
} }
else else
/* ---------- /* ----------
@ -523,15 +528,19 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, ")"); appendStringInfo(&buf, ")");
/* ---------- /* ----------
* Create the result in upper executor memory * Create the result in upper executor memory, and free objects
* ---------- * ----------
*/ */
len = buf.len + VARHDRSZ; len = buf.len + VARHDRSZ;
indexdef = SPI_palloc(len); indexdef = SPI_palloc(len);
VARATT_SIZEP(indexdef) = len; VARATT_SIZEP(indexdef) = len;
memcpy(VARDATA(indexdef), buf.data, buf.len); memcpy(VARDATA(indexdef), buf.data, buf.len);
pfree(buf.data); pfree(buf.data);
pfree(keybuf.data); pfree(keybuf.data);
ReleaseSysCache(ht_idx);
ReleaseSysCache(ht_idxrel);
ReleaseSysCache(ht_indrel);
/* ---------- /* ----------
* Disconnect from SPI manager * Disconnect from SPI manager
@ -568,13 +577,14 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
* Get the pg_shadow entry and print the result * Get the pg_shadow entry and print the result
* ---------- * ----------
*/ */
usertup = SearchSysCacheTuple(SHADOWSYSID, usertup = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(uid), ObjectIdGetDatum(uid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(usertup)) if (HeapTupleIsValid(usertup))
{ {
user_rec = (Form_pg_shadow) GETSTRUCT(usertup); user_rec = (Form_pg_shadow) GETSTRUCT(usertup);
StrNCpy(NameStr(*result), NameStr(user_rec->usename), NAMEDATALEN); StrNCpy(NameStr(*result), NameStr(user_rec->usename), NAMEDATALEN);
ReleaseSysCache(usertup);
} }
else else
sprintf(NameStr(*result), "unknown (UID=%d)", uid); sprintf(NameStr(*result), "unknown (UID=%d)", uid);
@ -1392,10 +1402,11 @@ get_rule_expr(Node *node, deparse_context *context)
HeapTuple tp; HeapTuple tp;
Form_pg_operator optup; Form_pg_operator optup;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
Assert(HeapTupleIsValid(tp)); if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup for operator %u failed", opno);
optup = (Form_pg_operator) GETSTRUCT(tp); optup = (Form_pg_operator) GETSTRUCT(tp);
switch (optup->oprkind) switch (optup->oprkind)
{ {
@ -1414,6 +1425,7 @@ get_rule_expr(Node *node, deparse_context *context)
default: default:
elog(ERROR, "get_rule_expr: bogus oprkind"); elog(ERROR, "get_rule_expr: bogus oprkind");
} }
ReleaseSysCache(tp);
} }
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
break; break;
@ -1524,9 +1536,9 @@ get_rule_expr(Node *node, deparse_context *context)
/* we do NOT parenthesize the arg expression, for now */ /* we do NOT parenthesize the arg expression, for now */
get_rule_expr(fselect->arg, context); get_rule_expr(fselect->arg, context);
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(exprType(fselect->arg)), ObjectIdGetDatum(exprType(fselect->arg)),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup of type %u failed", elog(ERROR, "cache lookup of type %u failed",
exprType(fselect->arg)); exprType(fselect->arg));
@ -1538,6 +1550,7 @@ get_rule_expr(Node *node, deparse_context *context)
fieldname = get_relid_attribute_name(typrelid, fieldname = get_relid_attribute_name(typrelid,
fselect->fieldnum); fselect->fieldnum);
appendStringInfo(buf, ".%s", quote_identifier(fieldname)); appendStringInfo(buf, ".%s", quote_identifier(fieldname));
ReleaseSysCache(typetup);
} }
break; break;
@ -1550,9 +1563,9 @@ get_rule_expr(Node *node, deparse_context *context)
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr(relabel->arg, context); get_rule_expr(relabel->arg, context);
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(relabel->resulttype), ObjectIdGetDatum(relabel->resulttype),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup of type %u failed", elog(ERROR, "cache lookup of type %u failed",
relabel->resulttype); relabel->resulttype);
@ -1560,6 +1573,7 @@ get_rule_expr(Node *node, deparse_context *context)
extval = pstrdup(NameStr(typeStruct->typname)); extval = pstrdup(NameStr(typeStruct->typname));
appendStringInfo(buf, ")::%s", quote_identifier(extval)); appendStringInfo(buf, ")::%s", quote_identifier(extval));
pfree(extval); pfree(extval);
ReleaseSysCache(typetup);
} }
break; break;
@ -1616,14 +1630,14 @@ get_func_expr(Expr *expr, deparse_context *context)
/* /*
* Get the functions pg_proc tuple * Get the functions pg_proc tuple
*/ */
proctup = SearchSysCacheTuple(PROCOID, proctup = SearchSysCache(PROCOID,
ObjectIdGetDatum(func->funcid), ObjectIdGetDatum(func->funcid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(proctup)) if (!HeapTupleIsValid(proctup))
elog(ERROR, "cache lookup for proc %u failed", func->funcid); elog(ERROR, "cache lookup for proc %u failed", func->funcid);
procStruct = (Form_pg_proc) GETSTRUCT(proctup); procStruct = (Form_pg_proc) GETSTRUCT(proctup);
proname = pstrdup(NameStr(procStruct->proname)); proname = NameStr(procStruct->proname);
/* /*
* nullvalue() and nonnullvalue() should get turned into special * nullvalue() and nonnullvalue() should get turned into special
@ -1636,6 +1650,7 @@ get_func_expr(Expr *expr, deparse_context *context)
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr((Node *) lfirst(expr->args), context); get_rule_expr((Node *) lfirst(expr->args), context);
appendStringInfo(buf, " ISNULL)"); appendStringInfo(buf, " ISNULL)");
ReleaseSysCache(proctup);
return; return;
} }
if (strcmp(proname, "nonnullvalue") == 0) if (strcmp(proname, "nonnullvalue") == 0)
@ -1643,6 +1658,7 @@ get_func_expr(Expr *expr, deparse_context *context)
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
get_rule_expr((Node *) lfirst(expr->args), context); get_rule_expr((Node *) lfirst(expr->args), context);
appendStringInfo(buf, " NOTNULL)"); appendStringInfo(buf, " NOTNULL)");
ReleaseSysCache(proctup);
return; return;
} }
} }
@ -1657,8 +1673,9 @@ get_func_expr(Expr *expr, deparse_context *context)
/* /*
* Strip off any RelabelType on the input, so we don't print * Strip off any RelabelType on the input, so we don't print
* redundancies like x::bpchar::char(8). XXX Are there any cases * redundancies like x::bpchar::char(8).
* where this is a bad idea? *
* XXX Are there any cases where this is a bad idea?
*/ */
if (IsA(arg, RelabelType)) if (IsA(arg, RelabelType))
arg = ((RelabelType *) arg)->arg; arg = ((RelabelType *) arg)->arg;
@ -1696,6 +1713,8 @@ get_func_expr(Expr *expr, deparse_context *context)
} }
else else
appendStringInfo(buf, "%s", quote_identifier(proname)); appendStringInfo(buf, "%s", quote_identifier(proname));
ReleaseSysCache(proctup);
return; return;
} }
@ -1711,6 +1730,8 @@ get_func_expr(Expr *expr, deparse_context *context)
get_rule_expr((Node *) lfirst(l), context); get_rule_expr((Node *) lfirst(l), context);
} }
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
ReleaseSysCache(proctup);
} }
@ -1766,9 +1787,9 @@ get_const_expr(Const *constval, deparse_context *context)
char *extval; char *extval;
char *valptr; char *valptr;
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(constval->consttype), ObjectIdGetDatum(constval->consttype),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup of type %u failed", constval->consttype); elog(ERROR, "cache lookup of type %u failed", constval->consttype);
@ -1785,6 +1806,7 @@ get_const_expr(Const *constval, deparse_context *context)
extval = pstrdup(NameStr(typeStruct->typname)); extval = pstrdup(NameStr(typeStruct->typname));
appendStringInfo(buf, "NULL::%s", quote_identifier(extval)); appendStringInfo(buf, "NULL::%s", quote_identifier(extval));
pfree(extval); pfree(extval);
ReleaseSysCache(typetup);
return; return;
} }
@ -1843,6 +1865,8 @@ get_const_expr(Const *constval, deparse_context *context)
pfree(extval); pfree(extval);
break; break;
} }
ReleaseSysCache(typetup);
} }
@ -2198,14 +2222,18 @@ get_relation_name(Oid relid)
{ {
HeapTuple classtup; HeapTuple classtup;
Form_pg_class classStruct; Form_pg_class classStruct;
char *result;
classtup = SearchSysCacheTuple(RELOID, classtup = SearchSysCache(RELOID,
ObjectIdGetDatum(relid), 0, 0, 0); ObjectIdGetDatum(relid),
0, 0, 0);
if (!HeapTupleIsValid(classtup)) if (!HeapTupleIsValid(classtup))
elog(ERROR, "cache lookup of relation %u failed", relid); elog(ERROR, "cache lookup of relation %u failed", relid);
classStruct = (Form_pg_class) GETSTRUCT(classtup); classStruct = (Form_pg_class) GETSTRUCT(classtup);
return pstrdup(NameStr(classStruct->relname)); result = pstrdup(NameStr(classStruct->relname));
ReleaseSysCache(classtup);
return result;
} }

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.81 2000/11/10 09:38:21 inoue Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.82 2000/11/16 22:30:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -324,12 +324,15 @@ scalarltsel(PG_FUNCTION_ARGS)
* Get left and right datatypes of the operator so we know what * Get left and right datatypes of the operator so we know what
* type the constant is. * type the constant is.
*/ */
oprtuple = get_operator_tuple(opid); oprtuple = SearchSysCache(OPEROID,
ObjectIdGetDatum(opid),
0, 0, 0);
if (!HeapTupleIsValid(oprtuple)) if (!HeapTupleIsValid(oprtuple))
elog(ERROR, "scalarltsel: no tuple for operator %u", opid); elog(ERROR, "scalarltsel: no tuple for operator %u", opid);
ltype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprleft; ltype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprleft;
rtype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprright; rtype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprright;
contype = (flag & SEL_RIGHT) ? rtype : ltype; contype = (flag & SEL_RIGHT) ? rtype : ltype;
ReleaseSysCache(oprtuple);
/* Now get info and stats about the attribute */ /* Now get info and stats about the attribute */
getattproperties(relid, attno, getattproperties(relid, attno,
@ -482,11 +485,14 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
* Get left and right datatypes of the operator so we know what * Get left and right datatypes of the operator so we know what
* type the attribute is. * type the attribute is.
*/ */
oprtuple = get_operator_tuple(opid); oprtuple = SearchSysCache(OPEROID,
ObjectIdGetDatum(opid),
0, 0, 0);
if (!HeapTupleIsValid(oprtuple)) if (!HeapTupleIsValid(oprtuple))
elog(ERROR, "patternsel: no tuple for operator %u", opid); elog(ERROR, "patternsel: no tuple for operator %u", opid);
ltype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprleft; ltype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprleft;
rtype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprright; rtype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprright;
ReleaseSysCache(oprtuple);
/* the right-hand const is type text for all supported operators */ /* the right-hand const is type text for all supported operators */
Assert(rtype == TEXTOID); Assert(rtype == TEXTOID);
@ -1189,10 +1195,10 @@ getattproperties(Oid relid, AttrNumber attnum,
HeapTuple atp; HeapTuple atp;
Form_pg_attribute att_tup; Form_pg_attribute att_tup;
atp = SearchSysCacheTuple(ATTNUM, atp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0); 0, 0);
if (!HeapTupleIsValid(atp)) if (!HeapTupleIsValid(atp))
elog(ERROR, "getattproperties: no attribute tuple %u %d", elog(ERROR, "getattproperties: no attribute tuple %u %d",
relid, (int) attnum); relid, (int) attnum);
@ -1202,6 +1208,8 @@ getattproperties(Oid relid, AttrNumber attnum,
*typlen = att_tup->attlen; *typlen = att_tup->attlen;
*typbyval = att_tup->attbyval; *typbyval = att_tup->attbyval;
*typmod = att_tup->atttypmod; *typmod = att_tup->atttypmod;
ReleaseSysCache(atp);
} }
/* /*
@ -1250,11 +1258,10 @@ getattstatistics(Oid relid,
* have at hand! (For example, we might have a '>' operator rather * have at hand! (For example, we might have a '>' operator rather
* than the '<' operator that will appear in staop.) * than the '<' operator that will appear in staop.)
*/ */
tuple = SearchSysCacheTupleCopy(STATRELID, tuple = SearchSysCache(STATRELID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
Int16GetDatum((int16) attnum), Int16GetDatum((int16) attnum),
0, 0, 0);
0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
/* no such stats entry */ /* no such stats entry */
@ -1267,14 +1274,15 @@ getattstatistics(Oid relid,
*commonfrac = ((Form_pg_statistic) GETSTRUCT(tuple))->stacommonfrac; *commonfrac = ((Form_pg_statistic) GETSTRUCT(tuple))->stacommonfrac;
/* Get the type input proc for the column datatype */ /* Get the type input proc for the column datatype */
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid), ObjectIdGetDatum(typid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "getattstatistics: Cache lookup failed for type %u", elog(ERROR, "getattstatistics: Cache lookup failed for type %u",
typid); typid);
fmgr_info(((Form_pg_type) GETSTRUCT(typeTuple))->typinput, &inputproc); fmgr_info(((Form_pg_type) GETSTRUCT(typeTuple))->typinput, &inputproc);
typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem; typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
ReleaseSysCache(typeTuple);
/* /*
* Values are variable-length fields, so cannot access as struct * Values are variable-length fields, so cannot access as struct
@ -1351,7 +1359,8 @@ getattstatistics(Oid relid,
pfree(strval); pfree(strval);
} }
} }
heap_freetuple(tuple);
ReleaseSysCache(tuple);
return true; return true;
} }
@ -1966,16 +1975,11 @@ string_lessthan(const char *str1, const char *str2, Oid datatype)
static Oid static Oid
find_operator(const char *opname, Oid datatype) find_operator(const char *opname, Oid datatype)
{ {
HeapTuple optup; return GetSysCacheOid(OPERNAME,
PointerGetDatum(opname),
optup = SearchSysCacheTuple(OPERNAME, ObjectIdGetDatum(datatype),
PointerGetDatum(opname), ObjectIdGetDatum(datatype),
ObjectIdGetDatum(datatype), CharGetDatum('b'));
ObjectIdGetDatum(datatype),
CharGetDatum('b'));
if (!HeapTupleIsValid(optup))
return InvalidOid;
return optup->t_data->t_oid;
} }
/* /*

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.33 2000/08/24 03:29:06 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.34 2000/11/16 22:30:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -77,9 +77,11 @@ SetDefine(char *querystr, char *typename)
*/ */
CommandCounterIncrement(); CommandCounterIncrement();
tup = SearchSysCacheTuple(PROCOID, procrel = heap_openr(ProcedureRelationName, RowExclusiveLock);
ObjectIdGetDatum(setoid),
0, 0, 0); tup = SearchSysCache(PROCOID,
ObjectIdGetDatum(setoid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "SetDefine: unable to define set %s", querystr); elog(ERROR, "SetDefine: unable to define set %s", querystr);
@ -105,25 +107,15 @@ SetDefine(char *querystr, char *typename)
replNull[i] = ' '; replNull[i] = ' ';
/* change the pg_proc tuple */ /* change the pg_proc tuple */
procrel = heap_openr(ProcedureRelationName, RowExclusiveLock); newtup = heap_modifytuple(tup,
procrel,
replValue,
replNull,
repl);
tup = SearchSysCacheTuple(PROCOID, heap_update(procrel, &newtup->t_self, newtup, NULL);
ObjectIdGetDatum(setoid),
0, 0, 0);
if (HeapTupleIsValid(tup))
{
newtup = heap_modifytuple(tup,
procrel,
replValue,
replNull,
repl);
heap_update(procrel, &tup->t_self, newtup, NULL); setoid = newtup->t_data->t_oid;
setoid = newtup->t_data->t_oid;
}
else
elog(ERROR, "SetDefine: could not find new set oid tuple");
if (RelationGetForm(procrel)->relhasindex) if (RelationGetForm(procrel)->relhasindex)
{ {
@ -133,9 +125,13 @@ SetDefine(char *querystr, char *typename)
CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup); CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup);
CatalogCloseIndices(Num_pg_proc_indices, idescs); CatalogCloseIndices(Num_pg_proc_indices, idescs);
} }
heap_close(procrel, RowExclusiveLock); heap_freetuple(newtup);
} }
ReleaseSysCache(tup);
heap_close(procrel, RowExclusiveLock);
return setoid; return setoid;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.71 2000/11/10 00:33:10 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.72 2000/11/16 22:30:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -28,7 +28,8 @@
#include "utils/catcache.h" #include "utils/catcache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
static void CatCacheRemoveCTup(CatCache *cache, Dlelem *e);
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct);
static Index CatalogCacheComputeHashIndex(CatCache *cache, static Index CatalogCacheComputeHashIndex(CatCache *cache,
ScanKey cur_skey); ScanKey cur_skey);
static Index CatalogCacheComputeTupleHashIndex(CatCache *cache, static Index CatalogCacheComputeTupleHashIndex(CatCache *cache,
@ -388,28 +389,17 @@ CatalogCacheComputeTupleHashIndex(CatCache *cache,
* -------------------------------- * --------------------------------
*/ */
static void static void
CatCacheRemoveCTup(CatCache *cache, Dlelem *elt) CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
{ {
CatCTup *ct; Assert(ct->refcount == 0);
CatCTup *other_ct;
Dlelem *other_elt;
if (!elt) /* probably-useless safety check */ /* delink from linked lists */
return; DLRemove(&ct->lrulist_elem);
DLRemove(&ct->cache_elem);
/* We need to zap both linked-list elements as well as the tuple */ /* free associated tuple data */
if (ct->tuple.t_data != NULL)
ct = (CatCTup *) DLE_VAL(elt); pfree(ct->tuple.t_data);
other_elt = ct->ct_node;
other_ct = (CatCTup *) DLE_VAL(other_elt);
heap_freetuple(ct->ct_tup);
DLRemove(other_elt);
DLFreeElem(other_elt);
pfree(other_ct);
DLRemove(elt);
DLFreeElem(elt);
pfree(ct); pfree(ct);
--cache->cc_ntup; --cache->cc_ntup;
@ -425,13 +415,11 @@ CatCacheRemoveCTup(CatCache *cache, Dlelem *elt)
* -------------------------------- * --------------------------------
*/ */
void void
CatalogCacheIdInvalidate(int cacheId, /* XXX */ CatalogCacheIdInvalidate(int cacheId,
Index hashIndex, Index hashIndex,
ItemPointer pointer) ItemPointer pointer)
{ {
CatCache *ccp; CatCache *ccp;
CatCTup *ct;
Dlelem *elt;
/* ---------------- /* ----------------
* sanity checks * sanity checks
@ -442,54 +430,101 @@ CatalogCacheIdInvalidate(int cacheId, /* XXX */
CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called"); CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
/* ---------------- /* ----------------
* inspect every cache that could contain the tuple * inspect caches to find the proper cache
* ---------------- * ----------------
*/ */
for (ccp = Caches; ccp; ccp = ccp->cc_next) for (ccp = Caches; ccp; ccp = ccp->cc_next)
{ {
Dlelem *elt,
*nextelt;
if (cacheId != ccp->id) if (cacheId != ccp->id)
continue; continue;
/* ---------------- /* ----------------
* inspect the hash bucket until we find a match or exhaust * inspect the hash bucket until we find a match or exhaust
* ---------------- * ----------------
*/ */
for (elt = DLGetHead(ccp->cc_cache[hashIndex]); for (elt = DLGetHead(&ccp->cc_cache[hashIndex]); elt; elt = nextelt)
elt;
elt = DLGetSucc(elt))
{ {
ct = (CatCTup *) DLE_VAL(elt); CatCTup *ct = (CatCTup *) DLE_VAL(elt);
if (ItemPointerEquals(pointer, &ct->ct_tup->t_self))
break; nextelt = DLGetSucc(elt);
if (ItemPointerEquals(pointer, &ct->tuple.t_self))
{
if (ct->refcount > 0)
ct->dead = true;
else
CatCacheRemoveCTup(ccp, ct);
CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
/* could be multiple matches, so keep looking! */
}
} }
break; /* need only search this one cache */
/* ----------------
* if we found a matching tuple, invalidate it.
* ----------------
*/
if (elt)
{
CatCacheRemoveCTup(ccp, elt);
CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
}
if (cacheId != InvalidCatalogCacheId)
break;
} }
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* public functions * public functions
* *
* AtEOXact_CatCache
* ResetSystemCache * ResetSystemCache
* InitSysCache * InitCatCache
* SearchSysCache * SearchCatCache
* ReleaseCatCache
* RelationInvalidateCatalogCacheTuple * RelationInvalidateCatalogCacheTuple
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
/* --------------------------------
* AtEOXact_CatCache
*
* Clean up catcaches at end of transaction (either commit or abort)
*
* We scan the caches to reset refcounts to zero. This is of course
* necessary in the abort case, since elog() may have interrupted routines.
* In the commit case, any nonzero counts indicate failure to call
* ReleaseSysCache, so we put out a notice for debugging purposes.
* --------------------------------
*/
void
AtEOXact_CatCache(bool isCommit)
{
CatCache *cache;
for (cache = Caches; cache; cache = cache->cc_next)
{
Dlelem *elt,
*nextelt;
for (elt = DLGetHead(&cache->cc_lrulist); elt; elt = nextelt)
{
CatCTup *ct = (CatCTup *) DLE_VAL(elt);
nextelt = DLGetSucc(elt);
if (ct->refcount != 0)
{
if (isCommit)
elog(NOTICE, "Cache reference leak: cache %s (%d), tuple %u has count %d",
cache->cc_relname, cache->id,
ct->tuple.t_data->t_oid,
ct->refcount);
ct->refcount = 0;
}
/* Clean up any now-deletable dead entries */
if (ct->dead)
CatCacheRemoveCTup(cache, ct);
}
}
}
/* -------------------------------- /* --------------------------------
* ResetSystemCache * ResetSystemCache
*
* Reset caches when a shared cache inval event forces it
* -------------------------------- * --------------------------------
*/ */
void void
@ -503,34 +538,25 @@ ResetSystemCache(void)
* here we purge the contents of all the caches * here we purge the contents of all the caches
* *
* for each system cache * for each system cache
* for each hash bucket * for each tuple
* for each tuple in hash bucket * remove the tuple, or at least mark it dead
* remove the tuple
* ---------------- * ----------------
*/ */
for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next) for (cache = Caches; cache; cache = cache->cc_next)
{ {
int hash; Dlelem *elt,
*nextelt;
for (hash = 0; hash < NCCBUCK; hash += 1) for (elt = DLGetHead(&cache->cc_lrulist); elt; elt = nextelt)
{ {
Dlelem *elt, CatCTup *ct = (CatCTup *) DLE_VAL(elt);
*nextelt;
for (elt = DLGetHead(cache->cc_cache[hash]); elt; elt = nextelt) nextelt = DLGetSucc(elt);
{
nextelt = DLGetSucc(elt);
CatCacheRemoveCTup(cache, elt);
}
}
/* double-check that ntup is now zero */ if (ct->refcount > 0)
if (cache->cc_ntup != 0) ct->dead = true;
{ else
elog(NOTICE, CatCacheRemoveCTup(cache, ct);
"ResetSystemCache: cache %d has cc_ntup = %d, should be 0",
cache->id, cache->cc_ntup);
cache->cc_ntup = 0;
} }
} }
@ -572,7 +598,7 @@ SystemCacheRelationFlushed(Oid relId)
} }
/* -------------------------------- /* --------------------------------
* InitSysCache * InitCatCache
* *
* This allocates and initializes a cache for a system catalog relation. * This allocates and initializes a cache for a system catalog relation.
* Actually, the cache is only partially initialized to avoid opening the * Actually, the cache is only partially initialized to avoid opening the
@ -581,18 +607,18 @@ SystemCacheRelationFlushed(Oid relId)
* -------------------------------- * --------------------------------
*/ */
#ifdef CACHEDEBUG #ifdef CACHEDEBUG
#define InitSysCache_DEBUG1 \ #define InitCatCache_DEBUG1 \
do { \ do { \
elog(DEBUG, "InitSysCache: rel=%s id=%d nkeys=%d size=%d\n", \ elog(DEBUG, "InitCatCache: rel=%s id=%d nkeys=%d size=%d\n", \
cp->cc_relname, cp->id, cp->cc_nkeys, cp->cc_size); \ cp->cc_relname, cp->id, cp->cc_nkeys, cp->cc_size); \
} while(0) } while(0)
#else #else
#define InitSysCache_DEBUG1 #define InitCatCache_DEBUG1
#endif #endif
CatCache * CatCache *
InitSysCache(int id, InitCatCache(int id,
char *relname, char *relname,
char *indname, char *indname,
int nkeys, int nkeys,
@ -624,25 +650,9 @@ InitSysCache(int id,
* and the LRU tuple list * and the LRU tuple list
* ---------------- * ----------------
*/ */
{ DLInitList(&cp->cc_lrulist);
for (i = 0; i < NCCBUCK; ++i)
/* DLInitList(&cp->cc_cache[i]);
* We can only do this optimization because the number of hash
* buckets never changes. Without it, we call palloc() too much.
* We could move this to dllist.c, but the way we do this is not
* dynamic/portable, so why allow other routines to use it.
*/
Dllist *cache_begin = palloc((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 * Caches is the pointer to the head of the list of all the
@ -673,7 +683,7 @@ InitSysCache(int id,
* information, if appropriate. * information, if appropriate.
* ---------------- * ----------------
*/ */
InitSysCache_DEBUG1; InitCatCache_DEBUG1;
/* ---------------- /* ----------------
* back to the old context before we return... * back to the old context before we return...
@ -742,14 +752,14 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
} }
/* -------------------------------- /* --------------------------------
* SearchSysCache * SearchCatCache
* *
* This call searches a system cache for a tuple, opening the relation * This call searches a system cache for a tuple, opening the relation
* if necessary (the first access to a particular cache). * if necessary (the first access to a particular cache).
* -------------------------------- * --------------------------------
*/ */
HeapTuple HeapTuple
SearchSysCache(CatCache *cache, SearchCatCache(CatCache *cache,
Datum v1, Datum v1,
Datum v2, Datum v2,
Datum v3, Datum v3,
@ -757,10 +767,8 @@ SearchSysCache(CatCache *cache,
{ {
ScanKeyData cur_skey[4]; ScanKeyData cur_skey[4];
Index hash; Index hash;
CatCTup *ct = NULL;
CatCTup *nct;
CatCTup *nct2;
Dlelem *elt; Dlelem *elt;
CatCTup *ct;
HeapTuple ntp; HeapTuple ntp;
Relation relation; Relation relation;
MemoryContext oldcxt; MemoryContext oldcxt;
@ -792,48 +800,50 @@ SearchSysCache(CatCache *cache,
* scan the hash bucket until we find a match or exhaust our tuples * scan the hash bucket until we find a match or exhaust our tuples
* ---------------- * ----------------
*/ */
for (elt = DLGetHead(cache->cc_cache[hash]); for (elt = DLGetHead(&cache->cc_cache[hash]);
elt; elt;
elt = DLGetSucc(elt)) elt = DLGetSucc(elt))
{ {
bool res; bool res;
ct = (CatCTup *) DLE_VAL(elt); ct = (CatCTup *) DLE_VAL(elt);
if (ct->dead)
continue; /* ignore dead entries */
/* ---------------- /* ----------------
* see if the cached tuple matches our key. * see if the cached tuple matches our key.
* (should we be worried about time ranges? -cim 10/2/90) * (should we be worried about time ranges? -cim 10/2/90)
* ---------------- * ----------------
*/ */
HeapKeyTest(ct->ct_tup, HeapKeyTest(&ct->tuple,
cache->cc_tupdesc, cache->cc_tupdesc,
cache->cc_nkeys, cache->cc_nkeys,
cur_skey, cur_skey,
res); res);
if (res) if (! res)
break; continue;
}
/* ---------------- /* ----------------
* if we found a tuple in the cache, move it to the top of the * we found a tuple in the cache: bump its refcount, move it to
* lru list, and return it. We also move it to the front of the * the front of the LRU list, and return it. We also move it
* list for its hashbucket, in order to speed subsequent searches. * to the front of the list for its hashbucket, in order to speed
* (The most frequently accessed elements in any hashbucket will * subsequent searches. (The most frequently accessed elements
* tend to be near the front of the hashbucket's list.) * in any hashbucket will tend to be near the front of the
* ---------------- * hashbucket's list.)
*/ * ----------------
if (elt) */
{ ct->refcount++;
Dlelem *old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
DLMoveToFront(old_lru_elt); DLMoveToFront(&ct->lrulist_elem);
DLMoveToFront(elt); DLMoveToFront(&ct->cache_elem);
#ifdef CACHEDEBUG #ifdef CACHEDEBUG
CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d", CACHE3_elog(DEBUG, "SearchCatCache(%s): found in bucket %d",
cache->cc_relname, hash); cache->cc_relname, hash);
#endif /* CACHEDEBUG */ #endif /* CACHEDEBUG */
return ct->ct_tup; return &ct->tuple;
} }
/* ---------------- /* ----------------
@ -864,7 +874,7 @@ SearchSysCache(CatCache *cache,
* if it's safe to do so, use the index. Else do a heap scan. * if it's safe to do so, use the index. Else do a heap scan.
* ---------------- * ----------------
*/ */
ntp = NULL; ct = NULL;
if ((RelationGetForm(relation))->relhasindex && if ((RelationGetForm(relation))->relhasindex &&
!IsIgnoringSystemIndexes() && !IsIgnoringSystemIndexes() &&
@ -876,7 +886,7 @@ SearchSysCache(CatCache *cache,
HeapTupleData tuple; HeapTupleData tuple;
Buffer buffer; Buffer buffer;
CACHE2_elog(DEBUG, "SearchSysCache(%s): performing index scan", CACHE2_elog(DEBUG, "SearchCatCache(%s): performing index scan",
cache->cc_relname); cache->cc_relname);
idesc = index_openr(cache->cc_indname); idesc = index_openr(cache->cc_indname);
@ -892,7 +902,8 @@ SearchSysCache(CatCache *cache,
{ {
/* Copy tuple into our context */ /* Copy tuple into our context */
oldcxt = MemoryContextSwitchTo(CacheMemoryContext); oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
ntp = heap_copytuple(&tuple); ct = (CatCTup *) palloc(sizeof(CatCTup));
heap_copytuple_with_tuple(&tuple, &ct->tuple);
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
break; break;
@ -906,7 +917,7 @@ SearchSysCache(CatCache *cache,
HeapScanDesc sd; HeapScanDesc sd;
int i; int i;
CACHE2_elog(DEBUG, "SearchSysCache(%s): performing heap scan", CACHE2_elog(DEBUG, "SearchCatCache(%s): performing heap scan",
cache->cc_relname); cache->cc_relname);
/* /*
@ -925,7 +936,8 @@ SearchSysCache(CatCache *cache,
{ {
/* Copy tuple into our context */ /* Copy tuple into our context */
oldcxt = MemoryContextSwitchTo(CacheMemoryContext); oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
ntp = heap_copytuple(ntp); ct = (CatCTup *) palloc(sizeof(CatCTup));
heap_copytuple_with_tuple(ntp, &ct->tuple);
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
/* We should not free the result of heap_getnext... */ /* We should not free the result of heap_getnext... */
} }
@ -934,77 +946,102 @@ SearchSysCache(CatCache *cache,
} }
/* ---------------- /* ----------------
* scan is complete. if tup is valid, we can add it to the cache. * close the relation
* note we have already copied it into the cache memory context.
* ----------------
*/
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;
CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
/*
* 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 *) palloc(sizeof(CatCTup));
nct->ct_tup = ntp;
elt = DLNewElem(nct);
nct2 = (CatCTup *) palloc(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);
MemoryContextSwitchTo(oldcxt);
/* ----------------
* If we've exceeded the desired size of this cache,
* throw away the least recently used entry.
* ----------------
*/
if (++cache->cc_ntup > cache->cc_maxtup)
{
CatCTup *ct;
elt = DLGetTail(cache->cc_lrulist);
ct = (CatCTup *) DLE_VAL(elt);
if (ct != nct) /* shouldn't be possible, but be safe... */
{
CACHE2_elog(DEBUG, "SearchSysCache(%s): Overflow, LRU removal",
cache->cc_relname);
CatCacheRemoveCTup(cache, elt);
}
}
CACHE4_elog(DEBUG, "SearchSysCache(%s): Contains %d/%d tuples",
cache->cc_relname, cache->cc_ntup, cache->cc_maxtup);
CACHE3_elog(DEBUG, "SearchSysCache(%s): put in bucket %d",
cache->cc_relname, hash);
}
/* ----------------
* close the relation and return the tuple we found (or NULL)
* ---------------- * ----------------
*/ */
heap_close(relation, AccessShareLock); heap_close(relation, AccessShareLock);
return ntp; /* ----------------
* scan is complete. if tup was found, we can add it to the cache.
* ----------------
*/
if (ct == NULL)
return NULL;
/* ----------------
* Finish initializing the CatCTup header, and add it to the
* linked lists.
* ----------------
*/
CACHE1_elog(DEBUG, "SearchCatCache: found tuple");
ct->ct_magic = CT_MAGIC;
DLInitElem(&ct->lrulist_elem, (void *) ct);
DLInitElem(&ct->cache_elem, (void *) ct);
ct->refcount = 1; /* count this first reference */
ct->dead = false;
DLAddHead(&cache->cc_lrulist, &ct->lrulist_elem);
DLAddHead(&cache->cc_cache[hash], &ct->cache_elem);
/* ----------------
* If we've exceeded the desired size of this cache,
* try to throw away the least recently used entry.
* ----------------
*/
if (++cache->cc_ntup > cache->cc_maxtup)
{
for (elt = DLGetTail(&cache->cc_lrulist);
elt;
elt = DLGetPred(elt))
{
CatCTup *oldct = (CatCTup *) DLE_VAL(elt);
if (oldct->refcount == 0)
{
CACHE2_elog(DEBUG, "SearchCatCache(%s): Overflow, LRU removal",
cache->cc_relname);
CatCacheRemoveCTup(cache, oldct);
break;
}
}
}
CACHE4_elog(DEBUG, "SearchCatCache(%s): Contains %d/%d tuples",
cache->cc_relname, cache->cc_ntup, cache->cc_maxtup);
CACHE3_elog(DEBUG, "SearchCatCache(%s): put in bucket %d",
cache->cc_relname, hash);
return &ct->tuple;
}
/* --------------------------------
* ReleaseCatCache()
*
* Decrement the reference count of a catcache entry (releasing the
* hold grabbed by a successful SearchCatCache).
*
* NOTE: if compiled with -DCATCACHE_FORCE_RELEASE then catcache entries
* will be freed as soon as their refcount goes to zero. In combination
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
* to catch references to already-released catcache entries.
* --------------------------------
*/
void
ReleaseCatCache(HeapTuple tuple)
{
CatCTup *ct = (CatCTup *) (((char *) tuple) -
offsetof(CatCTup, tuple));
/* Safety checks to ensure we were handed a cache entry */
Assert(ct->ct_magic == CT_MAGIC);
Assert(ct->refcount > 0);
ct->refcount--;
if (ct->refcount == 0
#ifndef CATCACHE_FORCE_RELEASE
&& ct->dead
#endif
)
{
/* We can find the associated cache using the dllist pointers */
Dllist *lru = DLGetListHdr(&ct->lrulist_elem);
CatCache *cache = (CatCache *) (((char *) lru) -
offsetof(CatCache, cc_lrulist));
CatCacheRemoveCTup(cache, ct);
}
} }
/* -------------------------------- /* --------------------------------

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.46 2000/10/05 19:48:29 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.47 2000/11/16 22:30:33 tgl Exp $
* *
* NOTES * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
@ -32,14 +32,11 @@
bool bool
op_class(Oid opno, Oid opclass, Oid amopid) op_class(Oid opno, Oid opclass, Oid amopid)
{ {
if (HeapTupleIsValid(SearchSysCacheTuple(AMOPOPID, return SearchSysCacheExists(AMOPOPID,
ObjectIdGetDatum(opclass), ObjectIdGetDatum(opclass),
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
ObjectIdGetDatum(amopid), ObjectIdGetDatum(amopid),
0))) 0);
return true;
else
return false;
} }
/* ---------- ATTRIBUTE CACHES ---------- */ /* ---------- ATTRIBUTE CACHES ---------- */
@ -49,21 +46,26 @@ op_class(Oid opno, Oid opclass, Oid amopid)
* *
* Given the relation id and the attribute number, * Given the relation id and the attribute number,
* return the "attname" field from the attribute relation. * return the "attname" field from the attribute relation.
*
* Note: returns a palloc'd copy of the string, or NULL if no such operator.
*/ */
char * char *
get_attname(Oid relid, AttrNumber attnum) get_attname(Oid relid, AttrNumber attnum)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(ATTNUM, tp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0); 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
char *result;
return pstrdup(NameStr(att_tup->attname)); result = pstrdup(NameStr(att_tup->attname));
ReleaseSysCache(tp);
return result;
} }
else else
return NULL; return NULL;
@ -80,15 +82,18 @@ get_attnum(Oid relid, char *attname)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(ATTNAME, tp = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
PointerGetDatum(attname), PointerGetDatum(attname),
0, 0); 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
AttrNumber result;
return att_tup->attnum; result = att_tup->attnum;
ReleaseSysCache(tp);
return result;
} }
else else
return InvalidAttrNumber; return InvalidAttrNumber;
@ -105,15 +110,18 @@ get_atttype(Oid relid, AttrNumber attnum)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(ATTNUM, tp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0); 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
Oid result;
return att_tup->atttypid; result = att_tup->atttypid;
ReleaseSysCache(tp);
return result;
} }
else else
return InvalidOid; return InvalidOid;
@ -128,15 +136,18 @@ get_attisset(Oid relid, char *attname)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(ATTNAME, tp = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
PointerGetDatum(attname), PointerGetDatum(attname),
0, 0); 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
bool result;
return att_tup->attisset; result = att_tup->attisset;
ReleaseSysCache(tp);
return result;
} }
else else
return false; return false;
@ -153,15 +164,18 @@ get_atttypmod(Oid relid, AttrNumber attnum)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(ATTNUM, tp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0); 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
int32 result;
return att_tup->atttypmod; result = att_tup->atttypmod;
ReleaseSysCache(tp);
return result;
} }
else else
return -1; return -1;
@ -185,12 +199,13 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
HeapTuple atp; HeapTuple atp;
Form_pg_attribute att_tup; Form_pg_attribute att_tup;
double dispersion; double dispersion;
Oid atttypid;
int32 ntuples; int32 ntuples;
atp = SearchSysCacheTuple(ATTNUM, atp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0); 0, 0);
if (!HeapTupleIsValid(atp)) if (!HeapTupleIsValid(atp))
{ {
/* this should not happen */ /* this should not happen */
@ -198,9 +213,14 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
relid, attnum); relid, attnum);
return min_estimate; return min_estimate;
} }
att_tup = (Form_pg_attribute) GETSTRUCT(atp); att_tup = (Form_pg_attribute) GETSTRUCT(atp);
dispersion = att_tup->attdispersion; dispersion = att_tup->attdispersion;
atttypid = att_tup->atttypid;
ReleaseSysCache(atp);
if (dispersion > 0.0) if (dispersion > 0.0)
return dispersion; /* we have a specific estimate from VACUUM */ return dispersion; /* we have a specific estimate from VACUUM */
@ -211,7 +231,7 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
* *
* Are there any other cases we should wire in special estimates for? * Are there any other cases we should wire in special estimates for?
*/ */
if (att_tup->atttypid == BOOLOID) if (atttypid == BOOLOID)
return 0.5; return 0.5;
/* /*
@ -219,9 +239,9 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
* 1/numtuples). Either way, we need the relation size. * 1/numtuples). Either way, we need the relation size.
*/ */
atp = SearchSysCacheTuple(RELOID, atp = SearchSysCache(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(atp)) if (!HeapTupleIsValid(atp))
{ {
/* this should not happen */ /* this should not happen */
@ -231,6 +251,8 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples; ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
ReleaseSysCache(atp);
if (ntuples == 0) if (ntuples == 0)
return min_estimate; /* no data available */ return min_estimate; /* no data available */
@ -277,14 +299,17 @@ get_opcode(Oid opno)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
RegProcedure result;
return optup->oprcode; result = optup->oprcode;
ReleaseSysCache(tp);
return result;
} }
else else
return (RegProcedure) InvalidOid; return (RegProcedure) InvalidOid;
@ -301,14 +326,17 @@ get_opname(Oid opno)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
char *result;
return pstrdup(NameStr(optup->oprname)); result = pstrdup(NameStr(optup->oprname));
ReleaseSysCache(tp);
return result;
} }
else else
return NULL; return NULL;
@ -324,10 +352,11 @@ bool
op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp) op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
{ {
HeapTuple tp; HeapTuple tp;
bool result = false;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
@ -339,10 +368,11 @@ op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
{ {
*leftOp = optup->oprlsortop; *leftOp = optup->oprlsortop;
*rightOp = optup->oprrsortop; *rightOp = optup->oprrsortop;
return true; result = true;
} }
ReleaseSysCache(tp);
} }
return false; return result;
} }
/* /*
@ -355,10 +385,11 @@ Oid
op_hashjoinable(Oid opno, Oid ltype, Oid rtype) op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
{ {
HeapTuple tp; HeapTuple tp;
Oid result = InvalidOid;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
@ -366,9 +397,10 @@ op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
if (optup->oprcanhash && if (optup->oprcanhash &&
optup->oprleft == ltype && optup->oprleft == ltype &&
optup->oprright == rtype) optup->oprright == rtype)
return opno; result = opno;
ReleaseSysCache(tp);
} }
return InvalidOid; return result;
} }
/* /*
@ -387,14 +419,6 @@ op_iscachable(Oid opno)
return func_iscachable((Oid) funcid); return func_iscachable((Oid) funcid);
} }
HeapTuple
get_operator_tuple(Oid opno)
{
return SearchSysCacheTuple(OPEROID,
ObjectIdGetDatum(opno),
0, 0, 0);
}
/* /*
* get_commutator * get_commutator
* *
@ -405,14 +429,17 @@ get_commutator(Oid opno)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
Oid result;
return optup->oprcom; result = optup->oprcom;
ReleaseSysCache(tp);
return result;
} }
else else
return InvalidOid; return InvalidOid;
@ -428,14 +455,17 @@ get_negator(Oid opno)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
Oid result;
return optup->oprnegate; result = optup->oprnegate;
ReleaseSysCache(tp);
return result;
} }
else else
return InvalidOid; return InvalidOid;
@ -451,14 +481,17 @@ get_oprrest(Oid opno)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
RegProcedure result;
return optup->oprrest; result = optup->oprrest;
ReleaseSysCache(tp);
return result;
} }
else else
return (RegProcedure) InvalidOid; return (RegProcedure) InvalidOid;
@ -474,14 +507,17 @@ get_oprjoin(Oid opno)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(OPEROID, tp = SearchSysCache(OPEROID,
ObjectIdGetDatum(opno), ObjectIdGetDatum(opno),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
RegProcedure result;
return optup->oprjoin; result = optup->oprjoin;
ReleaseSysCache(tp);
return result;
} }
else else
return (RegProcedure) InvalidOid; return (RegProcedure) InvalidOid;
@ -496,15 +532,18 @@ get_oprjoin(Oid opno)
Oid Oid
get_func_rettype(Oid funcid) get_func_rettype(Oid funcid)
{ {
HeapTuple func_tuple; HeapTuple tp;
Oid result;
func_tuple = SearchSysCacheTuple(PROCOID, tp = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcid), ObjectIdGetDatum(funcid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(func_tuple)) if (!HeapTupleIsValid(tp))
elog(ERROR, "Function OID %u does not exist", funcid); elog(ERROR, "Function OID %u does not exist", funcid);
return ((Form_pg_proc) GETSTRUCT(func_tuple))->prorettype; result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
ReleaseSysCache(tp);
return result;
} }
/* /*
@ -514,15 +553,18 @@ get_func_rettype(Oid funcid)
bool bool
func_iscachable(Oid funcid) func_iscachable(Oid funcid)
{ {
HeapTuple func_tuple; HeapTuple tp;
bool result;
func_tuple = SearchSysCacheTuple(PROCOID, tp = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcid), ObjectIdGetDatum(funcid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(func_tuple)) if (!HeapTupleIsValid(tp))
elog(ERROR, "Function OID %u does not exist", funcid); elog(ERROR, "Function OID %u does not exist", funcid);
return ((Form_pg_proc) GETSTRUCT(func_tuple))->proiscachable; result = ((Form_pg_proc) GETSTRUCT(tp))->proiscachable;
ReleaseSysCache(tp);
return result;
} }
/* ---------- RELATION CACHE ---------- */ /* ---------- RELATION CACHE ---------- */
@ -538,14 +580,17 @@ get_relnatts(Oid relid)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(RELOID, tp = SearchSysCache(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp); Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
int result;
return reltup->relnatts; result = reltup->relnatts;
ReleaseSysCache(tp);
return result;
} }
else else
return InvalidAttrNumber; return InvalidAttrNumber;
@ -556,20 +601,25 @@ get_relnatts(Oid relid)
* get_rel_name * get_rel_name
* *
* Returns the name of a given relation. * Returns the name of a given relation.
*
* Note: returns a palloc'd copy of the string, or NULL if no such operator.
*/ */
char * char *
get_rel_name(Oid relid) get_rel_name(Oid relid)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(RELOID, tp = SearchSysCache(RELOID,
ObjectIdGetDatum(relid), ObjectIdGetDatum(relid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp); Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
char *result;
return pstrdup(NameStr(reltup->relname)); result = pstrdup(NameStr(reltup->relname));
ReleaseSysCache(tp);
return result;
} }
else else
return NULL; return NULL;
@ -587,14 +637,17 @@ get_typlen(Oid typid)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(TYPEOID, tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid), ObjectIdGetDatum(typid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
int16 result;
return typtup->typlen; result = typtup->typlen;
ReleaseSysCache(tp);
return result;
} }
else else
return 0; return 0;
@ -611,33 +664,66 @@ get_typbyval(Oid typid)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(TYPEOID, tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid), ObjectIdGetDatum(typid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
bool result;
return typtup->typbyval; result = typtup->typbyval;
ReleaseSysCache(tp);
return result;
} }
else else
return false; return false;
} }
/*
* get_typlenbyval
*
* A two-fer: given the type OID, return both typlen and typbyval.
*
* Since both pieces of info are needed to know how to copy a Datum,
* many places need both. Might as well get them with one cache lookup
* instead of two. Also, this routine raises an error instead of
* returning a bogus value when given a bad type OID.
*/
void
get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
{
HeapTuple tp;
Form_pg_type typtup;
tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for type %u", typid);
typtup = (Form_pg_type) GETSTRUCT(tp);
*typlen = typtup->typlen;
*typbyval = typtup->typbyval;
ReleaseSysCache(tp);
}
#ifdef NOT_USED #ifdef NOT_USED
char char
get_typalign(Oid typid) get_typalign(Oid typid)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(TYPEOID, tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid), ObjectIdGetDatum(typid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
char result;
return typtup->typalign; result = typtup->typalign;
ReleaseSysCache(tp);
return result;
} }
else else
return 'i'; return 'i';
@ -666,9 +752,9 @@ get_typdefault(Oid typid)
bool typByVal; bool typByVal;
Datum returnValue; Datum returnValue;
typeTuple = SearchSysCacheTuple(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid), ObjectIdGetDatum(typid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "get_typdefault: failed to lookup type %u", typid); elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
@ -679,13 +765,17 @@ get_typdefault(Oid typid)
* First, see if there is a non-null typdefault field (usually there * First, see if there is a non-null typdefault field (usually there
* isn't) * isn't)
*/ */
typDefault = (struct varlena *) SysCacheGetAttr(TYPEOID, typDefault = (struct varlena *)
typeTuple, DatumGetPointer(SysCacheGetAttr(TYPEOID,
Anum_pg_type_typdefault, typeTuple,
&isNull); Anum_pg_type_typdefault,
&isNull));
if (isNull) if (isNull)
{
ReleaseSysCache(typeTuple);
return PointerGetDatum(NULL); return PointerGetDatum(NULL);
}
/* /*
* Otherwise, extract/copy the value. * Otherwise, extract/copy the value.
@ -748,6 +838,8 @@ get_typdefault(Oid typid)
} }
} }
ReleaseSysCache(typeTuple);
return returnValue; return returnValue;
} }
@ -764,14 +856,17 @@ get_typtype(Oid typid)
{ {
HeapTuple tp; HeapTuple tp;
tp = SearchSysCacheTuple(TYPEOID, tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid), ObjectIdGetDatum(typid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tp)) if (HeapTupleIsValid(tp))
{ {
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
char result;
return typtup->typtype; result = typtup->typtype;
ReleaseSysCache(tp);
return result;
} }
else else
return '\0'; return '\0';

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.56 2000/11/10 00:33:10 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.57 2000/11/16 22:30:33 tgl Exp $
* *
* NOTES * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
@ -343,7 +343,7 @@ static struct cachedesc cacheinfo[] = {
}; };
static CatCache *SysCache[lengthof(cacheinfo)]; static CatCache *SysCache[lengthof(cacheinfo)];
static int32 SysCacheSize = lengthof(cacheinfo); static int SysCacheSize = lengthof(cacheinfo);
static bool CacheInitialized = false; static bool CacheInitialized = false;
@ -354,99 +354,68 @@ IsCacheInitialized(void)
} }
/*
* zerocaches
*
* Make sure the SysCache structure is zero'd.
*/
void
zerocaches()
{
MemSet((char *) SysCache, 0, SysCacheSize * sizeof(CatCache *));
}
/* /*
* InitCatalogCache - initialize the caches * InitCatalogCache - initialize the caches
*
* Note that no database access is done here; we only allocate memory
* and initialize the cache structure. Interrogation of the database
* to complete initialization of a cache happens only upon first use
* of that cache.
*/ */
void void
InitCatalogCache() InitCatalogCache(void)
{ {
int cacheId; /* XXX type */ int cacheId;
if (!AMI_OVERRIDE) Assert(!CacheInitialized);
MemSet((char *) SysCache, 0, sizeof(SysCache));
for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
{ {
for (cacheId = 0; cacheId < SysCacheSize; cacheId += 1) SysCache[cacheId] = InitCatCache(cacheId,
{ cacheinfo[cacheId].name,
Assert(!PointerIsValid(SysCache[cacheId])); cacheinfo[cacheId].indname,
cacheinfo[cacheId].nkeys,
SysCache[cacheId] = InitSysCache(cacheId, cacheinfo[cacheId].key);
cacheinfo[cacheId].name, if (!PointerIsValid(SysCache[cacheId]))
cacheinfo[cacheId].indname, elog(ERROR, "InitCatalogCache: Can't init cache %s (%d)",
cacheinfo[cacheId].nkeys, cacheinfo[cacheId].name, cacheId);
cacheinfo[cacheId].key);
if (!PointerIsValid(SysCache[cacheId]))
{
elog(ERROR,
"InitCatalogCache: Can't init cache %s (%d)",
cacheinfo[cacheId].name,
cacheId);
}
}
} }
CacheInitialized = true; CacheInitialized = true;
} }
/* /*
* SearchSysCacheTuple * SearchSysCache
* *
* A layer on top of SearchSysCache that does the initialization and * A layer on top of SearchCatCache that does the initialization and
* key-setting for you. * key-setting for you.
* *
* Returns the cache copy of the tuple if one is found, NULL if not. * Returns the cache copy of the tuple if one is found, NULL if not.
* The tuple is the 'cache' copy. * The tuple is the 'cache' copy and must NOT be modified!
*
* When the caller is done using the tuple, call ReleaseSysCache()
* to release the reference count grabbed by SearchSysCache(). If this
* is not done, the tuple will remain locked in cache until end of
* transaction, which is tolerable but not desirable.
* *
* CAUTION: The tuple that is returned must NOT be freed by the caller! * CAUTION: The tuple that is returned must NOT be freed by the caller!
*
* CAUTION: The returned tuple may be flushed from the cache during
* subsequent cache lookup operations, or by shared cache invalidation.
* Callers should not expect the pointer to remain valid for long.
*
* XXX we ought to have some kind of referencecount mechanism for
* cache entries, to ensure entries aren't deleted while in use.
*/ */
HeapTuple HeapTuple
SearchSysCacheTuple(int cacheId,/* cache selection code */ SearchSysCache(int cacheId,
Datum key1, Datum key1,
Datum key2, Datum key2,
Datum key3, Datum key3,
Datum key4) Datum key4)
{ {
HeapTuple tp;
if (cacheId < 0 || cacheId >= SysCacheSize) if (cacheId < 0 || cacheId >= SysCacheSize)
{ {
elog(ERROR, "SearchSysCacheTuple: Bad cache id %d", cacheId); elog(ERROR, "SearchSysCache: Bad cache id %d", cacheId);
return (HeapTuple) NULL; return (HeapTuple) NULL;
} }
Assert(AMI_OVERRIDE || PointerIsValid(SysCache[cacheId])); Assert(PointerIsValid(SysCache[cacheId]));
if (!PointerIsValid(SysCache[cacheId]))
{
SysCache[cacheId] = InitSysCache(cacheId,
cacheinfo[cacheId].name,
cacheinfo[cacheId].indname,
cacheinfo[cacheId].nkeys,
cacheinfo[cacheId].key);
if (!PointerIsValid(SysCache[cacheId]))
elog(ERROR,
"InitCatalogCache: Can't init cache %s(%d)",
cacheinfo[cacheId].name,
cacheId);
}
/* /*
* If someone tries to look up a relname, translate temp relation * If someone tries to look up a relname, translate temp relation
@ -464,51 +433,75 @@ SearchSysCacheTuple(int cacheId,/* cache selection code */
key1 = CStringGetDatum(nontemp_relname); key1 = CStringGetDatum(nontemp_relname);
} }
tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4); return SearchCatCache(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,
cacheId, key1, key2, key3, key4);
#endif
return (HeapTuple) NULL;
}
return tp;
} }
/* /*
* SearchSysCacheTupleCopy * ReleaseSysCache
* * Release previously grabbed reference count on a tuple
* This is like SearchSysCacheTuple, except it returns a palloc'd copy of
* the tuple. The caller should heap_freetuple() the returned copy when
* done with it. This routine should be used when the caller intends to
* continue to access the tuple for more than a very short period of time.
*/ */
HeapTuple void
SearchSysCacheTupleCopy(int cacheId, /* cache selection code */ ReleaseSysCache(HeapTuple tuple)
Datum key1,
Datum key2,
Datum key3,
Datum key4)
{ {
HeapTuple cachetup; ReleaseCatCache(tuple);
cachetup = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
if (PointerIsValid(cachetup))
return heap_copytuple(cachetup);
else
return cachetup; /* NULL */
} }
/*
* SearchSysCacheCopy
*
* A convenience routine that does SearchSysCache and (if successful)
* returns a modifiable copy of the syscache entry. The original
* syscache entry is released before returning. The caller should
* heap_freetuple() the result when done with it.
*/
HeapTuple
SearchSysCacheCopy(int cacheId,
Datum key1,
Datum key2,
Datum key3,
Datum key4)
{
HeapTuple tuple,
newtuple;
tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
if (!HeapTupleIsValid(tuple))
return tuple;
newtuple = heap_copytuple(tuple);
ReleaseSysCache(tuple);
return newtuple;
}
/*
* GetSysCacheOid
*
* A convenience routine that does SearchSysCache and returns the OID
* of the found tuple, or InvalidOid if no tuple could be found.
* No lock is retained on the syscache entry.
*/
Oid
GetSysCacheOid(int cacheId,
Datum key1,
Datum key2,
Datum key3,
Datum key4)
{
HeapTuple tuple;
Oid result;
tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
if (!HeapTupleIsValid(tuple))
return InvalidOid;
result = tuple->t_data->t_oid;
ReleaseSysCache(tuple);
return result;
}
/* /*
* SysCacheGetAttr * SysCacheGetAttr
* *
* Given a tuple previously fetched by SearchSysCacheTuple() or * Given a tuple previously fetched by SearchSysCache(),
* SearchSysCacheTupleCopy(), extract a specific attribute. * extract a specific attribute.
* *
* This is equivalent to using heap_getattr() on a tuple fetched * This is equivalent to using heap_getattr() on a tuple fetched
* from a non-cached relation. Usually, this is only used for attributes * from a non-cached relation. Usually, this is only used for attributes

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.30 2000/11/08 22:10:01 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.31 2000/11/16 22:30:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -34,7 +34,6 @@
#include "catalog/heap.h" #include "catalog/heap.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/catcache.h"
#include "utils/temprel.h" #include "utils/temprel.h"

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.44 2000/07/05 23:11:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.45 2000/11/16 22:30:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -59,9 +59,9 @@ fmgr_dynamic(Oid functionId)
PGFunction user_fn; PGFunction user_fn;
bool isnull; bool isnull;
procedureTuple = SearchSysCacheTuple(PROCOID, procedureTuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(functionId), ObjectIdGetDatum(functionId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procedureTuple)) if (!HeapTupleIsValid(procedureTuple))
elog(ERROR, "fmgr_dynamic: function %u: cache lookup failed", elog(ERROR, "fmgr_dynamic: function %u: cache lookup failed",
functionId); functionId);
@ -88,6 +88,8 @@ fmgr_dynamic(Oid functionId)
pfree(prosrcstring); pfree(prosrcstring);
pfree(probinstring); pfree(probinstring);
ReleaseSysCache(procedureTuple);
return user_fn; return user_fn;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.46 2000/08/24 03:29:07 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.47 2000/11/16 22:30:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -134,9 +134,9 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
} }
/* Otherwise we need the pg_proc entry */ /* Otherwise we need the pg_proc entry */
procedureTuple = SearchSysCacheTuple(PROCOID, procedureTuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(functionId), ObjectIdGetDatum(functionId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procedureTuple)) if (!HeapTupleIsValid(procedureTuple))
elog(ERROR, "fmgr_info: function %u: cache lookup failed", elog(ERROR, "fmgr_info: function %u: cache lookup failed",
functionId); functionId);
@ -149,6 +149,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
if (!procedureStruct->proistrusted) if (!procedureStruct->proistrusted)
{ {
finfo->fn_addr = fmgr_untrusted; finfo->fn_addr = fmgr_untrusted;
ReleaseSysCache(procedureTuple);
return; return;
} }
@ -202,14 +203,12 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
/* /*
* Might be a created procedural language; try to look it up. * Might be a created procedural language; try to look it up.
*/ */
languageTuple = SearchSysCacheTuple(LANGOID, languageTuple = SearchSysCache(LANGOID,
ObjectIdGetDatum(language), ObjectIdGetDatum(language),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(languageTuple)) if (!HeapTupleIsValid(languageTuple))
{
elog(ERROR, "fmgr_info: cache lookup for language %u failed", elog(ERROR, "fmgr_info: cache lookup for language %u failed",
language); language);
}
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple); languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
if (languageStruct->lanispl) if (languageStruct->lanispl)
{ {
@ -231,8 +230,11 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
elog(ERROR, "fmgr_info: function %u: unsupported language %u", elog(ERROR, "fmgr_info: function %u: unsupported language %u",
functionId, language); functionId, language);
} }
ReleaseSysCache(languageTuple);
break; break;
} }
ReleaseSysCache(procedureTuple);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.56 2000/11/04 12:43:24 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.57 2000/11/16 22:30:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -340,12 +340,15 @@ SetSessionUserIdFromUserName(const char *username)
*/ */
AssertState(!IsBootstrapProcessingMode()); AssertState(!IsBootstrapProcessingMode());
userTup = SearchSysCacheTuple(SHADOWNAME, userTup = SearchSysCache(SHADOWNAME,
PointerGetDatum(username), PointerGetDatum(username),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(userTup)) if (!HeapTupleIsValid(userTup))
elog(FATAL, "user \"%s\" does not exist", username); elog(FATAL, "user \"%s\" does not exist", username);
SetSessionUserId( ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid ); SetSessionUserId( ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid );
ReleaseSysCache(userTup);
} }
@ -355,13 +358,19 @@ SetSessionUserIdFromUserName(const char *username)
char * char *
GetUserName(Oid userid) GetUserName(Oid userid)
{ {
HeapTuple tuple; HeapTuple tuple;
char *result;
tuple = SearchSysCacheTuple(SHADOWSYSID, ObjectIdGetDatum(userid), 0, 0, 0); tuple = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(userid),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "invalid user id %u", (unsigned) userid); elog(ERROR, "invalid user id %u", (unsigned) userid);
return pstrdup( NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename) ); result = pstrdup( NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename) );
ReleaseSysCache(tuple);
return result;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.71 2000/11/14 18:37:44 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.72 2000/11/16 22:30:39 tgl Exp $
* *
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
@ -320,10 +320,7 @@ InitPostgres(const char *dbname, const char *username)
/* /*
* Initialize all the system catalog caches. * Initialize all the system catalog caches.
*/ *
zerocaches();
/*
* Does not touch files since all routines are builtins (?) - thomas * Does not touch files since all routines are builtins (?) - thomas
* 1997-11-01 * 1997-11-01
*/ */

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.15 2000/09/06 14:15:22 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.16 2000/11/16 22:30:40 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* See superuser(). * See superuser().
@ -29,10 +29,16 @@ superuser(void)
privileges. privileges.
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
HeapTuple utup; HeapTuple utup;
bool result;
utup = SearchSysCacheTuple(SHADOWSYSID, utup = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(GetUserId()), ObjectIdGetDatum(GetUserId()),
0, 0, 0); 0, 0, 0);
Assert(utup != NULL); if (HeapTupleIsValid(utup))
return ((Form_pg_shadow) GETSTRUCT(utup))->usesuper; {
result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
ReleaseSysCache(utup);
return result;
}
return false;
} }

View File

@ -78,7 +78,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.10 2000/05/30 04:24:54 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.11 2000/11/16 22:30:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -88,7 +88,6 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "access/nbtree.h" #include "access/nbtree.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/parse_type.h"
#include "utils/logtape.h" #include "utils/logtape.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/tuplesort.h" #include "utils/tuplesort.h"
@ -506,7 +505,8 @@ tuplesort_begin_datum(Oid datumType,
bool randomAccess) bool randomAccess)
{ {
Tuplesortstate *state = tuplesort_begin_common(randomAccess); Tuplesortstate *state = tuplesort_begin_common(randomAccess);
Type typeInfo; int16 typlen;
bool typbyval;
state->comparetup = comparetup_datum; state->comparetup = comparetup_datum;
state->copytup = copytup_datum; state->copytup = copytup_datum;
@ -519,9 +519,9 @@ tuplesort_begin_datum(Oid datumType,
/* lookup the function that implements the sort operator */ /* lookup the function that implements the sort operator */
fmgr_info(get_opcode(sortOperator), &state->sortOpFn); fmgr_info(get_opcode(sortOperator), &state->sortOpFn);
/* lookup necessary attributes of the datum type */ /* lookup necessary attributes of the datum type */
typeInfo = typeidType(datumType); get_typlenbyval(datumType, &typlen, &typbyval);
state->datumTypeLen = typeLen(typeInfo); state->datumTypeLen = typlen;
state->datumTypeByVal = typeByVal(typeInfo); state->datumTypeByVal = typbyval;
return state; return state;
} }

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: hashjoin.h,v 1.19 2000/08/22 04:06:21 tgl Exp $ * $Id: hashjoin.h,v 1.20 2000/11/16 22:30:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -73,8 +73,8 @@ typedef struct HashTableData
* and outer sides of the hash are the same type, or at least * and outer sides of the hash are the same type, or at least
* binary-compatible types. * binary-compatible types.
*/ */
int16 typLen;
bool typByVal; bool typByVal;
int typLen;
/* /*
* During 1st scan of inner relation, we get tuples from executor. If * During 1st scan of inner relation, we get tuples from executor. If

View File

@ -2,12 +2,11 @@
* *
* dllist.h * dllist.h
* simple doubly linked list primitives * simple doubly linked list primitives
* the elements of the list are void* so the lists can contain * the elements of the list are void* so the lists can contain anything
* anything
* Dlelem can only be in one list at a time * Dlelem can only be in one list at a time
* *
* *
* Here's a small example of how to use Dllist's : * Here's a small example of how to use Dllists:
* *
* Dllist *lst; * Dllist *lst;
* Dlelem *elt; * Dlelem *elt;
@ -24,10 +23,18 @@
* DLFreeElem(elt); -- free the element since we don't * DLFreeElem(elt); -- free the element since we don't
* use it anymore * use it anymore
* *
*
* It is also possible to use Dllist objects that are embedded in larger
* structures instead of being separately malloc'd. To do this, use
* DLInitElem() to initialize a Dllist field within a larger object.
* Don't forget to DLRemove() each field from its list (if any) before
* freeing the larger object!
*
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: dllist.h,v 1.13 2000/06/08 22:37:46 momjian Exp $ * $Id: dllist.h,v 1.14 2000/11/16 22:30:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -35,7 +42,6 @@
#ifndef DLLIST_H #ifndef DLLIST_H
#define DLLIST_H #define DLLIST_H
struct Dllist; struct Dllist;
struct Dlelem; struct Dlelem;
@ -53,21 +59,27 @@ typedef struct Dllist
Dlelem *dll_tail; Dlelem *dll_tail;
} Dllist; } Dllist;
extern Dllist *DLNewList(void); /* initialize a new list */ extern Dllist *DLNewList(void); /* allocate and initialize a list header */
extern void DLFreeList(Dllist *); /* free up a list and all the extern void DLInitList(Dllist *list); /* init a header alloced by caller */
extern void DLFreeList(Dllist *list); /* free up a list and all the
* nodes in it */ * nodes in it */
extern Dlelem *DLNewElem(void *val); extern Dlelem *DLNewElem(void *val);
extern void DLFreeElem(Dlelem *); extern void DLInitElem(Dlelem *e, void *val);
extern Dlelem *DLGetHead(Dllist *); extern void DLFreeElem(Dlelem *e);
extern Dlelem *DLGetTail(Dllist *); extern void DLRemove(Dlelem *e); /* removes node from list */
extern Dlelem *DLRemTail(Dllist *l);
extern Dlelem *DLGetSucc(Dlelem *); /* get successor */
extern void DLRemove(Dlelem *); /* removes node from list */
extern void DLAddHead(Dllist *list, Dlelem *node); extern void DLAddHead(Dllist *list, Dlelem *node);
extern void DLAddTail(Dllist *list, Dlelem *node); extern void DLAddTail(Dllist *list, Dlelem *node);
extern Dlelem *DLRemHead(Dllist *list); /* remove and return the head */ extern Dlelem *DLRemHead(Dllist *list); /* remove and return the head */
extern void DLMoveToFront(Dlelem *); /* move node to front of its list */ extern Dlelem *DLRemTail(Dllist *list);
extern void DLMoveToFront(Dlelem *e); /* move node to front of its list */
#define DLE_VAL(x) (x->dle_val) /* These are macros for speed */
#define DLGetHead(list) ((list)->dll_head)
#define DLGetTail(list) ((list)->dll_tail)
#define DLGetSucc(elem) ((elem)->dle_next)
#define DLGetPred(elem) ((elem)->dle_prev)
#define DLGetListHdr(elem) ((elem)->dle_list)
#define DLE_VAL(elem) ((elem)->dle_val)
#endif /* DLLIST_H */ #endif /* DLLIST_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: makefuncs.h,v 1.25 2000/08/08 15:42:59 tgl Exp $ * $Id: makefuncs.h,v 1.26 2000/11/16 22:30:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -42,7 +42,8 @@ extern Const *makeConst(Oid consttype,
bool constisset, bool constisset,
bool constiscast); bool constiscast);
extern Attr * extern Const *makeNullConst(Oid consttype);
makeAttr(char *relname, char *attname);
extern Attr *makeAttr(char *relname, char *attname);
#endif /* MAKEFUNC_H */ #endif /* MAKEFUNC_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parse_oper.h,v 1.11 2000/01/26 05:58:27 momjian Exp $ * $Id: parse_oper.h,v 1.12 2000/11/16 22:30:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -18,10 +18,13 @@
typedef HeapTuple Operator; typedef HeapTuple Operator;
extern Oid any_ordering_op(Oid restype); extern Operator oper(char *op, Oid arg1, Oid arg2, bool noError);
extern Oid oprid(Operator op);
extern Operator oper(char *op, Oid arg1, Oid arg2, bool noWarnings);
extern Operator right_oper(char *op, Oid arg); extern Operator right_oper(char *op, Oid arg);
extern Operator left_oper(char *op, Oid arg); extern Operator left_oper(char *op, Oid arg);
extern Oid oper_oid(char *op, Oid arg1, Oid arg2, bool noError);
extern Oid oprid(Operator op);
extern Oid any_ordering_op(Oid restype);
#endif /* PARSE_OPER_H */ #endif /* PARSE_OPER_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parse_type.h,v 1.14 2000/06/08 22:37:53 momjian Exp $ * $Id: parse_type.h,v 1.15 2000/11/16 22:30:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -21,15 +21,18 @@ typedef HeapTuple Type;
extern bool typeidIsValid(Oid id); extern bool typeidIsValid(Oid id);
extern Type typeidType(Oid id); extern Type typeidType(Oid id);
extern Type typenameType(char *s); extern Type typenameType(char *s);
extern char *typeidTypeName(Oid id);
extern Oid typeTypeId(Type tp); extern Oid typeTypeId(Type tp);
extern int16 typeLen(Type t); extern int16 typeLen(Type t);
extern bool typeByVal(Type t); extern bool typeByVal(Type t);
extern char *typeTypeName(Type t); extern char *typeTypeName(Type t);
extern char typeTypeFlag(Type t); extern char typeTypeFlag(Type t);
extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod);
extern Oid typeidTypeRelid(Oid type_id);
extern Oid typeTypeRelid(Type typ); extern Oid typeTypeRelid(Type typ);
extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod);
extern char *typeidTypeName(Oid id);
extern Oid typeidTypeRelid(Oid type_id);
extern Oid typenameTypeId(char *s);
#define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid) #define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid)

View File

@ -7,14 +7,14 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: rewriteSupport.h,v 1.13 2000/09/29 18:21:24 tgl Exp $ * $Id: rewriteSupport.h,v 1.14 2000/11/16 22:30:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef REWRITESUPPORT_H #ifndef REWRITESUPPORT_H
#define REWRITESUPPORT_H #define REWRITESUPPORT_H
extern int IsDefinedRewriteRule(char *ruleName); extern bool IsDefinedRewriteRule(char *ruleName);
extern void SetRelationRuleStatus(Oid relationId, bool relHasRules, extern void SetRelationRuleStatus(Oid relationId, bool relHasRules,
bool relIsBecomingView); bool relIsBecomingView);

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catcache.h,v 1.27 2000/11/10 00:33:12 tgl Exp $ * $Id: catcache.h,v 1.28 2000/11/16 22:30:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -32,18 +32,29 @@
typedef struct catctup typedef struct catctup
{ {
HeapTuple ct_tup; /* A pointer to a tuple */ int ct_magic; /* for Assert checks */
#define CT_MAGIC 0x57261502
/* /*
* Each tuple in the cache has two catctup items, one in the LRU list * Each tuple in a cache is a member of two lists: one lists all the
* and one in the hashbucket list for its hash value. ct_node in each * elements in that cache in LRU order, and the other lists just the
* one points to the other one. * elements in one hashbucket, also in LRU order.
*
* A tuple marked "dead" must not be returned by subsequent searches.
* However, it won't be physically deleted from the cache until its
* refcount goes to zero.
*/ */
Dlelem *ct_node; /* the other catctup for this tuple */ Dlelem lrulist_elem; /* list member of global LRU list */
Dlelem cache_elem; /* list member of per-bucket list */
int refcount; /* number of active references */
bool dead; /* dead but not yet removed? */
HeapTupleData tuple; /* tuple management header */
} CatCTup; } CatCTup;
/* voodoo constants */ /* voodoo constants */
#define NCCBUCK 500 /* CatCache buckets */ #define NCCBUCK 500 /* CatCache buckets */
#define MAXTUP 300 /* Maximum # of tuples stored per cache */ #define MAXTUP 500 /* Maximum # of tuples stored per cache */
typedef struct catcache typedef struct catcache
@ -60,8 +71,8 @@ typedef struct catcache
short cc_key[4]; /* AttrNumber of each key */ short cc_key[4]; /* AttrNumber of each key */
PGFunction cc_hashfunc[4]; /* hash function to use for each key */ PGFunction cc_hashfunc[4]; /* hash function to use for each key */
ScanKeyData cc_skey[4]; /* precomputed key info for indexscans */ ScanKeyData cc_skey[4]; /* precomputed key info for indexscans */
Dllist *cc_lrulist; /* LRU list, most recent first */ Dllist cc_lrulist; /* overall LRU list, most recent first */
Dllist *cc_cache[NCCBUCK + 1]; /* hash buckets */ Dllist cc_cache[NCCBUCK]; /* hash buckets */
} CatCache; } CatCache;
#define InvalidCatalogCacheId (-1) #define InvalidCatalogCacheId (-1)
@ -70,12 +81,15 @@ typedef struct catcache
extern MemoryContext CacheMemoryContext; extern MemoryContext CacheMemoryContext;
extern void CreateCacheMemoryContext(void); extern void CreateCacheMemoryContext(void);
extern void AtEOXact_CatCache(bool isCommit);
extern CatCache *InitSysCache(int id, char *relname, char *indname, extern CatCache *InitCatCache(int id, char *relname, char *indname,
int nkeys, int *key); int nkeys, int *key);
extern HeapTuple SearchSysCache(CatCache *cache,
extern HeapTuple SearchCatCache(CatCache *cache,
Datum v1, Datum v2, Datum v1, Datum v2,
Datum v3, Datum v4); Datum v3, Datum v4);
extern void ReleaseCatCache(HeapTuple tuple);
extern void ResetSystemCache(void); extern void ResetSystemCache(void);
extern void SystemCacheRelationFlushed(Oid relId); extern void SystemCacheRelationFlushed(Oid relId);

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: lsyscache.h,v 1.26 2000/10/05 19:48:34 momjian Exp $ * $Id: lsyscache.h,v 1.27 2000/11/16 22:30:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -29,7 +29,6 @@ extern bool op_mergejoinable(Oid opno, Oid ltype, Oid rtype,
Oid *leftOp, Oid *rightOp); Oid *leftOp, Oid *rightOp);
extern Oid op_hashjoinable(Oid opno, Oid ltype, Oid rtype); extern Oid op_hashjoinable(Oid opno, Oid ltype, Oid rtype);
extern bool op_iscachable(Oid opno); extern bool op_iscachable(Oid opno);
extern HeapTuple get_operator_tuple(Oid opno);
extern Oid get_commutator(Oid opno); extern Oid get_commutator(Oid opno);
extern Oid get_negator(Oid opno); extern Oid get_negator(Oid opno);
extern RegProcedure get_oprrest(Oid opno); extern RegProcedure get_oprrest(Oid opno);
@ -39,6 +38,7 @@ extern bool func_iscachable(Oid funcid);
extern char *get_rel_name(Oid relid); extern char *get_rel_name(Oid relid);
extern int16 get_typlen(Oid typid); extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid); extern bool get_typbyval(Oid typid);
extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
extern Datum get_typdefault(Oid typid); extern Datum get_typdefault(Oid typid);
#endif /* LSYSCACHE_H */ #endif /* LSYSCACHE_H */

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: syscache.h,v 1.26 2000/06/17 04:56:29 tgl Exp $ * $Id: syscache.h,v 1.27 2000/11/16 22:30:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -57,12 +57,22 @@
#define TYPENAME 26 #define TYPENAME 26
#define TYPEOID 27 #define TYPEOID 27
extern void zerocaches(void);
extern void InitCatalogCache(void); extern void InitCatalogCache(void);
extern HeapTuple SearchSysCacheTuple(int cacheId,
extern HeapTuple SearchSysCache(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4); Datum key1, Datum key2, Datum key3, Datum key4);
extern HeapTuple SearchSysCacheTupleCopy(int cacheId, extern void ReleaseSysCache(HeapTuple tuple);
Datum key1, Datum key2, Datum key3, Datum key4);
/* convenience routines */
extern HeapTuple SearchSysCacheCopy(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
extern Oid GetSysCacheOid(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
/* macro for just probing for existence of a tuple via the syscache */
#define SearchSysCacheExists(c,k1,k2,k3,k4) \
OidIsValid(GetSysCacheOid(c,k1,k2,k3,k4))
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup, extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
AttrNumber attributeNumber, bool *isNull); AttrNumber attributeNumber, bool *isNull);

View File

@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.14 2000/10/24 17:01:05 tgl Exp $ * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.15 2000/11/16 22:30:49 tgl Exp $
* *
**********************************************************************/ **********************************************************************/
@ -521,9 +521,9 @@ plperl_func_handler(PG_FUNCTION_ARGS)
/************************************************************ /************************************************************
* Lookup the pg_proc tuple by Oid * Lookup the pg_proc tuple by Oid
************************************************************/ ************************************************************/
procTup = SearchSysCacheTuple(PROCOID, procTup = SearchSysCache(PROCOID,
ObjectIdGetDatum(fcinfo->flinfo->fn_oid), ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procTup)) if (!HeapTupleIsValid(procTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -537,9 +537,9 @@ plperl_func_handler(PG_FUNCTION_ARGS)
* Get the required information for input conversion of the * Get the required information for input conversion of the
* return value. * return value.
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->prorettype), ObjectIdGetDatum(procStruct->prorettype),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -560,6 +560,8 @@ plperl_func_handler(PG_FUNCTION_ARGS)
prodesc->result_in_elem = (Oid) (typeStruct->typelem); prodesc->result_in_elem = (Oid) (typeStruct->typelem);
prodesc->result_in_len = typeStruct->typlen; prodesc->result_in_len = typeStruct->typlen;
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* Get the required information for output conversion * Get the required information for output conversion
* of all procedure arguments * of all procedure arguments
@ -567,9 +569,9 @@ plperl_func_handler(PG_FUNCTION_ARGS)
prodesc->nargs = procStruct->pronargs; prodesc->nargs = procStruct->pronargs;
for (i = 0; i < prodesc->nargs; i++) for (i = 0; i < prodesc->nargs; i++)
{ {
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->proargtypes[i]), ObjectIdGetDatum(procStruct->proargtypes[i]),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -587,7 +589,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
fmgr_info(typeStruct->typoutput, &(prodesc->arg_out_func[i])); fmgr_info(typeStruct->typoutput, &(prodesc->arg_out_func[i]));
prodesc->arg_out_elem[i] = (Oid) (typeStruct->typelem); prodesc->arg_out_elem[i] = (Oid) (typeStruct->typelem);
prodesc->arg_out_len[i] = typeStruct->typlen; prodesc->arg_out_len[i] = typeStruct->typlen;
ReleaseSysCache(typeTup);
} }
/************************************************************ /************************************************************
@ -617,6 +619,8 @@ plperl_func_handler(PG_FUNCTION_ARGS)
************************************************************/ ************************************************************/
hv_store(plperl_proc_hash, internal_proname, proname_len, hv_store(plperl_proc_hash, internal_proname, proname_len,
newSViv((IV) prodesc), 0); newSViv((IV) prodesc), 0);
ReleaseSysCache(procTup);
} }
else else
{ {
@ -744,9 +748,9 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
/************************************************************ /************************************************************
* Lookup the pg_proc tuple by Oid * Lookup the pg_proc tuple by Oid
************************************************************/ ************************************************************/
procTup = SearchSysCacheTuple(PROCOID, procTup = SearchSysCache(PROCOID,
ObjectIdGetDatum(fcinfo->flinfo->fn_oid), ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procTup)) if (!HeapTupleIsValid(procTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -819,6 +823,8 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
hashent = Tcl_CreateHashEntry(plperl_proc_hash, hashent = Tcl_CreateHashEntry(plperl_proc_hash,
prodesc->proname, &hashnew); prodesc->proname, &hashnew);
Tcl_SetHashValue(hashent, (ClientData) prodesc); Tcl_SetHashValue(hashent, (ClientData) prodesc);
ReleaseSysCache(procTup);
} }
else else
{ {
@ -1068,9 +1074,9 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
* Lookup the attribute type in the syscache * Lookup the attribute type in the syscache
* for the input function * for the input function
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[attnum - 1]->atttypid), ObjectIdGetDatum(tupdesc->attrs[attnum - 1]->atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed", elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed",
@ -1079,6 +1085,7 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
} }
typinput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typinput); typinput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typinput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem); typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* Set the attribute to NOT NULL and convert the contents * Set the attribute to NOT NULL and convert the contents
@ -1538,9 +1545,9 @@ plperl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
************************************************************/ ************************************************************/
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ {
typeTup = SearchSysCacheTuple(TYPNAME, typeTup = SearchSysCache(TYPNAME,
PointerGetDatum(args[i]), PointerGetDatum(args[i]),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
elog(ERROR, "plperl: Cache lookup of type %s failed", args[i]); elog(ERROR, "plperl: Cache lookup of type %s failed", args[i]);
qdesc->argtypes[i] = typeTup->t_data->t_oid; qdesc->argtypes[i] = typeTup->t_data->t_oid;
@ -1549,6 +1556,7 @@ plperl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem; qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
qdesc->argvalues[i] = (Datum) NULL; qdesc->argvalues[i] = (Datum) NULL;
qdesc->arglen[i] = (int) (((Form_pg_type) GETSTRUCT(typeTup))->typlen); qdesc->arglen[i] = (int) (((Form_pg_type) GETSTRUCT(typeTup))->typlen);
ReleaseSysCache(typeTup);
} }
/************************************************************ /************************************************************
@ -2084,9 +2092,9 @@ plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
* Lookup the attribute type in the syscache * Lookup the attribute type in the syscache
* for the output function * for the output function
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid), ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed", elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed",
@ -2095,6 +2103,7 @@ plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput); typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem); typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* If there is a value, set the variable * If there is a value, set the variable
@ -2156,9 +2165,9 @@ plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
* Lookup the attribute type in the syscache * Lookup the attribute type in the syscache
* for the output function * for the output function
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid), ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed", elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed",
@ -2167,6 +2176,7 @@ plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput); typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem); typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* If there is a value, append the attribute name and the * If there is a value, append the attribute name and the

View File

@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.23 2000/08/31 13:26:16 wieck Exp $ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.24 2000/11/16 22:30:50 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
@ -53,7 +53,6 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/catcache.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
@ -131,9 +130,9 @@ plpgsql_compile(Oid fn_oid, int functype)
* Lookup the pg_proc tuple by Oid * Lookup the pg_proc tuple by Oid
* ---------- * ----------
*/ */
procTup = SearchSysCacheTuple(PROCOID, procTup = SearchSysCache(PROCOID,
ObjectIdGetDatum(fn_oid), ObjectIdGetDatum(fn_oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procTup)) if (!HeapTupleIsValid(procTup))
elog(ERROR, "plpgsql: cache lookup for proc %u failed", fn_oid); elog(ERROR, "plpgsql: cache lookup for proc %u failed", fn_oid);
@ -176,9 +175,9 @@ plpgsql_compile(Oid fn_oid, int functype)
* Lookup the functions return type * Lookup the functions return type
* ---------- * ----------
*/ */
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->prorettype), 0, 0, 0); ObjectIdGetDatum(procStruct->prorettype),
0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
plpgsql_comperrinfo(); plpgsql_comperrinfo();
@ -195,6 +194,7 @@ plpgsql_compile(Oid fn_oid, int functype)
function->fn_rettypelem = typeStruct->typelem; function->fn_rettypelem = typeStruct->typelem;
fmgr_info(typeStruct->typinput, &(function->fn_retinput)); fmgr_info(typeStruct->typinput, &(function->fn_retinput));
} }
ReleaseSysCache(typeTup);
/* ---------- /* ----------
* Create the variables for the procedures parameters * Create the variables for the procedures parameters
@ -208,9 +208,9 @@ plpgsql_compile(Oid fn_oid, int functype)
* Get the parameters type * Get the parameters type
* ---------- * ----------
*/ */
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->proargtypes[i]), 0, 0, 0); ObjectIdGetDatum(procStruct->proargtypes[i]),
0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
plpgsql_comperrinfo(); plpgsql_comperrinfo();
@ -276,6 +276,7 @@ plpgsql_compile(Oid fn_oid, int functype)
arg_varnos[i] = var->varno; arg_varnos[i] = var->varno;
} }
ReleaseSysCache(typeTup);
} }
break; break;
@ -512,6 +513,7 @@ plpgsql_compile(Oid fn_oid, int functype)
function->datums[i] = plpgsql_Datums[i]; function->datums[i] = plpgsql_Datums[i];
function->action = plpgsql_yylval.program; function->action = plpgsql_yylval.program;
ReleaseSysCache(procTup);
/* ---------- /* ----------
* Finally return the compiled function * Finally return the compiled function
@ -608,8 +610,9 @@ plpgsql_parse_word(char *word)
* ---------- * ----------
*/ */
typeXlated = xlateSqlType(cp); typeXlated = xlateSqlType(cp);
typeTup = SearchSysCacheTuple(TYPENAME, typeTup = SearchSysCache(TYPENAME,
PointerGetDatum(typeXlated), 0, 0, 0); PointerGetDatum(typeXlated),
0, 0, 0);
if (HeapTupleIsValid(typeTup)) if (HeapTupleIsValid(typeTup))
{ {
PLpgSQL_type *typ; PLpgSQL_type *typ;
@ -618,6 +621,7 @@ plpgsql_parse_word(char *word)
if (typeStruct->typrelid != InvalidOid) if (typeStruct->typrelid != InvalidOid)
{ {
ReleaseSysCache(typeTup);
pfree(cp); pfree(cp);
return T_WORD; return T_WORD;
} }
@ -634,6 +638,7 @@ plpgsql_parse_word(char *word)
plpgsql_yylval.dtype = typ; plpgsql_yylval.dtype = typ;
ReleaseSysCache(typeTup);
pfree(cp); pfree(cp);
return T_DTYPE; return T_DTYPE;
} }
@ -933,8 +938,9 @@ plpgsql_parse_wordtype(char *word)
* ---------- * ----------
*/ */
typeXlated = xlateSqlType(cp); typeXlated = xlateSqlType(cp);
typeTup = SearchSysCacheTuple(TYPENAME, typeTup = SearchSysCache(TYPENAME,
PointerGetDatum(typeXlated), 0, 0, 0); PointerGetDatum(typeXlated),
0, 0, 0);
if (HeapTupleIsValid(typeTup)) if (HeapTupleIsValid(typeTup))
{ {
PLpgSQL_type *typ; PLpgSQL_type *typ;
@ -943,6 +949,7 @@ plpgsql_parse_wordtype(char *word)
if (typeStruct->typrelid != InvalidOid) if (typeStruct->typrelid != InvalidOid)
{ {
ReleaseSysCache(typeTup);
pfree(cp); pfree(cp);
return T_ERROR; return T_ERROR;
} }
@ -959,6 +966,7 @@ plpgsql_parse_wordtype(char *word)
plpgsql_yylval.dtype = typ; plpgsql_yylval.dtype = typ;
ReleaseSysCache(typeTup);
pfree(cp); pfree(cp);
return T_DTYPE; return T_DTYPE;
} }
@ -1045,8 +1053,9 @@ plpgsql_parse_dblwordtype(char *string)
* First word could also be a table name * First word could also be a table name
* ---------- * ----------
*/ */
classtup = SearchSysCacheTuple(RELNAME, classtup = SearchSysCache(RELNAME,
PointerGetDatum(word1), 0, 0, 0); PointerGetDatum(word1),
0, 0, 0);
if (!HeapTupleIsValid(classtup)) if (!HeapTupleIsValid(classtup))
{ {
pfree(word1); pfree(word1);
@ -1060,6 +1069,7 @@ plpgsql_parse_dblwordtype(char *string)
classStruct = (Form_pg_class) GETSTRUCT(classtup); classStruct = (Form_pg_class) GETSTRUCT(classtup);
if (classStruct->relkind != 'r' && classStruct->relkind != 's') if (classStruct->relkind != 'r' && classStruct->relkind != 's')
{ {
ReleaseSysCache(classtup);
pfree(word1); pfree(word1);
return T_ERROR; return T_ERROR;
} }
@ -1068,31 +1078,33 @@ plpgsql_parse_dblwordtype(char *string)
* Fetch the named table field and it's type * Fetch the named table field and it's type
* ---------- * ----------
*/ */
attrtup = SearchSysCacheTuple(ATTNAME, attrtup = SearchSysCache(ATTNAME,
ObjectIdGetDatum(classtup->t_data->t_oid), ObjectIdGetDatum(classtup->t_data->t_oid),
PointerGetDatum(word2), 0, 0); PointerGetDatum(word2),
0, 0);
if (!HeapTupleIsValid(attrtup)) if (!HeapTupleIsValid(attrtup))
{ {
ReleaseSysCache(classtup);
pfree(word1); pfree(word1);
return T_ERROR; return T_ERROR;
} }
attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup); attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0); ObjectIdGetDatum(attrStruct->atttypid),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
{ {
plpgsql_comperrinfo(); plpgsql_comperrinfo();
elog(ERROR, "cache lookup for type %u of %s.%s failed", elog(ERROR, "cache lookup for type %u of %s.%s failed",
attrStruct->atttypid, word1, word2); attrStruct->atttypid, word1, word2);
} }
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
/* ---------- /* ----------
* Found that - build a compiler type struct and return it * Found that - build a compiler type struct and return it
* ---------- * ----------
*/ */
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type)); typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
typ->typname = DatumGetCString(DirectFunctionCall1(nameout, typ->typname = DatumGetCString(DirectFunctionCall1(nameout,
@ -1105,6 +1117,9 @@ plpgsql_parse_dblwordtype(char *string)
plpgsql_yylval.dtype = typ; plpgsql_yylval.dtype = typ;
ReleaseSysCache(classtup);
ReleaseSysCache(attrtup);
ReleaseSysCache(typetup);
pfree(word1); pfree(word1);
return T_DTYPE; return T_DTYPE;
} }
@ -1138,8 +1153,9 @@ plpgsql_parse_wordrowtype(char *string)
cp = strchr(word1, '%'); cp = strchr(word1, '%');
*cp = '\0'; *cp = '\0';
classtup = SearchSysCacheTuple(RELNAME, classtup = SearchSysCache(RELNAME,
PointerGetDatum(word1), 0, 0, 0); PointerGetDatum(word1),
0, 0, 0);
if (!HeapTupleIsValid(classtup)) if (!HeapTupleIsValid(classtup))
{ {
plpgsql_comperrinfo(); plpgsql_comperrinfo();
@ -1156,8 +1172,9 @@ plpgsql_parse_wordrowtype(char *string)
* Fetch the tables pg_type tuple too * Fetch the tables pg_type tuple too
* ---------- * ----------
*/ */
typetup = SearchSysCacheTuple(TYPENAME, typetup = SearchSysCache(TYPENAME,
PointerGetDatum(word1), 0, 0, 0); PointerGetDatum(word1),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
{ {
plpgsql_comperrinfo(); plpgsql_comperrinfo();
@ -1178,15 +1195,18 @@ plpgsql_parse_wordrowtype(char *string)
row->fieldnames = malloc(sizeof(char *) * row->nfields); row->fieldnames = malloc(sizeof(char *) * row->nfields);
row->varnos = malloc(sizeof(int) * row->nfields); row->varnos = malloc(sizeof(int) * row->nfields);
ReleaseSysCache(typetup);
for (i = 0; i < row->nfields; i++) for (i = 0; i < row->nfields; i++)
{ {
/* ---------- /* ----------
* Get the attribute and it's type * Get the attribute and it's type
* ---------- * ----------
*/ */
attrtup = SearchSysCacheTuple(ATTNUM, attrtup = SearchSysCache(ATTNUM,
ObjectIdGetDatum(classtup->t_data->t_oid), ObjectIdGetDatum(classtup->t_data->t_oid),
(Datum) (i + 1), 0, 0); Int16GetDatum(i + 1),
0, 0);
if (!HeapTupleIsValid(attrtup)) if (!HeapTupleIsValid(attrtup))
{ {
plpgsql_comperrinfo(); plpgsql_comperrinfo();
@ -1198,8 +1218,9 @@ plpgsql_parse_wordrowtype(char *string)
cp = DatumGetCString(DirectFunctionCall1(nameout, cp = DatumGetCString(DirectFunctionCall1(nameout,
NameGetDatum(&(attrStruct->attname)))); NameGetDatum(&(attrStruct->attname))));
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0); ObjectIdGetDatum(attrStruct->atttypid),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
{ {
plpgsql_comperrinfo(); plpgsql_comperrinfo();
@ -1238,6 +1259,9 @@ plpgsql_parse_wordrowtype(char *string)
var->isnull = true; var->isnull = true;
var->shouldfree = false; var->shouldfree = false;
ReleaseSysCache(typetup);
ReleaseSysCache(attrtup);
plpgsql_adddatum((PLpgSQL_datum *) var); plpgsql_adddatum((PLpgSQL_datum *) var);
/* ---------- /* ----------
@ -1248,6 +1272,8 @@ plpgsql_parse_wordrowtype(char *string)
row->varnos[i] = var->varno; row->varnos[i] = var->varno;
} }
ReleaseSysCache(classtup);
/* ---------- /* ----------
* Return the complete row definition * Return the complete row definition
* ---------- * ----------

View File

@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.31 2000/09/12 19:41:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.32 2000/11/16 22:30:50 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
@ -1641,10 +1641,12 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
extval = "<NULL>"; extval = "<NULL>";
else else
{ {
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(var->datatype->typoid), 0, 0, 0); ObjectIdGetDatum(var->datatype->typoid),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed (1)", var->datatype->typoid); elog(ERROR, "cache lookup for type %u failed (1)",
var->datatype->typoid);
typeStruct = (Form_pg_type) GETSTRUCT(typetup); typeStruct = (Form_pg_type) GETSTRUCT(typetup);
fmgr_info(typeStruct->typoutput, &finfo_output); fmgr_info(typeStruct->typoutput, &finfo_output);
@ -1652,6 +1654,7 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
var->value, var->value,
ObjectIdGetDatum(typeStruct->typelem), ObjectIdGetDatum(typeStruct->typelem),
Int32GetDatum(var->datatype->atttypmod))); Int32GetDatum(var->datatype->atttypmod)));
ReleaseSysCache(typetup);
} }
plpgsql_dstring_append(&ds, extval); plpgsql_dstring_append(&ds, extval);
break; break;
@ -1961,21 +1964,24 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate,
* Get the C-String representation. * Get the C-String representation.
* ---------- * ----------
*/ */
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(restype), 0, 0, 0); ObjectIdGetDatum(restype),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed (1)", restype); elog(ERROR, "cache lookup for type %u failed (1)", restype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup); typeStruct = (Form_pg_type) GETSTRUCT(typetup);
fmgr_info(typeStruct->typoutput, &finfo_output); fmgr_info(typeStruct->typoutput, &finfo_output);
querystr = DatumGetCString(FunctionCall3(&finfo_output, querystr = DatumGetCString(FunctionCall3(&finfo_output,
query, query,
ObjectIdGetDatum(typeStruct->typelem), ObjectIdGetDatum(typeStruct->typelem),
Int32GetDatum(-1))); Int32GetDatum(-1)));
if(!typeStruct->typbyval) if(!typeStruct->typbyval)
pfree((void *)query); pfree((void *)query);
ReleaseSysCache(typetup);
/* ---------- /* ----------
* Call SPI_exec() without preparing a saved plan. * Call SPI_exec() without preparing a saved plan.
* The returncode can be any OK except for OK_SELECT. * The returncode can be any OK except for OK_SELECT.
@ -2064,8 +2070,9 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
* Get the C-String representation. * Get the C-String representation.
* ---------- * ----------
*/ */
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(restype), 0, 0, 0); ObjectIdGetDatum(restype),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed (1)", restype); elog(ERROR, "cache lookup for type %u failed (1)", restype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup); typeStruct = (Form_pg_type) GETSTRUCT(typetup);
@ -2079,6 +2086,8 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
if(!typeStruct->typbyval) if(!typeStruct->typbyval)
pfree((void *)query); pfree((void *)query);
ReleaseSysCache(typetup);
/* ---------- /* ----------
* Run the query * Run the query
* ---------- * ----------
@ -2283,8 +2292,9 @@ exec_assign_value(PLpgSQL_execstate * estate,
*/ */
atttype = SPI_gettypeid(rec->tupdesc, i + 1); atttype = SPI_gettypeid(rec->tupdesc, i + 1);
atttypmod = rec->tupdesc->attrs[i]->atttypmod; atttypmod = rec->tupdesc->attrs[i]->atttypmod;
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(atttype), 0, 0, 0); ObjectIdGetDatum(atttype),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed", atttype); elog(ERROR, "cache lookup for type %u failed", atttype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup); typeStruct = (Form_pg_type) GETSTRUCT(typetup);
@ -2299,6 +2309,7 @@ exec_assign_value(PLpgSQL_execstate * estate,
nulls[i] = 'n'; nulls[i] = 'n';
else else
nulls[i] = ' '; nulls[i] = ' ';
ReleaseSysCache(typetup);
} }
/* ---------- /* ----------
@ -2603,9 +2614,13 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate,
* so that we can free the expression context. * so that we can free the expression context.
*/ */
if (! *isNull) if (! *isNull)
retval = datumCopy(retval, {
get_typbyval(*rettype), int16 typeLength;
get_typlen(*rettype)); bool byValue;
get_typlenbyval(*rettype, &typeLength, &byValue);
retval = datumCopy(retval, byValue, typeLength);
}
FreeExprContext(econtext); FreeExprContext(econtext);
@ -2726,8 +2741,9 @@ exec_cast_value(Datum value, Oid valtype,
FmgrInfo finfo_output; FmgrInfo finfo_output;
char *extval; char *extval;
typetup = SearchSysCacheTuple(TYPEOID, typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(valtype), 0, 0, 0); ObjectIdGetDatum(valtype),
0, 0, 0);
if (!HeapTupleIsValid(typetup)) if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed", valtype); elog(ERROR, "cache lookup for type %u failed", valtype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup); typeStruct = (Form_pg_type) GETSTRUCT(typetup);
@ -2742,6 +2758,7 @@ exec_cast_value(Datum value, Oid valtype,
ObjectIdGetDatum(reqtypelem), ObjectIdGetDatum(reqtypelem),
Int32GetDatum(reqtypmod)); Int32GetDatum(reqtypmod));
pfree(extval); pfree(extval);
ReleaseSysCache(typetup);
} }
} }

View File

@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.28 2000/07/19 11:53:02 wieck Exp $ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.29 2000/11/16 22:30:52 tgl Exp $
* *
**********************************************************************/ **********************************************************************/
@ -437,9 +437,9 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
/************************************************************ /************************************************************
* Lookup the pg_proc tuple by Oid * Lookup the pg_proc tuple by Oid
************************************************************/ ************************************************************/
procTup = SearchSysCacheTuple(PROCOID, procTup = SearchSysCache(PROCOID,
ObjectIdGetDatum(fcinfo->flinfo->fn_oid), ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procTup)) if (!HeapTupleIsValid(procTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -452,9 +452,9 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
/************************************************************ /************************************************************
* Lookup the pg_language tuple by Oid * Lookup the pg_language tuple by Oid
************************************************************/ ************************************************************/
langTup = SearchSysCacheTuple(LANGOID, langTup = SearchSysCache(LANGOID,
ObjectIdGetDatum(procStruct->prolang), ObjectIdGetDatum(procStruct->prolang),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(langTup)) if (!HeapTupleIsValid(langTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -469,14 +469,15 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
interp = pltcl_safe_interp; interp = pltcl_safe_interp;
else else
interp = pltcl_norm_interp; interp = pltcl_norm_interp;
ReleaseSysCache(langTup);
/************************************************************ /************************************************************
* Get the required information for input conversion of the * Get the required information for input conversion of the
* return value. * return value.
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->prorettype), ObjectIdGetDatum(procStruct->prorettype),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -496,6 +497,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
fmgr_info(typeStruct->typinput, &(prodesc->result_in_func)); fmgr_info(typeStruct->typinput, &(prodesc->result_in_func));
prodesc->result_in_elem = typeStruct->typelem; prodesc->result_in_elem = typeStruct->typelem;
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* Get the required information for output conversion * Get the required information for output conversion
* of all procedure arguments * of all procedure arguments
@ -504,9 +507,9 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
proc_internal_args[0] = '\0'; proc_internal_args[0] = '\0';
for (i = 0; i < prodesc->nargs; i++) for (i = 0; i < prodesc->nargs; i++)
{ {
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->proargtypes[i]), ObjectIdGetDatum(procStruct->proargtypes[i]),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -523,6 +526,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
strcat(proc_internal_args, " "); strcat(proc_internal_args, " ");
sprintf(buf, "__PLTcl_Tup_%d", i + 1); sprintf(buf, "__PLTcl_Tup_%d", i + 1);
strcat(proc_internal_args, buf); strcat(proc_internal_args, buf);
ReleaseSysCache(typeTup);
continue; continue;
} }
else else
@ -536,6 +540,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
strcat(proc_internal_args, " "); strcat(proc_internal_args, " ");
sprintf(buf, "%d", i + 1); sprintf(buf, "%d", i + 1);
strcat(proc_internal_args, buf); strcat(proc_internal_args, buf);
ReleaseSysCache(typeTup);
} }
/************************************************************ /************************************************************
@ -591,6 +597,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
hashent = Tcl_CreateHashEntry(pltcl_proc_hash, hashent = Tcl_CreateHashEntry(pltcl_proc_hash,
prodesc->proname, &hashnew); prodesc->proname, &hashnew);
Tcl_SetHashValue(hashent, (ClientData) prodesc); Tcl_SetHashValue(hashent, (ClientData) prodesc);
ReleaseSysCache(procTup);
} }
else else
{ {
@ -800,9 +808,9 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
/************************************************************ /************************************************************
* Lookup the pg_proc tuple by Oid * Lookup the pg_proc tuple by Oid
************************************************************/ ************************************************************/
procTup = SearchSysCacheTuple(PROCOID, procTup = SearchSysCache(PROCOID,
ObjectIdGetDatum(fcinfo->flinfo->fn_oid), ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(procTup)) if (!HeapTupleIsValid(procTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -815,9 +823,9 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
/************************************************************ /************************************************************
* Lookup the pg_language tuple by Oid * Lookup the pg_language tuple by Oid
************************************************************/ ************************************************************/
langTup = SearchSysCacheTuple(LANGOID, langTup = SearchSysCache(LANGOID,
ObjectIdGetDatum(procStruct->prolang), ObjectIdGetDatum(procStruct->prolang),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(langTup)) if (!HeapTupleIsValid(langTup))
{ {
free(prodesc->proname); free(prodesc->proname);
@ -832,6 +840,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
interp = pltcl_safe_interp; interp = pltcl_safe_interp;
else else
interp = pltcl_norm_interp; interp = pltcl_norm_interp;
ReleaseSysCache(langTup);
/************************************************************ /************************************************************
* Create the tcl command to define the internal * Create the tcl command to define the internal
@ -896,6 +905,8 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
hashent = Tcl_CreateHashEntry(pltcl_proc_hash, hashent = Tcl_CreateHashEntry(pltcl_proc_hash,
prodesc->proname, &hashnew); prodesc->proname, &hashnew);
Tcl_SetHashValue(hashent, (ClientData) prodesc); Tcl_SetHashValue(hashent, (ClientData) prodesc);
ReleaseSysCache(procTup);
} }
else else
{ {
@ -1151,9 +1162,9 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
* Lookup the attribute type in the syscache * Lookup the attribute type in the syscache
* for the input function * for the input function
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[attnum - 1]->atttypid), ObjectIdGetDatum(tupdesc->attrs[attnum - 1]->atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed", elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed",
@ -1162,6 +1173,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
} }
typinput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typinput); typinput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typinput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem); typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* Set the attribute to NOT NULL and convert the contents * Set the attribute to NOT NULL and convert the contents
@ -1706,9 +1718,9 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
************************************************************/ ************************************************************/
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ {
typeTup = SearchSysCacheTuple(TYPENAME, typeTup = SearchSysCache(TYPENAME,
PointerGetDatum(args[i]), PointerGetDatum(args[i]),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
elog(ERROR, "pltcl: Cache lookup of type %s failed", args[i]); elog(ERROR, "pltcl: Cache lookup of type %s failed", args[i]);
qdesc->argtypes[i] = typeTup->t_data->t_oid; qdesc->argtypes[i] = typeTup->t_data->t_oid;
@ -1717,6 +1729,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem; qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
qdesc->argvalues[i] = (Datum) NULL; qdesc->argvalues[i] = (Datum) NULL;
qdesc->arglen[i] = (int) (((Form_pg_type) GETSTRUCT(typeTup))->typlen); qdesc->arglen[i] = (int) (((Form_pg_type) GETSTRUCT(typeTup))->typlen);
ReleaseSysCache(typeTup);
} }
/************************************************************ /************************************************************
@ -2263,9 +2276,9 @@ pltcl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
* Lookup the attribute type in the syscache * Lookup the attribute type in the syscache
* for the output function * for the output function
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid), ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed", elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed",
@ -2274,6 +2287,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput); typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem); typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* If there is a value, set the variable * If there is a value, set the variable
@ -2332,9 +2346,9 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
* Lookup the attribute type in the syscache * Lookup the attribute type in the syscache
* for the output function * for the output function
************************************************************/ ************************************************************/
typeTup = SearchSysCacheTuple(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid), ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTup)) if (!HeapTupleIsValid(typeTup))
{ {
elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed", elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed",
@ -2343,6 +2357,7 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput); typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem); typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
ReleaseSysCache(typeTup);
/************************************************************ /************************************************************
* If there is a value, append the attribute name and the * If there is a value, append the attribute name and the