Commit a933ee38 authored by Tom Lane's avatar Tom Lane

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.
parent cff23842
...@@ -14,30 +14,29 @@ ...@@ -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) ...@@ -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);
......
...@@ -311,7 +311,7 @@ c-mode) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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()?
......
...@@ -358,7 +358,7 @@ cases where Name and char * are used interchangeably.<P> ...@@ -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 ...@@ -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> ...@@ -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: ...@@ -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>
......
...@@ -9,7 +9,7 @@ ...@@ -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); ...@@ -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 ...@@ -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,
ObjectIdGetDatum(type), typeTuple = SearchSysCache(TYPEOID,
0, 0, 0); ObjectIdGetDatum(type),
0, 0, 0);
if (HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
{ elog(ERROR, "getTypeOutAndElem: Cache lookup of type %u failed", type);
Form_pg_type pt = (Form_pg_type) GETSTRUCT(typeTuple); pt = (Form_pg_type) GETSTRUCT(typeTuple);
*typOutput = (Oid) pt->typoutput; *typOutput = pt->typoutput;
*typElem = (Oid) pt->typelem; *typElem = pt->typelem;
return OidIsValid(*typOutput); ReleaseSysCache(typeTuple);
} return OidIsValid(*typOutput);
elog(ERROR, "getTypeOutAndElem: Cache lookup of type %u failed", type);
*typOutput = InvalidOid;
*typElem = InvalidOid;
return 0;
} }
/* ---------------- /* ----------------
......
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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))
{ {
/* ---------------- /* ----------------
......
...@@ -6,7 +6,7 @@ ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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));
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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();
......
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
} }
...@@ -8,7 +8,7 @@ ...@@ -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 @@ ...@@ -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() ...@@ -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) ...@@ -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)) * Check if the attr is a set before messing with the length
* and byval, since those were already set in
* TupleDescInitEntry. In fact, this seems redundant here,
* but who knows what I'll break if I take it out...
*/
if (!(*attributeP)->attisset)
{ {
elog(ERROR, "fillatt: unknown atttypid %d", get_typlenbyval((*attributeP)->atttypid,
(*attributeP)->atttypid); & (*attributeP)->attlen,
& (*attributeP)->attbyval);
} }
else
{
(*attributeP)->attnum = (int16) ++i;
/* attributeP++;
* Check if the attr is a set before messing with the length
* and byval, since those were already set in
* TupleDescInitEntry. In fact, this seems redundant here,
* but who knows what I'll break if I take it out...
*/
if (!(*attributeP)->attisset)
{
typp = (Form_pg_type) GETSTRUCT(tuple); /* XXX */
(*attributeP)->attlen = typp->typlen;
(*attributeP)->attbyval = typp->typbyval;
}
}
attributeP += 1;
} }
} }
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -9,7 +9,7 @@ ...@@ -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, ...@@ -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,
......
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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),
......
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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))
if (!HeapTupleIsValid(oldtup)) elog(ERROR, "TypeRename: type \"%s\" not defined", oldTypeName);
{
heap_close(pg_type_desc, RowExclusiveLock);
elog(ERROR, "TypeRename: type %s not defined", oldTypeName);
}
newtup = SearchSysCacheTuple(TYPENAME, if (SearchSysCacheExists(TYPENAME,
PointerGetDatum(newTypeName), PointerGetDatum(newTypeName),
0, 0, 0); 0, 0, 0))
if (HeapTupleIsValid(newtup)) elog(ERROR, "TypeRename: type \"%s\" already defined", newTypeName);
{
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); namestrcpy(&(((Form_pg_type) GETSTRUCT(tuple))->typname), newTypeName);
heap_update(pg_type_desc, &oldtup->t_self, oldtup, NULL); heap_update(pg_type_desc, &tuple->t_self, tuple, 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);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -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); ...@@ -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) ...@@ -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))
{
CommitTransactionCommand();
return;
}
/* /*
* We can VACUUM ANALYZE any table except pg_statistic. * We can VACUUM ANALYZE any table except pg_statistic.
* see update_relstats * see update_relstats
*/ */
if (!HeapTupleIsValid(tuple) || if (strcmp(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname),
strcmp(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname), StatisticRelationName) == 0)
StatisticRelationName) == 0)
{ {
ReleaseSysCache(tuple);
CommitTransactionCommand(); CommitTransactionCommand();
return; 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) ...@@ -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) ...@@ -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) ...@@ -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
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
/* /*
......
...@@ -15,7 +15,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
This diff is collapsed.
...@@ -276,7 +276,6 @@ DeleteComments(Oid oid) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -7,7 +7,7 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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 ...@@ -893,65 +893,64 @@ static Oid
GetOutputFunction(Oid type) GetOutputFunction(Oid type)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
Oid result;
typeTuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(type), typeTuple = SearchSysCache(TYPEOID,
0, 0, 0); ObjectIdGetDatum(type),
0, 0, 0);
if (HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput; elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type);
result = ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput;
elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type); ReleaseSysCache(typeTuple);
return InvalidOid; return result;
} }
static Oid static Oid
GetTypeElement(Oid type) GetInputFunction(Oid type)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
Oid result;
typeTuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(type), typeTuple = SearchSysCache(TYPEOID,
0, 0, 0); ObjectIdGetDatum(type),
0, 0, 0);
if (HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem; elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type);
result = ((Form_pg_type) GETSTRUCT(typeTuple))->typinput;
elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type); ReleaseSysCache(typeTuple);
return InvalidOid; return result;
} }
static Oid static Oid
GetInputFunction(Oid type) GetTypeElement(Oid type)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
Oid result;
typeTuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(type), typeTuple = SearchSysCache(TYPEOID,
0, 0, 0); ObjectIdGetDatum(type),
0, 0, 0);
if (HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typinput; elog(ERROR, "GetTypeElement: Cache lookup of type %u failed", type);
result = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type); ReleaseSysCache(typeTuple);
return InvalidOid; return result;
} }
static Oid static bool
IsTypeByVal(Oid type) IsTypeByVal(Oid type)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
bool result;
typeTuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(type), typeTuple = SearchSysCache(TYPEOID,
0, 0, 0); ObjectIdGetDatum(type),
0, 0, 0);
if (HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval; elog(ERROR, "IsTypeByVal: Cache lookup of type %u failed", type);
result = ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval;
elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type); ReleaseSysCache(typeTuple);
return result;
return InvalidOid;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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.
* pg_relation), find the appropriate tuple, and add the specified
* lock to it.
*/
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTupleCopy(RELOID,
ObjectIdGetDatum(relationId),
0, 0, 0)
;
Assert(HeapTupleIsValid(tuple));
((Form_pg_class) GETSTRUCT(tuple))->relhassubclass = relhassubclass;
heap_update(relationRelation, &tuple->t_self, tuple, NULL);
/* keep the catalog indices up to date */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation, tuple
);
CatalogCloseIndices(Num_pg_class_indices, idescs);
heap_freetuple(tuple);
heap_close(relationRelation, RowExclusiveLock);
}
/*
* Fetch a modifiable copy of the tuple, modify it, update pg_class.
*/
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(RELOID,
ObjectIdGetDatum(relationId),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "setRelhassubclassInRelation: cache lookup failed for relation %u", relationId);
((Form_pg_class) GETSTRUCT(tuple))->relhassubclass = relhassubclass;
heap_update(relationRelation, &tuple->t_self, tuple, NULL);
/* keep the catalog indices up to date */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation, tuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
heap_freetuple(tuple);
heap_close(relationRelation, RowExclusiveLock);
}
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
...@@ -10,7 +10,7 @@ ...@@ -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) ...@@ -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) ...@@ -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);
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 * ...@@ -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) ...@@ -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 */ ) ...@@ -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) ...@@ -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);
} }
/* /*
......
...@@ -48,7 +48,6 @@ void ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -8,7 +8,7 @@ ...@@ -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 */ ...@@ -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 */ ...@@ -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 */ ...@@ -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 */ ...@@ -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 */ ...@@ -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 */ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -7,7 +7,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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));
......
...@@ -6,7 +6,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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() ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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;
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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++;
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
...@@ -34,7 +34,7 @@ ...@@ -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 @@ ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -15,7 +15,7 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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;
......
...@@ -7,7 +7,7 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -3,7 +3,7 @@ ...@@ -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 * ...@@ -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) ...@@ -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) ...@@ -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
......
...@@ -2,7 +2,6 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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;
...@@ -68,59 +75,18 @@ DLNewElem(void *val) ...@@ -68,59 +75,18 @@ DLNewElem(void *val)
} }
void void
DLFreeElem(Dlelem *e) DLInitElem(Dlelem *e, void *val)
{
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); e->dle_next = 0;
e->dle_prev = 0;
return e ? e->dle_val : 0; e->dle_val = val;
} e->dle_list = 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 * void
DLGetSucc(Dlelem *e) /* get successor */ DLFreeElem(Dlelem *e)
{ {
return e ? e->dle_next : 0; free(e);
} }
void void
...@@ -131,16 +97,16 @@ 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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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
......
...@@ -6,7 +6,7 @@ ...@@ -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) ...@@ -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) ...@@ -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)
......
...@@ -9,7 +9,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
} }
/* /*
......
...@@ -10,7 +10,7 @@ ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -8,7 +8,7 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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-
......
...@@ -7,7 +7,7 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,
......
...@@ -15,7 +15,7 @@ ...@@ -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, ...@@ -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,
......
...@@ -8,7 +8,7 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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()
......
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -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, ...@@ -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, ...@@ -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;
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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, ...@@ -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);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment