aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/common/printtup.c36
-rw-r--r--src/backend/access/common/tupdesc.c30
-rw-r--r--src/backend/access/gist/gist.c29
-rw-r--r--src/backend/access/index/istrat.c61
-rw-r--r--src/backend/access/transam/xact.c4
-rw-r--r--src/backend/catalog/aclchk.c145
-rw-r--r--src/backend/catalog/catalog.c48
-rw-r--r--src/backend/catalog/heap.c64
-rw-r--r--src/backend/catalog/index.c104
-rw-r--r--src/backend/catalog/indexing.c9
-rw-r--r--src/backend/catalog/pg_aggregate.c82
-rw-r--r--src/backend/catalog/pg_operator.c48
-rw-r--r--src/backend/catalog/pg_proc.c65
-rw-r--r--src/backend/catalog/pg_type.c68
-rw-r--r--src/backend/commands/analyze.c39
-rw-r--r--src/backend/commands/async.c35
-rw-r--r--src/backend/commands/cluster.c24
-rw-r--r--src/backend/commands/command.c195
-rw-r--r--src/backend/commands/comment.c105
-rw-r--r--src/backend/commands/copy.c95
-rw-r--r--src/backend/commands/creatinh.c90
-rw-r--r--src/backend/commands/dbcommands.c10
-rw-r--r--src/backend/commands/define.c13
-rw-r--r--src/backend/commands/indexcmds.c119
-rw-r--r--src/backend/commands/proclang.c30
-rw-r--r--src/backend/commands/remove.c70
-rw-r--r--src/backend/commands/rename.c62
-rw-r--r--src/backend/commands/trigger.c39
-rw-r--r--src/backend/commands/user.c89
-rw-r--r--src/backend/commands/vacuum.c23
-rw-r--r--src/backend/executor/execUtils.c10
-rw-r--r--src/backend/executor/functions.c21
-rw-r--r--src/backend/executor/nodeAgg.c41
-rw-r--r--src/backend/executor/nodeGroup.c7
-rw-r--r--src/backend/executor/nodeHash.c15
-rw-r--r--src/backend/executor/nodeMergejoin.c20
-rw-r--r--src/backend/executor/spi.c11
-rw-r--r--src/backend/lib/dllist.c98
-rw-r--r--src/backend/nodes/makefuncs.c25
-rw-r--r--src/backend/nodes/outfuncs.c7
-rw-r--r--src/backend/optimizer/path/indxpath.c48
-rw-r--r--src/backend/optimizer/plan/createplan.c25
-rw-r--r--src/backend/optimizer/plan/initsplan.c5
-rw-r--r--src/backend/optimizer/plan/subselect.c28
-rw-r--r--src/backend/optimizer/prep/preptlist.c11
-rw-r--r--src/backend/optimizer/util/clauses.c56
-rw-r--r--src/backend/optimizer/util/plancat.c48
-rw-r--r--src/backend/parser/analyze.c54
-rw-r--r--src/backend/parser/parse_agg.c18
-rw-r--r--src/backend/parser/parse_clause.c13
-rw-r--r--src/backend/parser/parse_coerce.c36
-rw-r--r--src/backend/parser/parse_expr.c44
-rw-r--r--src/backend/parser/parse_func.c64
-rw-r--r--src/backend/parser/parse_node.c52
-rw-r--r--src/backend/parser/parse_oper.c214
-rw-r--r--src/backend/parser/parse_type.c219
-rw-r--r--src/backend/rewrite/rewriteManip.c23
-rw-r--r--src/backend/rewrite/rewriteRemove.c27
-rw-r--r--src/backend/rewrite/rewriteSupport.c19
-rw-r--r--src/backend/tcop/fastpath.c30
-rw-r--r--src/backend/tcop/utility.c10
-rw-r--r--src/backend/utils/adt/acl.c18
-rw-r--r--src/backend/utils/adt/arrayfuncs.c9
-rw-r--r--src/backend/utils/adt/format_type.c18
-rw-r--r--src/backend/utils/adt/regproc.c20
-rw-r--r--src/backend/utils/adt/ri_triggers.c18
-rw-r--r--src/backend/utils/adt/ruleutils.c98
-rw-r--r--src/backend/utils/adt/selfuncs.c56
-rw-r--r--src/backend/utils/adt/sets.c40
-rw-r--r--src/backend/utils/cache/catcache.c391
-rw-r--r--src/backend/utils/cache/lsyscache.c349
-rw-r--r--src/backend/utils/cache/syscache.c187
-rw-r--r--src/backend/utils/cache/temprel.c3
-rw-r--r--src/backend/utils/fmgr/dfmgr.c10
-rw-r--r--src/backend/utils/fmgr/fmgr.c20
-rw-r--r--src/backend/utils/init/miscinit.c23
-rw-r--r--src/backend/utils/init/postinit.c7
-rw-r--r--src/backend/utils/misc/superuser.c18
-rw-r--r--src/backend/utils/sort/tuplesort.c12
-rw-r--r--src/include/executor/hashjoin.h4
-rw-r--r--src/include/lib/dllist.h42
-rw-r--r--src/include/nodes/makefuncs.h7
-rw-r--r--src/include/parser/parse_oper.h11
-rw-r--r--src/include/parser/parse_type.h9
-rw-r--r--src/include/rewrite/rewriteSupport.h4
-rw-r--r--src/include/utils/catcache.h36
-rw-r--r--src/include/utils/lsyscache.h4
-rw-r--r--src/include/utils/syscache.h20
-rw-r--r--src/pl/plperl/plperl.c54
-rw-r--r--src/pl/plpgsql/src/pl_comp.c92
-rw-r--r--src/pl/plpgsql/src/pl_exec.c53
-rw-r--r--src/pl/tcl/pltcl.c69
92 files changed, 2600 insertions, 2232 deletions
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 6fe0e9652c2..ccf3071b502 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.53 2000/05/30 04:24:27 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.54 2000/11/16 22:30:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,7 +36,7 @@ static void printtup_cleanup(DestReceiver *self);
* getTypeOutAndElem -- get both typoutput and typelem for a type
*
* 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.
* ----------------
*/
@@ -44,25 +44,19 @@ int
getTypeOutAndElem(Oid type, Oid *typOutput, Oid *typElem)
{
HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(type),
- 0, 0, 0);
-
- if (HeapTupleIsValid(typeTuple))
- {
- Form_pg_type pt = (Form_pg_type) GETSTRUCT(typeTuple);
-
- *typOutput = (Oid) pt->typoutput;
- *typElem = (Oid) pt->typelem;
- return OidIsValid(*typOutput);
- }
-
- elog(ERROR, "getTypeOutAndElem: Cache lookup of type %u failed", type);
-
- *typOutput = InvalidOid;
- *typElem = InvalidOid;
- return 0;
+ Form_pg_type pt;
+
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(ERROR, "getTypeOutAndElem: Cache lookup of type %u failed", type);
+ pt = (Form_pg_type) GETSTRUCT(typeTuple);
+
+ *typOutput = pt->typoutput;
+ *typElem = pt->typelem;
+ ReleaseSysCache(typeTuple);
+ return OidIsValid(*typOutput);
}
/* ----------------
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 1ed2366efda..8b9b7cd537f 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -8,7 +8,7 @@
*
*
* 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
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -401,9 +401,9 @@ TupleDescInitEntry(TupleDesc desc,
* -cim 6/14/90
* ----------------
*/
- tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(oidtypeid),
- 0, 0, 0);
+ tuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(oidtypeid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
/* ----------------
@@ -455,25 +455,18 @@ TupleDescInitEntry(TupleDesc desc,
*/
if (attisset)
{
- Type t = typeidType(OIDOID);
-
- att->attlen = typeLen(t);
- att->attbyval = typeByVal(t);
+ att->attlen = sizeof(Oid);
+ att->attbyval = true;
+ att->attstorage = 'p';
}
else
{
att->attlen = typeForm->typlen;
att->attbyval = typeForm->typbyval;
-/*
- * Default to the types storage
- */
-#ifdef TUPLE_TOASTER_ACTIVE
att->attstorage = typeForm->typstorage;
-#else
- att->attstorage = 'p';
-#endif
}
+ ReleaseSysCache(tuple);
return true;
}
@@ -496,12 +489,11 @@ TupleDescMakeSelfReference(TupleDesc desc,
char *relname)
{
Form_pg_attribute att;
- Type t = typeidType(OIDOID);
att = desc->attrs[attnum - 1];
att->atttypid = TypeShellMake(relname);
- att->attlen = typeLen(t);
- att->attbyval = typeByVal(t);
+ att->attlen = sizeof(Oid);
+ att->attbyval = true;
att->attstorage = 'p';
att->attnelems = 0;
}
@@ -580,7 +572,7 @@ BuildDescForRelation(List *schema, char *relname)
}
if (!TupleDescInitEntry(desc, attnum, attname,
- typeTypeId(typenameType(typename)),
+ typenameTypeId(typename),
atttypmod, attdim, attisset))
{
/* ----------------
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index d7bfeb1287d..d8e9005e933 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.64 2000/11/08 22:09:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.65 2000/11/16 22:30:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1140,6 +1140,7 @@ initGISTstate(GISTSTATE *giststate, Relation index)
equal_proc;
HeapTuple htup;
Form_pg_index itupform;
+ Oid indexrelid;
consistent_proc = index_getprocid(index, 1, GIST_CONSISTENT_PROC);
union_proc = index_getprocid(index, 1, GIST_UNION_PROC);
@@ -1157,32 +1158,32 @@ initGISTstate(GISTSTATE *giststate, Relation index)
fmgr_info(equal_proc, &giststate->equalFn);
/* see if key type is different from type of attribute being indexed */
- htup = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(RelationGetRelid(index)),
- 0, 0, 0);
- itupform = (Form_pg_index) GETSTRUCT(htup);
+ htup = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(RelationGetRelid(index)),
+ 0, 0, 0);
if (!HeapTupleIsValid(htup))
elog(ERROR, "initGISTstate: index %u not found",
RelationGetRelid(index));
+ itupform = (Form_pg_index) GETSTRUCT(htup);
giststate->haskeytype = itupform->indhaskeytype;
+ indexrelid = itupform->indexrelid;
+ ReleaseSysCache(htup);
+
if (giststate->haskeytype)
{
/* key type is different -- is it byval? */
- htup = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(itupform->indexrelid),
- UInt16GetDatum(FirstOffsetNumber),
- 0, 0);
+ htup = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(indexrelid),
+ UInt16GetDatum(FirstOffsetNumber),
+ 0, 0);
if (!HeapTupleIsValid(htup))
- {
elog(ERROR, "initGISTstate: no attribute tuple %u %d",
- itupform->indexrelid, FirstOffsetNumber);
- return;
- }
+ indexrelid, FirstOffsetNumber);
giststate->keytypbyval = (((Form_pg_attribute) htup)->attbyval);
+ ReleaseSysCache(htup);
}
else
giststate->keytypbyval = FALSE;
- return;
}
diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c
index d6a966bcd44..681b80e1e86 100644
--- a/src/backend/access/index/istrat.c
+++ b/src/backend/access/index/istrat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.46 2000/07/14 22:17:30 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.47 2000/11/16 22:30:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -482,9 +482,9 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
if (cachesearch)
{
- tuple = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(operatorObjectId),
- 0, 0, 0);
+ tuple = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(operatorObjectId),
+ 0, 0, 0);
}
else
{
@@ -505,24 +505,25 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
{
if (!cachesearch)
heap_endscan(scan);
- elog(ERROR, "OperatorObjectIdFillScanKeyEntry: unknown operator %u",
+ elog(ERROR, "OperatorRelationFillScanKeyEntry: unknown operator %u",
operatorObjectId);
}
entry->sk_flags = 0;
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);
if (!RegProcedureIsValid(entry->sk_procedure))
- {
elog(ERROR,
- "OperatorObjectIdFillScanKeyEntry: no procedure for operator %u",
+ "OperatorRelationFillScanKeyEntry: no procedure for operator %u",
operatorObjectId);
- }
+
+ fmgr_info(entry->sk_procedure, &entry->sk_func);
+ entry->sk_nargs = entry->sk_func.fn_nargs;
}
@@ -547,16 +548,16 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
HeapTuple tuple;
Form_pg_index iform;
StrategyMap map;
- AttrNumber attributeNumber;
- int attributeIndex;
+ AttrNumber attNumber;
+ int attIndex;
Oid operatorClassObjectId[INDEX_MAX_KEYS];
bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
if (cachesearch)
{
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexObjectId),
- 0, 0, 0);
+ tuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexObjectId),
+ 0, 0, 0);
}
else
{
@@ -583,19 +584,23 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
* XXX note that the following assumes the INDEX tuple is well formed
* 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");
break;
}
- operatorClassObjectId[attributeIndex] = iform->indclass[attributeIndex];
+ operatorClassObjectId[attIndex] = iform->indclass[attIndex];
}
- if (!cachesearch)
+ if (cachesearch)
+ {
+ ReleaseSysCache(tuple);
+ }
+ else
{
heap_endscan(scan);
heap_close(relation, AccessShareLock);
@@ -614,20 +619,19 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
relation = heap_openr(AccessMethodProcedureRelationName,
AccessShareLock);
- for (attributeNumber = 1; attributeNumber <= maxAttributeNumber;
- attributeNumber++)
+ for (attNumber = 1; attNumber <= maxAttributeNumber; attNumber++)
{
int16 support;
Form_pg_amproc aform;
RegProcedure *loc;
- loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)];
+ loc = &indexSupport[((attNumber - 1) * maxSupportNumber)];
for (support = 0; support < maxSupportNumber; ++support)
loc[support] = InvalidOid;
entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
+ ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
@@ -654,17 +658,16 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
operatorRelation = heap_openr(OperatorRelationName, AccessShareLock);
- for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
- attributeNumber--)
+ for (attNumber = maxAttributeNumber; attNumber > 0; attNumber--)
{
StrategyNumber strategy;
entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
+ ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
map = IndexStrategyGetStrategyMap(indexStrategy,
maxStrategyNumber,
- attributeNumber);
+ attNumber);
for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy));
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 6d950e96942..600e9ddcaec 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -8,7 +8,7 @@
*
*
* 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
* Transaction aborts can now occur two ways:
@@ -1112,6 +1112,7 @@ CommitTransaction(void)
AtEOXact_nbtree();
AtCommit_Cache();
AtCommit_Locks();
+ AtEOXact_CatCache(true);
AtCommit_Memory();
AtEOXact_Files();
@@ -1192,6 +1193,7 @@ AbortTransaction(void)
AtEOXact_SPI();
AtEOXact_nbtree();
AtAbort_Cache();
+ AtEOXact_CatCache(false);
AtAbort_Memory();
AtEOXact_Files();
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index b7013d28824..b2698ad19b6 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -8,7 +8,7 @@
*
*
* 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
* See acl.h.
@@ -77,6 +77,7 @@ ChangeAcl(char *relname,
*new_acl;
Relation relation;
HeapTuple tuple;
+ HeapTuple newtuple;
Datum aclDatum;
Datum values[Natts_pg_class];
char nulls[Natts_pg_class];
@@ -89,9 +90,9 @@ ChangeAcl(char *relname,
* there's no ACL, create a default using the pg_class.relowner field.
*/
relation = heap_openr(RelationRelationName, RowExclusiveLock);
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(relname),
- 0, 0, 0);
+ tuple = SearchSysCache(RELNAME,
+ PointerGetDatum(relname),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
heap_close(relation, RowExclusiveLock);
@@ -134,14 +135,16 @@ ChangeAcl(char *relname,
}
replaces[Anum_pg_class_relacl - 1] = 'r';
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 */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, relation, tuple);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newtuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
heap_close(relation, RowExclusiveLock);
@@ -156,11 +159,14 @@ get_grosysid(char *groname)
HeapTuple tuple;
AclId id = 0;
- tuple = SearchSysCacheTuple(GRONAME,
- PointerGetDatum(groname),
- 0, 0, 0);
+ tuple = SearchSysCache(GRONAME,
+ PointerGetDatum(groname),
+ 0, 0, 0);
if (HeapTupleIsValid(tuple))
+ {
id = ((Form_pg_group) GETSTRUCT(tuple))->grosysid;
+ ReleaseSysCache(tuple);
+ }
else
elog(ERROR, "non-existent group \"%s\"", groname);
return id;
@@ -172,11 +178,14 @@ get_groname(AclId grosysid)
HeapTuple tuple;
char *name = NULL;
- tuple = SearchSysCacheTuple(GROSYSID,
- ObjectIdGetDatum(grosysid),
- 0, 0, 0);
+ tuple = SearchSysCache(GROSYSID,
+ ObjectIdGetDatum(grosysid),
+ 0, 0, 0);
if (HeapTupleIsValid(tuple))
- name = NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname);
+ {
+ name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname));
+ ReleaseSysCache(tuple);
+ }
else
elog(NOTICE, "get_groname: group %u not found", grosysid);
return name;
@@ -185,6 +194,7 @@ get_groname(AclId grosysid)
static bool
in_group(AclId uid, AclId gid)
{
+ bool result = false;
HeapTuple tuple;
Datum att;
bool isNull;
@@ -193,9 +203,9 @@ in_group(AclId uid, AclId gid)
int i,
num;
- tuple = SearchSysCacheTuple(GROSYSID,
- ObjectIdGetDatum(gid),
- 0, 0, 0);
+ tuple = SearchSysCache(GROSYSID,
+ ObjectIdGetDatum(gid),
+ 0, 0, 0);
if (HeapTupleIsValid(tuple))
{
att = SysCacheGetAttr(GROSYSID,
@@ -212,13 +222,17 @@ in_group(AclId uid, AclId gid)
for (i = 0; i < num; ++i)
{
if (aidp[i] == uid)
- return true;
+ {
+ result = true;
+ break;
+ }
}
}
+ ReleaseSysCache(tuple);
}
else
elog(NOTICE, "in_group: group %u not found", gid);
- return false;
+ return result;
}
/*
@@ -342,9 +356,9 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
bool isNull;
Acl *acl;
- tuple = SearchSysCacheTuple(SHADOWSYSID,
- ObjectIdGetDatum(userid),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(userid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_aclcheck: invalid user id %u",
(unsigned) userid);
@@ -363,6 +377,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
{
elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied",
relname);
+ ReleaseSysCache(tuple);
return ACLCHECK_NO_PRIV;
}
@@ -375,15 +390,19 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
elog(DEBUG, "pg_aclcheck: \"%s\" is superuser",
usename);
#endif
+ ReleaseSysCache(tuple);
return ACLCHECK_OK;
}
+ ReleaseSysCache(tuple);
+ /* caution: usename is inaccessible beyond this point... */
+
/*
* Normal case: get the relation's ACL from pg_class
*/
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(relname),
- 0, 0, 0);
+ tuple = SearchSysCache(RELNAME,
+ PointerGetDatum(relname),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_aclcheck: class \"%s\" not found", relname);
@@ -404,8 +423,11 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
}
result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode);
+
if (acl)
pfree(acl);
+ ReleaseSysCache(tuple);
+
return result;
}
@@ -415,12 +437,12 @@ pg_ownercheck(Oid userid,
int cacheid)
{
HeapTuple tuple;
- AclId owner_id = 0;
+ AclId owner_id;
char *usename;
- tuple = SearchSysCacheTuple(SHADOWSYSID,
- ObjectIdGetDatum(userid),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(userid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_ownercheck: invalid user id %u",
(unsigned) userid);
@@ -435,11 +457,16 @@ pg_ownercheck(Oid userid,
elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
usename);
#endif
+ ReleaseSysCache(tuple);
return 1;
}
- tuple = SearchSysCacheTuple(cacheid, PointerGetDatum(value),
- 0, 0, 0);
+ ReleaseSysCache(tuple);
+ /* caution: usename is inaccessible beyond this point... */
+
+ tuple = SearchSysCache(cacheid,
+ PointerGetDatum(value),
+ 0, 0, 0);
switch (cacheid)
{
case OPEROID:
@@ -468,9 +495,12 @@ pg_ownercheck(Oid userid,
break;
default:
elog(ERROR, "pg_ownercheck: invalid cache id: %d", cacheid);
+ owner_id = 0; /* keep compiler quiet */
break;
}
+ ReleaseSysCache(tuple);
+
return userid == owner_id;
}
@@ -482,15 +512,15 @@ pg_func_ownercheck(Oid userid,
{
HeapTuple tuple;
AclId owner_id;
- char *username;
+ char *usename;
- tuple = SearchSysCacheTuple(SHADOWSYSID,
- ObjectIdGetDatum(userid),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(userid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_func_ownercheck: invalid user id %u",
(unsigned) userid);
- username = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
+ usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
/*
* Superusers bypass all permission-checking.
@@ -499,21 +529,27 @@ pg_func_ownercheck(Oid userid,
{
#ifdef ACLDEBUG_TRACE
elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
- username);
+ usename);
#endif
+ ReleaseSysCache(tuple);
return 1;
}
- tuple = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(arglist),
- 0);
+ ReleaseSysCache(tuple);
+ /* caution: usename is inaccessible beyond this point... */
+
+ tuple = SearchSysCache(PROCNAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(arglist),
+ 0);
if (!HeapTupleIsValid(tuple))
func_error("pg_func_ownercheck", funcname, nargs, arglist, NULL);
owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
+ ReleaseSysCache(tuple);
+
return userid == owner_id;
}
@@ -524,15 +560,15 @@ pg_aggr_ownercheck(Oid userid,
{
HeapTuple tuple;
AclId owner_id;
- char *username;
+ char *usename;
- tuple = SearchSysCacheTuple(SHADOWSYSID,
- PointerGetDatum(userid),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWSYSID,
+ PointerGetDatum(userid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "pg_aggr_ownercheck: invalid user id %u",
(unsigned) userid);
- username = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
+ usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
/*
* Superusers bypass all permission-checking.
@@ -541,20 +577,25 @@ pg_aggr_ownercheck(Oid userid,
{
#ifdef ACLDEBUG_TRACE
elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser",
- username);
+ usename);
#endif
+ ReleaseSysCache(tuple);
return 1;
}
- tuple = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggname),
- ObjectIdGetDatum(basetypeID),
- 0, 0);
+ ReleaseSysCache(tuple);
+ /* caution: usename is inaccessible beyond this point... */
+ tuple = SearchSysCache(AGGNAME,
+ PointerGetDatum(aggname),
+ ObjectIdGetDatum(basetypeID),
+ 0, 0);
if (!HeapTupleIsValid(tuple))
agg_error("pg_aggr_ownercheck", aggname, basetypeID);
owner_id = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggowner;
+ ReleaseSysCache(tuple);
+
return userid == owner_id;
}
diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
index c7b191dd2da..aed3864e900 100644
--- a/src/backend/catalog/catalog.c
+++ b/src/backend/catalog/catalog.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.36 2000/10/22 05:14:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.37 2000/11/16 22:30:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,7 @@
#include "catalog/catname.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
-#include "utils/syscache.h"
+#include "utils/lsyscache.h"
#ifdef OLD_FILE_NAMING
/*
@@ -251,12 +251,10 @@ newoid()
void
fillatt(TupleDesc tupleDesc)
{
- Form_pg_attribute *attributeP;
- Form_pg_type typp;
- HeapTuple tuple;
- int i;
int natts = tupleDesc->natts;
Form_pg_attribute *att = tupleDesc->attrs;
+ Form_pg_attribute *attributeP;
+ int i;
if (natts < 0 || natts > MaxHeapAttributeNumber)
elog(ERROR, "fillatt: %d attributes is too large", natts);
@@ -268,33 +266,23 @@ fillatt(TupleDesc tupleDesc)
attributeP = &att[0];
- for (i = 0; i < natts;)
+ for (i = 1; i <= natts; i++)
{
- tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum((*attributeP)->atttypid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
+ (*attributeP)->attnum = (int16) i;
+
+ /*
+ * 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",
- (*attributeP)->atttypid);
+ get_typlenbyval((*attributeP)->atttypid,
+ & (*attributeP)->attlen,
+ & (*attributeP)->attbyval);
}
- else
- {
- (*attributeP)->attnum = (int16) ++i;
- /*
- * 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;
+ attributeP++;
}
}
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 2c4a9e515b2..3da6d82d4d0 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* 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
@@ -488,7 +488,6 @@ CheckAttributeNames(TupleDesc tupdesc)
Oid
RelnameFindRelid(const char *relname)
{
- HeapTuple tuple;
Oid relid;
/*
@@ -497,19 +496,16 @@ RelnameFindRelid(const char *relname)
*/
if (!IsBootstrapProcessingMode())
{
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(relname),
- 0, 0, 0);
- if (HeapTupleIsValid(tuple))
- relid = tuple->t_data->t_oid;
- else
- relid = InvalidOid;
+ relid = GetSysCacheOid(RELNAME,
+ PointerGetDatum(relname),
+ 0, 0, 0);
}
else
{
Relation pg_class_desc;
ScanKeyData key;
HeapScanDesc pg_class_scan;
+ HeapTuple tuple;
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
@@ -756,8 +752,8 @@ AddNewRelationType(char *typeName, Oid new_rel_oid)
*/
new_type_oid = TypeCreate(typeName, /* type name */
new_rel_oid, /* relation oid */
- typeLen(typeidType(OIDOID)), /* internal size */
- typeLen(typeidType(OIDOID)), /* external size */
+ sizeof(Oid), /* internal size */
+ sizeof(Oid), /* external size */
'c', /* type-type (catalog) */
',', /* default array delimiter */
"int4in", /* input procedure */
@@ -1080,15 +1076,12 @@ DeleteRelationTuple(Relation rel)
*/
pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
- tup = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(rel->rd_id),
- 0, 0, 0);
+ tup = SearchSysCacheCopy(RELOID,
+ ObjectIdGetDatum(rel->rd_id),
+ 0, 0, 0);
if (!HeapTupleIsValid(tup))
- {
- heap_close(pg_class_desc, RowExclusiveLock);
elog(ERROR, "Relation \"%s\" does not exist",
RelationGetRelationName(rel));
- }
/* ----------------
* delete the relation tuple from pg_class, and finish up.
@@ -1136,14 +1129,15 @@ RelationTruncateIndexes(Oid heapId)
indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid;
indexInfo = BuildIndexInfo(indexTuple);
- /* Fetch the pg_class tuple associated with this index */
- classTuple = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(indexId),
- 0, 0, 0);
+ /* Fetch access method from pg_class tuple for this index */
+ classTuple = SearchSysCache(RELOID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
if (!HeapTupleIsValid(classTuple))
elog(ERROR, "RelationTruncateIndexes: index %u not found in pg_class",
indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
+ ReleaseSysCache(classTuple);
/*
* We have to re-open the heap rel each time through this loop
@@ -1258,19 +1252,17 @@ DeleteAttributeTuples(Relation rel)
attnum <= rel->rd_att->natts;
attnum++)
{
- if (HeapTupleIsValid(tup = SearchSysCacheTupleCopy(ATTNUM,
+ tup = SearchSysCacheCopy(ATTNUM,
ObjectIdGetDatum(RelationGetRelid(rel)),
- Int16GetDatum(attnum),
- 0, 0)))
+ Int16GetDatum(attnum),
+ 0, 0);
+ if (HeapTupleIsValid(tup))
{
-
/*** Delete any comments associated with this attribute ***/
-
DeleteComments(tup->t_data->t_oid);
heap_delete(pg_attribute_desc, &tup->t_self, NULL);
heap_freetuple(tup);
-
}
}
@@ -1586,9 +1578,10 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
return; /* done if pg_attribute is OK */
attrrel = heap_openr(AttributeRelationName, RowExclusiveLock);
- atttup = SearchSysCacheTupleCopy(ATTNUM,
- ObjectIdGetDatum(RelationGetRelid(rel)),
- (Datum) attnum, 0, 0);
+ atttup = SearchSysCacheCopy(ATTNUM,
+ ObjectIdGetDatum(RelationGetRelid(rel)),
+ Int16GetDatum(attnum),
+ 0, 0);
if (!HeapTupleIsValid(atttup))
elog(ERROR, "cache lookup of attribute %d in relation %u failed",
attnum, RelationGetRelid(rel));
@@ -1953,11 +1946,12 @@ AddRelationRawConstraints(Relation rel,
* message, but for ALTER TABLE ADD ATTRIBUTE this'd be important.)
*/
relrel = heap_openr(RelationRelationName, RowExclusiveLock);
- reltup = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(RelationGetRelid(rel)),
- 0, 0, 0);
+ reltup = SearchSysCacheCopy(RELOID,
+ ObjectIdGetDatum(RelationGetRelid(rel)),
+ 0, 0, 0);
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->relchecks = numchecks;
@@ -1970,8 +1964,8 @@ AddRelationRawConstraints(Relation rel,
CatalogIndexInsert(relidescs, Num_pg_class_indices, relrel, reltup);
CatalogCloseIndices(Num_pg_class_indices, relidescs);
- heap_close(relrel, RowExclusiveLock);
heap_freetuple(reltup);
+ heap_close(relrel, RowExclusiveLock);
}
static void
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 3833c961f40..d379246a922 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
*
*
* 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
@@ -174,9 +174,9 @@ BuildFuncTupleDesc(Oid funcOid)
/*
* Lookup the function to get its name and return type.
*/
- tuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(funcOid),
- 0, 0, 0);
+ tuple = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(funcOid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "Function %u does not exist", funcOid);
retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;
@@ -187,12 +187,14 @@ BuildFuncTupleDesc(Oid funcOid)
namestrcpy(&funcTupDesc->attrs[0]->attname,
NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname));
+ ReleaseSysCache(tuple);
+
/*
* Lookup the return type in pg_type for the type length etc.
*/
- tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(retType),
- 0, 0, 0);
+ tuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(retType),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "Type %u does not exist", retType);
@@ -208,6 +210,8 @@ BuildFuncTupleDesc(Oid funcOid)
funcTupDesc->attrs[0]->attstorage = 'p';
funcTupDesc->attrs[0]->attalign = ((Form_pg_type) GETSTRUCT(tuple))->typalign;
+ ReleaseSysCache(tuple);
+
return funcTupDesc;
}
@@ -759,10 +763,12 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
/* open the index system catalog relation */
pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexoid),
- 0, 0, 0);
- Assert(HeapTupleIsValid(tuple));
+ tuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexoid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "UpdateIndexPredicate: cache lookup failed for index %u",
+ indexoid);
for (i = 0; i < Natts_pg_index; i++)
{
@@ -779,6 +785,8 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
heap_update(pg_index, &newtup->t_self, newtup, NULL);
heap_freetuple(newtup);
+ ReleaseSysCache(tuple);
+
heap_close(pg_index, RowExclusiveLock);
pfree(predText);
}
@@ -1069,11 +1077,12 @@ index_drop(Oid indexId)
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
/* Remove the pg_class tuple for the index itself */
- tuple = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(indexId),
- 0, 0, 0);
-
- Assert(HeapTupleIsValid(tuple));
+ tuple = SearchSysCacheCopy(RELOID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "index_drop: cache lookup failed for index %u",
+ indexId);
heap_delete(relationRelation, &tuple->t_self, NULL);
heap_freetuple(tuple);
@@ -1098,10 +1107,10 @@ index_drop(Oid indexId)
attnum = 1; /* indexes start at 1 */
- while (HeapTupleIsValid(tuple = SearchSysCacheTupleCopy(ATTNUM,
+ while (HeapTupleIsValid(tuple = SearchSysCacheCopy(ATTNUM,
ObjectIdGetDatum(indexId),
Int16GetDatum(attnum),
- 0, 0)))
+ 0, 0)))
{
heap_delete(attributeRelation, &tuple->t_self, NULL);
heap_freetuple(tuple);
@@ -1115,10 +1124,12 @@ index_drop(Oid indexId)
*/
indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
- tuple = SearchSysCacheTupleCopy(INDEXRELID,
- ObjectIdGetDatum(indexId),
- 0, 0, 0);
- Assert(HeapTupleIsValid(tuple));
+ tuple = SearchSysCacheCopy(INDEXRELID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "index_drop: cache lookup failed for index %u",
+ indexId);
heap_delete(indexRelation, &tuple->t_self, NULL);
heap_freetuple(tuple);
@@ -1318,21 +1329,24 @@ LockClassinfoForUpdate(Oid relid, HeapTuple rtup,
Buffer *buffer, bool confirmCommitted)
{
HeapTuple classTuple;
- Form_pg_class pgcform;
bool test;
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
* probably modify the rel's pg_class tuple later on.
*/
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);
switch (test)
{
@@ -1418,9 +1432,9 @@ setRelhasindex(Oid relid, bool hasindex)
if (!IsIgnoringSystemIndexes())
{
- tuple = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
+ tuple = SearchSysCacheCopy(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
}
else
{
@@ -1542,9 +1556,9 @@ UpdateStats(Oid relid, long reltuples)
if (!in_place_upd)
{
- tuple = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
+ tuple = SearchSysCacheCopy(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
}
else
{
@@ -1887,19 +1901,20 @@ IndexGetRelation(Oid indexId)
{
HeapTuple tuple;
Form_pg_index index;
+ Oid result;
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexId),
- 0, 0, 0);
+ tuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
elog(ERROR, "IndexGetRelation: can't find index id %u",
indexId);
- }
index = (Form_pg_index) GETSTRUCT(tuple);
Assert(index->indexrelid == indexId);
- return index->indrelid;
+ result = index->indrelid;
+ ReleaseSysCache(tuple);
+ return result;
}
/* ---------------------------------
@@ -1965,12 +1980,13 @@ reindex_index(Oid indexId, bool force)
heap_close(indexRelation, AccessShareLock);
/* Fetch the classTuple associated with this index */
- classTuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexId),
- 0, 0, 0);
+ classTuple = SearchSysCache(RELOID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
if (!HeapTupleIsValid(classTuple))
elog(ERROR, "reindex_index: index %u not found in pg_class", indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
+ ReleaseSysCache(classTuple);
/* Open our index relation */
heapRelation = heap_open(heapId, ExclusiveLock);
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index 6003ab6bc53..60eae115ec7 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.73 2000/11/10 00:33:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.74 2000/11/16 22:30:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -153,13 +153,14 @@ CatalogIndexInsert(Relation *idescs,
IndexInfo *indexInfo;
InsertIndexResult indexRes;
- index_tup = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(idescs[i]->rd_id),
- 0, 0, 0);
+ index_tup = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(idescs[i]->rd_id),
+ 0, 0, 0);
if (!HeapTupleIsValid(index_tup))
elog(ERROR, "CatalogIndexInsert: index %u not found",
idescs[i]->rd_id);
indexInfo = BuildIndexInfo(index_tup);
+ ReleaseSysCache(index_tup);
FormIndexDatum(indexInfo,
heapTuple,
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index e3fa7c5535b..9c9d54c8f3e 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.35 2000/07/17 03:04:43 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.36 2000/11/16 22:30:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -82,15 +82,10 @@ AggregateCreate(char *aggName,
* specified as 'ANY' for a data-independent transition function,
* such as COUNT(*).
*/
- tup = SearchSysCacheTuple(TYPENAME,
+ basetype = GetSysCacheOid(TYPENAME,
PointerGetDatum(aggbasetypeName),
0, 0, 0);
- if (HeapTupleIsValid(tup))
- {
- basetype = tup->t_data->t_oid;
- Assert(OidIsValid(basetype));
- }
- else
+ if (!OidIsValid(basetype))
{
if (strcasecmp(aggbasetypeName, "ANY") != 0)
elog(ERROR, "AggregateCreate: Type '%s' undefined",
@@ -99,24 +94,21 @@ AggregateCreate(char *aggName,
}
/* make sure there is no existing agg of same name and base type */
- tup = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggName),
- ObjectIdGetDatum(basetype),
- 0, 0);
- if (HeapTupleIsValid(tup))
+ if (SearchSysCacheExists(AGGNAME,
+ PointerGetDatum(aggName),
+ ObjectIdGetDatum(basetype),
+ 0, 0))
elog(ERROR,
"AggregateCreate: aggregate '%s' with base type '%s' already exists",
aggName, aggbasetypeName);
/* handle transtype */
- tup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(aggtranstypeName),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
+ transtype = GetSysCacheOid(TYPENAME,
+ PointerGetDatum(aggtranstypeName),
+ 0, 0, 0);
+ if (!OidIsValid(transtype))
elog(ERROR, "AggregateCreate: Type '%s' undefined",
aggtranstypeName);
- transtype = tup->t_data->t_oid;
- Assert(OidIsValid(transtype));
/* handle transfn */
fnArgs[0] = transtype;
@@ -129,48 +121,50 @@ AggregateCreate(char *aggName,
{
nargs = 1;
}
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(aggtransfnName),
- Int32GetDatum(nargs),
- PointerGetDatum(fnArgs),
- 0);
+ tup = SearchSysCache(PROCNAME,
+ PointerGetDatum(aggtransfnName),
+ Int32GetDatum(nargs),
+ PointerGetDatum(fnArgs),
+ 0);
if (!HeapTupleIsValid(tup))
func_error("AggregateCreate", aggtransfnName, nargs, fnArgs, NULL);
transfn = tup->t_data->t_oid;
+ Assert(OidIsValid(transfn));
proc = (Form_pg_proc) GETSTRUCT(tup);
if (proc->prorettype != transtype)
elog(ERROR, "AggregateCreate: return type of '%s' is not '%s'",
aggtransfnName, aggtranstypeName);
- Assert(OidIsValid(transfn));
/*
* If the transfn is strict and the initval is NULL, make sure
* input type and transtype are the same (or at least binary-
* compatible), so that it's OK to use the first input value
* as the initial transValue.
*/
- if (((Form_pg_proc) GETSTRUCT(tup))->proisstrict && agginitval == NULL)
+ if (proc->proisstrict && agginitval == NULL)
{
if (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");
}
+ ReleaseSysCache(tup);
/* handle finalfn, if supplied */
if (aggfinalfnName)
{
fnArgs[0] = transtype;
fnArgs[1] = 0;
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(aggfinalfnName),
- Int32GetDatum(1),
- PointerGetDatum(fnArgs),
- 0);
+ tup = SearchSysCache(PROCNAME,
+ PointerGetDatum(aggfinalfnName),
+ Int32GetDatum(1),
+ PointerGetDatum(fnArgs),
+ 0);
if (!HeapTupleIsValid(tup))
func_error("AggregateCreate", aggfinalfnName, 1, fnArgs, NULL);
finalfn = tup->t_data->t_oid;
+ Assert(OidIsValid(finalfn));
proc = (Form_pg_proc) GETSTRUCT(tup);
finaltype = proc->prorettype;
- Assert(OidIsValid(finalfn));
+ ReleaseSysCache(tup);
}
else
{
@@ -237,10 +231,10 @@ AggNameGetInitVal(char *aggName, Oid basetype, bool *isNull)
Assert(PointerIsValid(aggName));
Assert(PointerIsValid(isNull));
- tup = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggName),
- ObjectIdGetDatum(basetype),
- 0, 0);
+ tup = SearchSysCache(AGGNAME,
+ PointerGetDatum(aggName),
+ ObjectIdGetDatum(basetype),
+ 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "AggNameGetInitVal: cache lookup failed for aggregate '%s'",
aggName);
@@ -254,20 +248,24 @@ AggNameGetInitVal(char *aggName, Oid basetype, bool *isNull)
Anum_pg_aggregate_agginitval,
isNull);
if (*isNull)
+ {
+ ReleaseSysCache(tup);
return (Datum) 0;
+ }
strInitVal = DatumGetCString(DirectFunctionCall1(textout, textInitVal));
- tup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(transtype),
- 0, 0, 0);
+ ReleaseSysCache(tup);
+
+ tup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(transtype),
+ 0, 0, 0);
if (!HeapTupleIsValid(tup))
- {
- pfree(strInitVal);
elog(ERROR, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type %u", transtype);
- }
+
typinput = ((Form_pg_type) GETSTRUCT(tup))->typinput;
typelem = ((Form_pg_type) GETSTRUCT(tup))->typelem;
+ ReleaseSysCache(tup);
initVal = OidFunctionCall3(typinput,
CStringGetDatum(strInitVal),
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 388bad8a583..29f404063ff 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -8,7 +8,7 @@
*
*
* 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
* these routines moved here from commands/define.c and somewhat cleaned up.
@@ -575,12 +575,11 @@ OperatorDef(char *operatorName,
typeId[1] = rightTypeId;
nargs = 2;
}
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(procedureName),
- Int32GetDatum(nargs),
- PointerGetDatum(typeId),
- 0);
-
+ tup = SearchSysCache(PROCNAME,
+ PointerGetDatum(procedureName),
+ Int32GetDatum(nargs),
+ PointerGetDatum(typeId),
+ 0);
if (!HeapTupleIsValid(tup))
func_error("OperatorDef", procedureName, nargs, typeId, NULL);
@@ -588,27 +587,32 @@ OperatorDef(char *operatorName,
values[Anum_pg_operator_oprresult - 1] = ObjectIdGetDatum(((Form_pg_proc)
GETSTRUCT(tup))->prorettype);
+ ReleaseSysCache(tup);
+
/* ----------------
* find restriction
* ----------------
*/
if (restrictionName)
{ /* optional */
+ Oid restOid;
+
MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
typeId[0] = OIDOID; /* operator OID */
typeId[1] = OIDOID; /* relation OID */
typeId[2] = INT2OID; /* attribute number */
typeId[3] = 0; /* value - can be any type */
typeId[4] = INT4OID; /* flags - left or right selectivity */
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(restrictionName),
- Int32GetDatum(5),
- PointerGetDatum(typeId),
- 0);
- if (!HeapTupleIsValid(tup))
+
+ restOid = GetSysCacheOid(PROCNAME,
+ PointerGetDatum(restrictionName),
+ Int32GetDatum(5),
+ PointerGetDatum(typeId),
+ 0);
+ if (!OidIsValid(restOid))
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
values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid);
@@ -619,6 +623,8 @@ OperatorDef(char *operatorName,
*/
if (joinName)
{ /* optional */
+ Oid joinOid;
+
MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
typeId[0] = OIDOID; /* operator OID */
typeId[1] = OIDOID; /* relation OID 1 */
@@ -626,15 +632,15 @@ OperatorDef(char *operatorName,
typeId[3] = OIDOID; /* relation OID 2 */
typeId[4] = INT2OID; /* attribute number 2 */
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(joinName),
- Int32GetDatum(5),
- PointerGetDatum(typeId),
- 0);
- if (!HeapTupleIsValid(tup))
+ joinOid = GetSysCacheOid(PROCNAME,
+ PointerGetDatum(joinName),
+ Int32GetDatum(5),
+ PointerGetDatum(typeId),
+ 0);
+ if (!OidIsValid(joinOid))
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
values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid);
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 26861047b24..9d3ce5c50d6 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.49 2000/10/07 00:58:15 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.50 2000/11/16 22:30:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -71,7 +71,7 @@ ProcedureCreate(char *procedureName,
Oid toid;
NameData procname;
TupleDesc tupDesc;
- Oid retval;
+ Oid retval;
/* ----------------
* sanity checks
@@ -80,15 +80,12 @@ ProcedureCreate(char *procedureName,
Assert(PointerIsValid(prosrc));
Assert(PointerIsValid(probin));
- tup = SearchSysCacheTuple(LANGNAME,
- PointerGetDatum(languageName),
- 0, 0, 0);
-
- if (!HeapTupleIsValid(tup))
+ languageObjectId = GetSysCacheOid(LANGNAME,
+ PointerGetDatum(languageName),
+ 0, 0, 0);
+ if (!OidIsValid(languageObjectId))
elog(ERROR, "ProcedureCreate: no such language '%s'", languageName);
- languageObjectId = tup->t_data->t_oid;
-
parameterCount = 0;
MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid));
foreach(x, argList)
@@ -124,13 +121,12 @@ ProcedureCreate(char *procedureName,
typev[parameterCount++] = toid;
}
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(procedureName),
- UInt16GetDatum(parameterCount),
- PointerGetDatum(typev),
- 0);
-
- if (HeapTupleIsValid(tup))
+ /* Check for duplicate definition */
+ if (SearchSysCacheExists(PROCNAME,
+ PointerGetDatum(procedureName),
+ UInt16GetDatum(parameterCount),
+ PointerGetDatum(typev),
+ 0))
elog(ERROR, "ProcedureCreate: procedure %s already exists with same arguments",
procedureName);
@@ -161,12 +157,12 @@ ProcedureCreate(char *procedureName,
prosrctext = DatumGetTextP(DirectFunctionCall1(textin,
CStringGetDatum(prosrc)));
- tup = SearchSysCacheTuple(PROSRC,
- PointerGetDatum(prosrctext),
- 0, 0, 0);
+ retval = GetSysCacheOid(PROSRC,
+ PointerGetDatum(prosrctext),
+ 0, 0, 0);
pfree(prosrctext);
- if (HeapTupleIsValid(tup))
- return tup->t_data->t_oid;
+ if (OidIsValid(retval))
+ return retval;
#else
elog(ERROR, "lookup for procedure by source needs fix (Jan)");
#endif /* SETS_FIXED */
@@ -351,7 +347,7 @@ checkretval(Oid rettype, List *queryTreeList)
List *tlist;
List *tlistitem;
int tlistlen;
- Type typ;
+ Oid typerelid;
Resdom *resnode;
Relation reln;
Oid relid;
@@ -375,11 +371,9 @@ checkretval(Oid rettype, List *queryTreeList)
}
/* 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)
- 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.
@@ -390,14 +384,17 @@ checkretval(Oid rettype, List *queryTreeList)
* For base-type returns, the target list should have exactly one entry,
* and its type should agree with what the user declared.
*/
- if (typeTypeRelid(typ) == InvalidOid)
+ typerelid = typeidTypeRelid(rettype);
+ if (typerelid == InvalidOid)
{
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;
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;
}
@@ -422,12 +419,13 @@ checkretval(Oid rettype, List *queryTreeList)
* declared return type, and be sure that attributes 1 .. n in the target
* list match the declared types.
*/
- reln = heap_open(typeTypeRelid(typ), AccessShareLock);
+ reln = heap_open(typerelid, AccessShareLock);
relid = reln->rd_id;
relnatts = reln->rd_rel->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 */
i = 0;
@@ -441,7 +439,7 @@ checkretval(Oid rettype, List *queryTreeList)
tletype = exprType(tle->expr);
if (tletype != reln->rd_att->attrs[i]->atttypid)
elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
- typeTypeName(typ),
+ typeidTypeName(rettype),
typeidTypeName(tletype),
typeidTypeName(reln->rd_att->attrs[i]->atttypid),
i+1);
@@ -450,7 +448,8 @@ checkretval(Oid rettype, List *queryTreeList)
/* this shouldn't happen, but let's just check... */
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);
}
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 2e5970cfcc8..f1f306424f0 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.55 2000/08/21 17:22:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.56 2000/11/16 22:30:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -388,6 +388,8 @@ TypeCreate(char *typeName,
for (j = 0; j < 4; ++j)
{
+ Oid procOid;
+
procname = procs[j];
/*
@@ -396,13 +398,13 @@ TypeCreate(char *typeName,
*/
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(procname),
- Int32GetDatum(1),
- PointerGetDatum(argList),
- 0);
+ procOid = GetSysCacheOid(PROCNAME,
+ PointerGetDatum(procname),
+ Int32GetDatum(1),
+ PointerGetDatum(argList),
+ 0);
- if (!HeapTupleIsValid(tup))
+ if (!OidIsValid(procOid))
{
/*
@@ -428,17 +430,17 @@ TypeCreate(char *typeName,
argList[1] = OIDOID;
argList[2] = INT4OID;
}
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(procname),
- Int32GetDatum(nargs),
- PointerGetDatum(argList),
- 0);
+ procOid = GetSysCacheOid(PROCNAME,
+ PointerGetDatum(procname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(argList),
+ 0);
}
- if (!HeapTupleIsValid(tup))
+ if (!OidIsValid(procOid))
func_error("TypeCreate", procname, 1, argList, NULL);
}
- values[i++] = ObjectIdGetDatum(tup->t_data->t_oid); /* 11 - 14 */
+ values[i++] = ObjectIdGetDatum(procOid); /* 11 - 14 */
}
/* ----------------
@@ -536,41 +538,31 @@ TypeRename(const char *oldTypeName, const char *newTypeName)
{
Relation pg_type_desc;
Relation idescs[Num_pg_type_indices];
- HeapTuple oldtup,
- newtup;
+ HeapTuple tuple;
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
- oldtup = SearchSysCacheTupleCopy(TYPENAME,
- PointerGetDatum(oldTypeName),
- 0, 0, 0);
-
- if (!HeapTupleIsValid(oldtup))
- {
- heap_close(pg_type_desc, RowExclusiveLock);
- elog(ERROR, "TypeRename: type %s not defined", oldTypeName);
- }
+ tuple = SearchSysCacheCopy(TYPENAME,
+ PointerGetDatum(oldTypeName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "TypeRename: type \"%s\" not defined", oldTypeName);
- newtup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(newTypeName),
- 0, 0, 0);
- if (HeapTupleIsValid(newtup))
- {
- heap_freetuple(oldtup);
- heap_close(pg_type_desc, RowExclusiveLock);
- elog(ERROR, "TypeRename: type %s already defined", newTypeName);
- }
+ if (SearchSysCacheExists(TYPENAME,
+ PointerGetDatum(newTypeName),
+ 0, 0, 0))
+ 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 */
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);
- heap_freetuple(oldtup);
+ heap_freetuple(tuple);
heap_close(pg_type_desc, RowExclusiveLock);
}
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index a83a5b7c3ab..bc1a2b9918f 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.8 2000/10/16 17:08:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.9 2000/11/16 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
@@ -58,8 +58,7 @@ static void del_stats(Oid relid, int attcnt, int *attnums);
void
analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
{
- HeapTuple tuple,
- typetuple;
+ HeapTuple tuple;
Relation onerel;
int32 i;
int attr_cnt,
@@ -81,20 +80,26 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
* Race condition -- if the pg_class tuple has gone away since the
* last time we saw it, we don't need to vacuum it.
*/
- tuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
+ tuple = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ CommitTransactionCommand();
+ return;
+ }
/*
* We can VACUUM ANALYZE any table except pg_statistic.
* see update_relstats
*/
- if (!HeapTupleIsValid(tuple) ||
- strcmp(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname),
- StatisticRelationName) == 0)
+ if (strcmp(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname),
+ StatisticRelationName) == 0)
{
+ ReleaseSysCache(tuple);
CommitTransactionCommand();
return;
}
+ ReleaseSysCache(tuple);
onerel = heap_open(relid, AccessShareLock);
@@ -168,6 +173,7 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
{
pgopform = (Form_pg_operator) GETSTRUCT(func_operator);
fmgr_info(pgopform->oprcode, &(stats->f_cmpeq));
+ ReleaseSysCache(func_operator);
}
else
stats->f_cmpeq.fn_addr = NULL;
@@ -178,6 +184,7 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
pgopform = (Form_pg_operator) GETSTRUCT(func_operator);
fmgr_info(pgopform->oprcode, &(stats->f_cmplt));
stats->op_cmplt = oprid(func_operator);
+ ReleaseSysCache(func_operator);
}
else
{
@@ -190,17 +197,19 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
{
pgopform = (Form_pg_operator) GETSTRUCT(func_operator);
fmgr_info(pgopform->oprcode, &(stats->f_cmpgt));
+ ReleaseSysCache(func_operator);
}
else
stats->f_cmpgt.fn_addr = NULL;
- typetuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(stats->attr->atttypid),
- 0, 0, 0);
- if (HeapTupleIsValid(typetuple))
+ tuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(stats->attr->atttypid),
+ 0, 0, 0);
+ if (HeapTupleIsValid(tuple))
{
- stats->outfunc = ((Form_pg_type) GETSTRUCT(typetuple))->typoutput;
- stats->typelem = ((Form_pg_type) GETSTRUCT(typetuple))->typelem;
+ stats->outfunc = ((Form_pg_type) GETSTRUCT(tuple))->typoutput;
+ stats->typelem = ((Form_pg_type) GETSTRUCT(tuple))->typelem;
+ ReleaseSysCache(tuple);
}
else
{
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 6611f134727..77f7776f6d9 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.70 2000/10/03 03:11:13 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.71 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -193,9 +193,7 @@ void
Async_Listen(char *relname, int pid)
{
Relation lRel;
- TupleDesc tdesc;
- HeapTuple tuple,
- newtup;
+ HeapTuple tuple;
Datum values[Natts_pg_listener];
char nulls[Natts_pg_listener];
int i;
@@ -205,13 +203,12 @@ Async_Listen(char *relname, int pid)
elog(DEBUG, "Async_Listen: %s", relname);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
- tdesc = RelationGetDescr(lRel);
/* Detect whether we are already listening on this relname */
- tuple = SearchSysCacheTuple(LISTENREL, Int32GetDatum(pid),
- PointerGetDatum(relname),
- 0, 0);
- if (tuple != NULL)
+ if (SearchSysCacheExists(LISTENREL,
+ Int32GetDatum(pid),
+ PointerGetDatum(relname),
+ 0, 0))
{
/* No need to scan the rest of the table */
heap_close(lRel, AccessExclusiveLock);
@@ -235,18 +232,18 @@ Async_Listen(char *relname, int pid)
values[i++] = (Datum) 0; /* no notifies pending */
tupDesc = lRel->rd_att;
- newtup = heap_formtuple(tupDesc, values, nulls);
- heap_insert(lRel, newtup);
+ tuple = heap_formtuple(tupDesc, values, nulls);
+ heap_insert(lRel, tuple);
if (RelationGetForm(lRel)->relhasindex)
{
Relation idescs[Num_pg_listener_indices];
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);
}
- heap_freetuple(newtup);
+ heap_freetuple(tuple);
heap_close(lRel, AccessExclusiveLock);
@@ -296,11 +293,15 @@ Async_Unlisten(char *relname, int pid)
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
/* Note we assume there can be only one matching tuple. */
- lTuple = SearchSysCacheTuple(LISTENREL, Int32GetDatum(pid),
- PointerGetDatum(relname),
- 0, 0);
- if (lTuple != NULL)
+ lTuple = SearchSysCache(LISTENREL,
+ Int32GetDatum(pid),
+ PointerGetDatum(relname),
+ 0, 0);
+ if (HeapTupleIsValid(lTuple))
+ {
heap_delete(lRel, &lTuple->t_self, NULL);
+ ReleaseSysCache(lTuple);
+ }
heap_close(lRel, AccessExclusiveLock);
/*
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index c02bafc3227..5c263e4c26c 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.59 2000/11/08 22:09:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.60 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -84,15 +84,16 @@ cluster(char *oldrelname, char *oldindexname)
/*
* Check that index is in fact an index on the given relation
*/
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(OIDOldIndex),
- 0, 0, 0);
+ tuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(OIDOldIndex),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "CLUSTER: no pg_index entry for index %u",
OIDOldIndex);
if (((Form_pg_index) GETSTRUCT(tuple))->indrelid != OIDOldHeap)
elog(ERROR, "CLUSTER: \"%s\" is not an index for table \"%s\"",
saveoldindexname, saveoldrelname);
+ ReleaseSysCache(tuple);
/* Drop relcache refcnts, but do NOT give up the locks */
heap_close(OldHeap, NoLock);
@@ -184,17 +185,17 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
* To do this I get the info from pg_index, and add a new index with
* a temporary name.
*/
- Old_pg_index_Tuple = SearchSysCacheTupleCopy(INDEXRELID,
- ObjectIdGetDatum(OIDOldIndex),
- 0, 0, 0);
+ Old_pg_index_Tuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(OIDOldIndex),
+ 0, 0, 0);
Assert(Old_pg_index_Tuple);
Old_pg_index_Form = (Form_pg_index) GETSTRUCT(Old_pg_index_Tuple);
indexInfo = BuildIndexInfo(Old_pg_index_Tuple);
- Old_pg_index_relation_Tuple = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(OIDOldIndex),
- 0, 0, 0);
+ Old_pg_index_relation_Tuple = SearchSysCache(RELOID,
+ ObjectIdGetDatum(OIDOldIndex),
+ 0, 0, 0);
Assert(Old_pg_index_relation_Tuple);
Old_pg_index_relation_Form = (Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple);
@@ -209,6 +210,9 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
setRelhasindex(OIDNewHeap, true);
+ ReleaseSysCache(Old_pg_index_Tuple);
+ ReleaseSysCache(Old_pg_index_relation_Tuple);
+
index_close(OldIndex);
heap_close(NewHeap, NoLock);
}
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index 958469fa4e1..42f05f0761c 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.111 2000/11/14 01:57:30 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.112 2000/11/16 22:30:19 tgl Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
@@ -274,13 +274,13 @@ AlterTableAddColumn(const char *relationName,
attrdesc;
Oid myrelid;
HeapTuple reltup;
+ HeapTuple newreltup;
HeapTuple attributeTuple;
Form_pg_attribute attribute;
FormData_pg_attribute attributeD;
int i;
int minattnum,
maxatts;
- HeapTuple tup;
Relation idescs[Num_pg_attr_indices];
Relation ridescs[Num_pg_class_indices];
bool hasindex;
@@ -359,9 +359,9 @@ AlterTableAddColumn(const char *relationName,
rel = heap_openr(RelationRelationName, RowExclusiveLock);
- reltup = SearchSysCacheTupleCopy(RELNAME,
- PointerGetDatum(relationName),
- 0, 0, 0);
+ reltup = SearchSysCache(RELNAME,
+ PointerGetDatum(relationName),
+ 0, 0, 0);
if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
@@ -371,10 +371,8 @@ AlterTableAddColumn(const char *relationName,
* XXX is the following check sufficient?
*/
if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
- {
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
relationName);
- }
minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
maxatts = minattnum + 1;
@@ -407,12 +405,10 @@ AlterTableAddColumn(const char *relationName,
char *typename;
int attnelems;
- tup = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(reltup->t_data->t_oid),
- PointerGetDatum(colDef->colname),
- 0, 0);
-
- if (HeapTupleIsValid(tup))
+ if (SearchSysCacheExists(ATTNAME,
+ ObjectIdGetDatum(reltup->t_data->t_oid),
+ PointerGetDatum(colDef->colname),
+ 0, 0))
elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"",
colDef->colname, relationName);
@@ -430,13 +426,13 @@ AlterTableAddColumn(const char *relationName,
else
attnelems = 0;
- typeTuple = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(typename),
- 0, 0, 0);
- tform = (Form_pg_type) GETSTRUCT(typeTuple);
-
+ typeTuple = SearchSysCache(TYPENAME,
+ PointerGetDatum(typename),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename);
+ tform = (Form_pg_type) GETSTRUCT(typeTuple);
+
namestrcpy(&(attribute->attname), colDef->colname);
attribute->atttypid = typeTuple->t_data->t_oid;
attribute->attlen = tform->typlen;
@@ -453,6 +449,8 @@ AlterTableAddColumn(const char *relationName,
attribute->atthasdef = (colDef->raw_default != NULL ||
colDef->cooked_default != NULL);
+ ReleaseSysCache(typeTuple);
+
heap_insert(attrdesc, attributeTuple);
if (hasindex)
CatalogIndexInsert(idescs,
@@ -466,15 +464,21 @@ AlterTableAddColumn(const char *relationName,
heap_close(attrdesc, RowExclusiveLock);
- ((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts;
- heap_update(rel, &reltup->t_self, reltup, NULL);
+ /*
+ * Update number of attributes in pg_class tuple
+ */
+ newreltup = heap_copytuple(reltup);
+
+ ((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts;
+ heap_update(rel, &newreltup->t_self, newreltup, NULL);
/* keep catalog indices current */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
- CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, reltup);
+ CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, newreltup);
CatalogCloseIndices(Num_pg_class_indices, ridescs);
- heap_freetuple(reltup);
+ heap_freetuple(newreltup);
+ ReleaseSysCache(reltup);
heap_close(rel, NoLock);
@@ -555,11 +559,10 @@ AlterTableAlterColumn(const char *relationName,
/*
* get the number of the attribute
*/
- tuple = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(myrelid),
- PointerGetDatum(colName),
- 0, 0);
-
+ tuple = SearchSysCache(ATTNAME,
+ ObjectIdGetDatum(myrelid),
+ PointerGetDatum(colName),
+ 0, 0);
if (!HeapTupleIsValid(tuple))
{
heap_close(rel, AccessExclusiveLock);
@@ -568,6 +571,7 @@ AlterTableAlterColumn(const char *relationName,
}
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
+ ReleaseSysCache(tuple);
if (newDefault) /* SET DEFAULT */
{
@@ -595,7 +599,6 @@ AlterTableAlterColumn(const char *relationName,
Relation attr_rel;
ScanKeyData scankeys[3];
HeapScanDesc scan;
- HeapTuple tuple;
attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock);
ScanKeyEntryInitialize(&scankeys[0], 0x0,
@@ -867,10 +870,11 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
}
else
{
- htup = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(index->indexrelid),
- 0, 0, 0);
+ htup = SearchSysCache(RELOID,
+ ObjectIdGetDatum(index->indexrelid),
+ 0, 0, 0);
RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
+ ReleaseSysCache(htup);
}
break;
}
@@ -941,18 +945,19 @@ AlterTableDropColumn(const char *relationName,
if (length(find_all_inheritors(myrelid)) > 1)
elog(ERROR, "ALTER TABLE: cannot drop a column on table that is inherited from");
-
/*
* lock the pg_class tuple for update
*/
- reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName),
- 0, 0, 0);
-
+ rel = heap_openr(RelationRelationName, RowExclusiveLock);
+ reltup = SearchSysCache(RELNAME,
+ PointerGetDatum(relationName),
+ 0, 0, 0);
if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName);
- rel = heap_openr(RelationRelationName, RowExclusiveLock);
classtuple.t_self = reltup->t_self;
+ ReleaseSysCache(reltup);
+
switch (heap_mark4update(rel, &classtuple, &buffer))
{
case HeapTupleSelfUpdated:
@@ -976,19 +981,21 @@ AlterTableDropColumn(const char *relationName,
attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock);
/*
- * Get the target pg_attribute tuple
+ * Get the target pg_attribute tuple and make a modifiable copy
*/
- tup = SearchSysCacheTupleCopy(ATTNAME,
- ObjectIdGetDatum(reltup->t_data->t_oid),
- PointerGetDatum(colName), 0, 0);
+ tup = SearchSysCacheCopy(ATTNAME,
+ ObjectIdGetDatum(reltup->t_data->t_oid),
+ PointerGetDatum(colName),
+ 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"",
colName, relationName);
attribute = (Form_pg_attribute) GETSTRUCT(tup);
- if (attribute->attnum <= 0)
- elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", colName);
attnum = attribute->attnum;
+ if (attnum <= 0)
+ elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped",
+ colName);
attoid = tup->t_data->t_oid;
/*
@@ -1226,10 +1233,9 @@ AlterTableAddConstraint(char *relationName,
int count;
List *indexoidlist,
*indexoidscan;
- Form_pg_index indexStruct = NULL;
Form_pg_attribute *rel_attrs = NULL;
- int i;
- int found=0;
+ int i;
+ bool found = false;
if (get_temp_rel_by_username(fkconstraint->pktable_name)!=NULL &&
get_temp_rel_by_username(relationName)==NULL) {
@@ -1264,42 +1270,50 @@ AlterTableAddConstraint(char *relationName,
indexoidlist = RelationGetIndexList(pkrel);
foreach(indexoidscan, indexoidlist)
+ {
+ Oid indexoid = lfirsti(indexoidscan);
+ HeapTuple indexTuple;
+ Form_pg_index indexStruct;
+
+ indexTuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexoid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(indexTuple))
+ elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
+ indexoid);
+ indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
+
+ if (indexStruct->indisunique)
{
- Oid indexoid = lfirsti(indexoidscan);
- HeapTuple indexTuple;
- List *attrl;
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexoid),
- 0, 0, 0);
- if (!HeapTupleIsValid(indexTuple))
- elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
- indexoid);
- indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
-
- if (indexStruct->indisunique) {
- /* go through the fkconstraint->pk_attrs list */
- foreach(attrl, fkconstraint->pk_attrs) {
- Ident *attr=lfirst(attrl);
- found=0;
- for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
+ List *attrl;
+
+ /* go through the fkconstraint->pk_attrs list */
+ foreach(attrl, fkconstraint->pk_attrs)
+ {
+ Ident *attr=lfirst(attrl);
+ found = false;
+ for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
+ {
+ int pkattno = indexStruct->indkey[i];
+ if (pkattno>0)
{
- int pkattno = indexStruct->indkey[i];
- if (pkattno>0) {
- char *name = NameStr(rel_attrs[pkattno-1]->attname);
- if (strcmp(name, attr->name)==0) {
- found=1;
- break;
- }
+ char *name = NameStr(rel_attrs[pkattno-1]->attname);
+ if (strcmp(name, attr->name)==0)
+ {
+ found = true;
+ break;
}
}
- if (!found)
- break;
}
+ if (!found)
+ break;
}
- if (found)
- break;
- indexStruct = NULL;
}
+ ReleaseSysCache(indexTuple);
+ if (found)
+ break;
+ }
+
if (!found)
elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
fkconstraint->pktable_name);
@@ -1309,17 +1323,18 @@ AlterTableAddConstraint(char *relationName,
rel_attrs = rel->rd_att->attrs;
if (fkconstraint->fk_attrs!=NIL) {
- int found=0;
List *fkattrs;
Ident *fkattr;
+
+ found = false;
foreach(fkattrs, fkconstraint->fk_attrs) {
- int count=0;
- found=0;
+ int count;
+ found = false;
fkattr=lfirst(fkattrs);
- for (; count < rel->rd_att->natts; count++) {
+ for (count = 0; count < rel->rd_att->natts; count++) {
char *name = NameStr(rel->rd_att->attrs[count]->attname);
if (strcmp(name, fkattr->name)==0) {
- found=1;
+ found = true;
break;
}
}
@@ -1441,20 +1456,22 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
/*
* look up the new owner in pg_shadow and get the sysid
*/
- tuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(newOwnerName),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(newOwnerName),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: user \"%s\" not found", newOwnerName);
-
newOwnerSysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid;
+ ReleaseSysCache(tuple);
/*
- * find the table's entry in pg_class and lock it for writing
+ * find the table's entry in pg_class and make a modifiable copy
*/
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
- tuple = SearchSysCacheTupleCopy(RELNAME, PointerGetDatum(relationName),
- 0, 0, 0);
+ tuple = SearchSysCacheCopy(RELNAME,
+ PointerGetDatum(relationName),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName);
@@ -1525,13 +1542,15 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
*/
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
- reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName),
- 0, 0, 0);
+ reltup = SearchSysCache(RELNAME,
+ PointerGetDatum(relationName),
+ 0, 0, 0);
if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName);
-
classtuple.t_self = reltup->t_self;
+ ReleaseSysCache(reltup);
+
switch (heap_mark4update(class_rel, &classtuple, &buffer))
{
case HeapTupleSelfUpdated:
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index bff2b897c6e..8ab997831b9 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -276,7 +276,6 @@ DeleteComments(Oid oid)
static void
CommentRelation(int reltype, char *relname, char *comment)
{
-
HeapTuple reltuple;
Oid oid;
char relkind;
@@ -288,17 +287,20 @@ CommentRelation(int reltype, char *relname, char *comment)
/*** Now, attempt to find the oid in the cached version of pg_class ***/
- reltuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname),
- 0, 0, 0);
+ reltuple = SearchSysCache(RELNAME,
+ PointerGetDatum(relname),
+ 0, 0, 0);
if (!HeapTupleIsValid(reltuple))
elog(ERROR, "relation '%s' does not exist", relname);
oid = reltuple->t_data->t_oid;
- /*** Next, verify that the relation type matches the intent ***/
-
relkind = ((Form_pg_class) GETSTRUCT(reltuple))->relkind;
+ ReleaseSysCache(reltuple);
+
+ /*** Next, verify that the relation type matches the intent ***/
+
switch (reltype)
{
case (INDEX):
@@ -322,7 +324,6 @@ CommentRelation(int reltype, char *relname, char *comment)
/*** Create the comments using the tuple's oid ***/
CreateComments(oid, comment);
-
}
/*------------------------------------------------------------------
@@ -340,9 +341,7 @@ CommentRelation(int reltype, char *relname, char *comment)
static void
CommentAttribute(char *relname, char *attrname, char *comment)
{
-
Relation relation;
- HeapTuple attrtuple;
Oid oid;
/*** First, check object security ***/
@@ -350,15 +349,19 @@ CommentAttribute(char *relname, char *attrname, char *comment)
if (!pg_ownercheck(GetUserId(), relname, 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);
- attrtuple = SearchSysCacheTuple(ATTNAME, ObjectIdGetDatum(relation->rd_id),
- PointerGetDatum(attrname), 0, 0);
- if (!HeapTupleIsValid(attrtuple))
+
+ /*** Now, fetch the attribute oid from the system cache ***/
+
+ oid = GetSysCacheOid(ATTNAME,
+ ObjectIdGetDatum(relation->rd_id),
+ PointerGetDatum(attrname),
+ 0, 0);
+ if (!OidIsValid(oid))
elog(ERROR, "'%s' is not an attribute of class '%s'",
attrname, relname);
- oid = attrtuple->t_data->t_oid;
/*** Call CreateComments() to create/drop the comments ***/
@@ -412,11 +415,13 @@ CommentDatabase(char *database, char *comment)
/*** Now, fetch user information ***/
userid = GetUserId();
- usertuple = SearchSysCacheTuple(SHADOWSYSID, ObjectIdGetDatum(userid),
- 0, 0, 0);
+ usertuple = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(userid),
+ 0, 0, 0);
if (!HeapTupleIsValid(usertuple))
elog(ERROR, "invalid user id %u", (unsigned) userid);
superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper;
+ ReleaseSysCache(usertuple);
/*** Allow if the userid matches the database dba or is a superuser ***/
@@ -452,8 +457,6 @@ CommentDatabase(char *database, char *comment)
static void
CommentRewrite(char *rule, char *comment)
{
-
- HeapTuple rewritetuple;
Oid oid;
char *relation;
int aclcheck;
@@ -472,17 +475,15 @@ CommentRewrite(char *rule, char *comment)
/*** Next, find the rule's oid ***/
- rewritetuple = SearchSysCacheTuple(RULENAME, PointerGetDatum(rule),
- 0, 0, 0);
- if (!HeapTupleIsValid(rewritetuple))
+ oid = GetSysCacheOid(RULENAME,
+ PointerGetDatum(rule),
+ 0, 0, 0);
+ if (!OidIsValid(oid))
elog(ERROR, "rule '%s' does not exist", rule);
- oid = rewritetuple->t_data->t_oid;
-
/*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment);
-
}
/*------------------------------------------------------------------
@@ -499,8 +500,6 @@ CommentRewrite(char *rule, char *comment)
static void
CommentType(char *type, char *comment)
{
-
- HeapTuple typetuple;
Oid oid;
/*** First, validate user ***/
@@ -515,17 +514,15 @@ CommentType(char *type, char *comment)
/*** Next, find the type's oid ***/
- typetuple = SearchSysCacheTuple(TYPENAME, PointerGetDatum(type),
- 0, 0, 0);
- if (!HeapTupleIsValid(typetuple))
+ oid = GetSysCacheOid(TYPENAME,
+ PointerGetDatum(type),
+ 0, 0, 0);
+ if (!OidIsValid(oid))
elog(ERROR, "type '%s' does not exist", type);
- oid = typetuple->t_data->t_oid;
-
/*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment);
-
}
/*------------------------------------------------------------------
@@ -543,7 +540,6 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
{
TypeName *aggtype = (TypeName *) lfirst(arguments);
char *aggtypename = NULL;
- HeapTuple aggtuple;
Oid baseoid,
oid;
bool defined;
@@ -580,9 +576,11 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
/*** Now, attempt to find the actual tuple in pg_aggregate ***/
- aggtuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggregate),
- ObjectIdGetDatum(baseoid), 0, 0);
- if (!HeapTupleIsValid(aggtuple))
+ oid = GetSysCacheOid(AGGNAME,
+ PointerGetDatum(aggregate),
+ ObjectIdGetDatum(baseoid),
+ 0, 0);
+ if (!OidIsValid(oid))
{
if (aggtypename)
{
@@ -593,12 +591,9 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
elog(ERROR, "aggregate '%s' does not exist", aggregate);
}
- oid = aggtuple->t_data->t_oid;
-
/*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment);
-
}
/*------------------------------------------------------------------
@@ -615,8 +610,6 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
static void
CommentProc(char *function, List *arguments, char *comment)
{
- HeapTuple argtuple,
- functuple;
Oid oid,
argoids[FUNC_MAX_ARGS];
int i,
@@ -640,12 +633,11 @@ CommentProc(char *function, List *arguments, char *comment)
argoids[i] = InvalidOid;
else
{
- argtuple = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(typnam),
- 0, 0, 0);
- if (!HeapTupleIsValid(argtuple))
+ argoids[i] = GetSysCacheOid(TYPENAME,
+ PointerGetDatum(typnam),
+ 0, 0, 0);
+ if (!OidIsValid(argoids[i]))
elog(ERROR, "CommentProc: type '%s' not found", typnam);
- argoids[i] = argtuple->t_data->t_oid;
}
}
@@ -659,14 +651,14 @@ CommentProc(char *function, List *arguments, char *comment)
/*** Now, find the corresponding oid for this procedure ***/
- functuple = SearchSysCacheTuple(PROCNAME, PointerGetDatum(function),
- Int32GetDatum(argcount),
- PointerGetDatum(argoids), 0);
- if (!HeapTupleIsValid(functuple))
+ oid = GetSysCacheOid(PROCNAME,
+ PointerGetDatum(function),
+ Int32GetDatum(argcount),
+ PointerGetDatum(argoids),
+ 0);
+ if (!OidIsValid(oid))
func_error("CommentProc", function, argcount, argoids, NULL);
- oid = functuple->t_data->t_oid;
-
/*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment);
@@ -738,10 +730,11 @@ CommentOperator(char *opername, List *arguments, char *comment)
/*** Attempt to fetch the operator oid ***/
- optuple = SearchSysCacheTupleCopy(OPERNAME, PointerGetDatum(opername),
- ObjectIdGetDatum(leftoid),
- ObjectIdGetDatum(rightoid),
- CharGetDatum(oprtype));
+ optuple = SearchSysCache(OPERNAME,
+ PointerGetDatum(opername),
+ ObjectIdGetDatum(leftoid),
+ ObjectIdGetDatum(rightoid),
+ CharGetDatum(oprtype));
if (!HeapTupleIsValid(optuple))
elog(ERROR, "operator '%s' does not exist", opername);
@@ -764,6 +757,8 @@ CommentOperator(char *opername, List *arguments, char *comment)
if (oid == InvalidOid)
elog(ERROR, "operator '%s' does not have an underlying function", opername);
+ ReleaseSysCache(optuple);
+
/*** Call CreateComments() to create/drop the comments ***/
CreateComments(oid, comment);
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 2877999500c..bbbb5aa2cfc 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.123 2000/11/12 00:36:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.124 2000/11/16 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,9 +48,9 @@
static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print);
static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print);
static Oid GetOutputFunction(Oid type);
-static Oid GetTypeElement(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 char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print);
@@ -669,7 +669,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
continue;
}
#endif /* _DROP_COLUMN_HACK__ */
- byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
+ byval[i] = IsTypeByVal(attr[i]->atttypid);
}
lineno = 0;
@@ -893,65 +893,64 @@ static Oid
GetOutputFunction(Oid type)
{
HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(type),
- 0, 0, 0);
-
- if (HeapTupleIsValid(typeTuple))
- return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput;
-
- elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type);
- return InvalidOid;
+ Oid result;
+
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type);
+ result = ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput;
+ ReleaseSysCache(typeTuple);
+ return result;
}
static Oid
-GetTypeElement(Oid type)
+GetInputFunction(Oid type)
{
HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(type),
- 0, 0, 0);
-
- if (HeapTupleIsValid(typeTuple))
- return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
-
- elog(ERROR, "GetOutputFunction: Cache lookup of type %u failed", type);
- return InvalidOid;
+ Oid result;
+
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type);
+ result = ((Form_pg_type) GETSTRUCT(typeTuple))->typinput;
+ ReleaseSysCache(typeTuple);
+ return result;
}
static Oid
-GetInputFunction(Oid type)
+GetTypeElement(Oid type)
{
HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(type),
- 0, 0, 0);
-
- if (HeapTupleIsValid(typeTuple))
- return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typinput;
-
- elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type);
- return InvalidOid;
+ Oid result;
+
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(ERROR, "GetTypeElement: Cache lookup of type %u failed", type);
+ result = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
+ ReleaseSysCache(typeTuple);
+ return result;
}
-static Oid
+static bool
IsTypeByVal(Oid type)
{
HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(type),
- 0, 0, 0);
-
- if (HeapTupleIsValid(typeTuple))
- return (int) ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval;
-
- elog(ERROR, "GetInputFunction: Cache lookup of type %u failed", type);
-
- return InvalidOid;
+ bool result;
+
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(ERROR, "IsTypeByVal: Cache lookup of type %u failed", type);
+ result = ((Form_pg_type) GETSTRUCT(typeTuple))->typbyval;
+ ReleaseSysCache(typeTuple);
+ return result;
}
diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c
index a1d45d170a1..970782d6da3 100644
--- a/src/backend/commands/creatinh.c
+++ b/src/backend/commands/creatinh.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.66 2000/11/13 09:16:55 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.67 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -408,11 +408,14 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
* form name, type and constraints
*/
attributeName = NameStr(attribute->attname);
- tuple = SearchSysCacheTuple(TYPEOID,
+ tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(attribute->atttypid),
- 0, 0, 0);
- Assert(HeapTupleIsValid(tuple));
- attributeType = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname);
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ 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
@@ -554,22 +557,25 @@ StoreCatalogInheritance(Oid relationId, List *supers)
idList = NIL;
foreach(entry, supers)
{
+ Oid entryOid;
Datum datum[Natts_pg_inherits];
char nullarr[Natts_pg_inherits];
- tuple = SearchSysCacheTuple(RELNAME,
+ entryOid = GetSysCacheOid(RELNAME,
PointerGetDatum(strVal(lfirst(entry))),
- 0, 0, 0);
- AssertArg(HeapTupleIsValid(tuple));
+ 0, 0, 0);
+ if (!OidIsValid(entryOid))
+ elog(ERROR, "StoreCatalogInheritance: cache lookup failed for relation \"%s\"",
+ strVal(lfirst(entry)));
/*
* build idList for use below
*/
- idList = lappendi(idList, tuple->t_data->t_oid);
+ idList = lappendi(idList, entryOid);
- datum[0] = ObjectIdGetDatum(relationId); /* inhrel */
- datum[1] = ObjectIdGetDatum(tuple->t_data->t_oid); /* inhparent */
- datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
+ datum[0] = ObjectIdGetDatum(relationId); /* inhrel */
+ datum[1] = ObjectIdGetDatum(entryOid); /* inhparent */
+ datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
nullarr[0] = ' ';
nullarr[1] = ' ';
@@ -624,11 +630,10 @@ StoreCatalogInheritance(Oid relationId, List *supers)
for (number = 1;; number += 1)
{
- tuple = SearchSysCacheTuple(INHRELID,
- ObjectIdGetDatum(id),
- Int16GetDatum(number),
- 0, 0);
-
+ tuple = SearchSysCache(INHRELID,
+ ObjectIdGetDatum(id),
+ Int16GetDatum(number),
+ 0, 0);
if (!HeapTupleIsValid(tuple))
break;
@@ -636,6 +641,8 @@ StoreCatalogInheritance(Oid relationId, List *supers)
GETSTRUCT(tuple))->inhparent,
NIL);
+ ReleaseSysCache(tuple);
+
current = lnext(current);
}
lnext(current) = next;
@@ -746,35 +753,28 @@ checkAttrExists(const char *attributeName, const char *attributeType, List *sche
static void
setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
{
- Relation relationRelation;
- HeapTuple tuple;
- 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);
-}
+ Relation relationRelation;
+ HeapTuple tuple;
+ Relation idescs[Num_pg_class_indices];
+ /*
+ * 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);
+}
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 70fd952db63..464a9b68fb2 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.67 2000/11/14 18:37:41 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.68 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -445,9 +445,9 @@ get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb)
{
HeapTuple utup;
- utup = SearchSysCacheTuple(SHADOWSYSID,
- ObjectIdGetDatum(use_sysid),
- 0, 0, 0);
+ utup = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(use_sysid),
+ 0, 0, 0);
if (!HeapTupleIsValid(utup))
return false;
@@ -457,6 +457,8 @@ get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb)
if (use_createdb)
*use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
+ ReleaseSysCache(utup);
+
return true;
}
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index a33d155db9f..9d681a4a50f 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -10,7 +10,7 @@
*
*
* 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
* The "DefineFoo" routines take the parse tree and pick out the
@@ -277,10 +277,9 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
Form_pg_language languageStruct;
/* Lookup the language in the system cache */
- languageTuple = SearchSysCacheTuple(LANGNAME,
- PointerGetDatum(languageName),
- 0, 0, 0);
-
+ languageTuple = SearchSysCache(LANGNAME,
+ PointerGetDatum(languageName),
+ 0, 0, 0);
if (!HeapTupleIsValid(languageTuple))
elog(ERROR,
"Unrecognized language specified in a CREATE FUNCTION: "
@@ -299,12 +298,12 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
* be defined by postgres superusers only
*/
if (!languageStruct->lanpltrusted && !superuser())
- {
elog(ERROR, "Only users with Postgres superuser privilege "
"are permitted to create a function in the '%s' "
"language.",
languageName);
- }
+
+ ReleaseSysCache(languageTuple);
}
/*
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index fff6d569753..788701b20fe 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.40 2000/11/08 22:09:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.41 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -86,7 +86,6 @@ DefineIndex(char *heapRelationName,
Oid relationId;
IndexInfo *indexInfo;
int numberOfAttributes;
- HeapTuple tuple;
List *cnfPred = NIL;
bool lossy = false;
List *pl;
@@ -111,13 +110,12 @@ DefineIndex(char *heapRelationName,
/*
* compute access method id
*/
- tuple = SearchSysCacheTuple(AMNAME,
- PointerGetDatum(accessMethodName),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
+ accessMethodId = GetSysCacheOid(AMNAME,
+ PointerGetDatum(accessMethodName),
+ 0, 0, 0);
+ if (!OidIsValid(accessMethodId))
elog(ERROR, "DefineIndex: access method \"%s\" not found",
accessMethodName);
- accessMethodId = tuple->t_data->t_oid;
/*
* XXX Hardwired hacks to check for limitations on supported index types.
@@ -239,21 +237,22 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
/*
* Get index's relation id and access method id from pg_class
*/
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(indexRelationName),
- 0, 0, 0);
+ tuple = SearchSysCache(RELNAME,
+ PointerGetDatum(indexRelationName),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ExtendIndex: index \"%s\" not found",
indexRelationName);
indexId = tuple->t_data->t_oid;
accessMethodId = ((Form_pg_class) GETSTRUCT(tuple))->relam;
+ ReleaseSysCache(tuple);
/*
* Extract info from the pg_index tuple for the index
*/
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexId),
- 0, 0, 0);
+ tuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ExtendIndex: relation \"%s\" is not an index",
indexRelationName);
@@ -262,6 +261,7 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
relationId = index->indrelid;
indexInfo = BuildIndexInfo(tuple);
oldPred = indexInfo->ii_Predicate;
+ ReleaseSysCache(tuple);
if (oldPred == NULL)
elog(ERROR, "ExtendIndex: \"%s\" is not a partial index",
@@ -391,16 +391,16 @@ FuncIndexArgs(IndexInfo *indexInfo,
HeapTuple tuple;
Form_pg_attribute att;
- tuple = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relId),
- PointerGetDatum(arg),
- 0, 0);
+ tuple = SearchSysCache(ATTNAME,
+ ObjectIdGetDatum(relId),
+ PointerGetDatum(arg),
+ 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "DefineIndex: attribute \"%s\" not found", arg);
att = (Form_pg_attribute) GETSTRUCT(tuple);
-
indexInfo->ii_KeyAttrNumbers[nargs] = att->attnum;
argTypes[nargs] = att->atttypid;
+ ReleaseSysCache(tuple);
nargs++;
}
@@ -465,10 +465,10 @@ NormIndexAttrs(IndexInfo *indexInfo,
if (attribute->name == NULL)
elog(ERROR, "missing attribute for define index");
- atttuple = SearchSysCacheTupleCopy(ATTNAME,
- ObjectIdGetDatum(relId),
- PointerGetDatum(attribute->name),
- 0, 0);
+ atttuple = SearchSysCache(ATTNAME,
+ ObjectIdGetDatum(relId),
+ PointerGetDatum(attribute->name),
+ 0, 0);
if (!HeapTupleIsValid(atttuple))
elog(ERROR, "DefineIndex: attribute \"%s\" not found",
attribute->name);
@@ -479,7 +479,7 @@ NormIndexAttrs(IndexInfo *indexInfo,
classOidP[attn] = GetAttrOpClass(attribute, attform->atttypid,
accessMethodName, accessMethodId);
- heap_freetuple(atttuple);
+ ReleaseSysCache(atttuple);
attn++;
}
}
@@ -507,13 +507,12 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
doTypeCheck = false;
}
- tuple = SearchSysCacheTuple(CLANAME,
- PointerGetDatum(attribute->class),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
+ opClassId = GetSysCacheOid(CLANAME,
+ PointerGetDatum(attribute->class),
+ 0, 0, 0);
+ if (!OidIsValid(opClassId))
elog(ERROR, "DefineIndex: opclass \"%s\" not found",
attribute->class);
- opClassId = tuple->t_data->t_oid;
/*
* Assume the opclass is supported by this index access method
@@ -532,10 +531,8 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
if (! HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
- {
elog(ERROR, "DefineIndex: opclass \"%s\" not supported by access method \"%s\"",
attribute->class, accessMethodName);
- }
oprId = ((Form_pg_amop) GETSTRUCT(tuple))->amopopr;
@@ -557,9 +554,9 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
*/
if (doTypeCheck)
{
- tuple = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(oprId),
- 0, 0, 0);
+ tuple = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(oprId),
+ 0, 0, 0);
if (HeapTupleIsValid(tuple))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tuple);
@@ -570,6 +567,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
! IS_BINARY_COMPATIBLE(attrType, opInputType))
elog(ERROR, "DefineIndex: opclass \"%s\" does not accept datatype \"%s\"",
attribute->class, typeidTypeName(attrType));
+ ReleaseSysCache(tuple);
}
}
@@ -580,15 +578,18 @@ static char *
GetDefaultOpClass(Oid atttypid)
{
HeapTuple tuple;
+ char *result;
- tuple = SearchSysCacheTuple(CLADEFTYPE,
- ObjectIdGetDatum(atttypid),
- 0, 0, 0);
+ tuple = SearchSysCache(CLADEFTYPE,
+ ObjectIdGetDatum(atttypid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
return NULL;
- return DatumGetCString(DirectFunctionCall1(nameout,
- NameGetDatum(&((Form_pg_opclass) GETSTRUCT(tuple))->opcname)));
+ result = pstrdup(NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname));
+
+ ReleaseSysCache(tuple);
+ return result;
}
/*
@@ -605,21 +606,19 @@ RemoveIndex(char *name)
{
HeapTuple tuple;
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(name),
- 0, 0, 0);
-
+ tuple = SearchSysCache(RELNAME,
+ PointerGetDatum(name),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "index \"%s\" does not exist", name);
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
- {
elog(ERROR, "relation \"%s\" is of type \"%c\"",
- name,
- ((Form_pg_class) GETSTRUCT(tuple))->relkind);
- }
+ name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
index_drop(tuple->t_data->t_oid);
+
+ ReleaseSysCache(tuple);
}
/*
@@ -644,22 +643,20 @@ ReindexIndex(const char *name, bool force /* currently unused */ )
if (IsTransactionBlock())
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(name),
- 0, 0, 0);
-
+ tuple = SearchSysCache(RELNAME,
+ PointerGetDatum(name),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "index \"%s\" does not exist", name);
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
- {
elog(ERROR, "relation \"%s\" is of type \"%c\"",
- name,
- ((Form_pg_class) GETSTRUCT(tuple))->relkind);
- }
+ name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
if (!reindex_index(tuple->t_data->t_oid, force))
elog(NOTICE, "index \"%s\" wasn't reindexed", name);
+
+ ReleaseSysCache(tuple);
}
/*
@@ -684,22 +681,20 @@ ReindexTable(const char *name, bool force)
if (IsTransactionBlock())
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(name),
- 0, 0, 0);
-
+ tuple = SearchSysCache(RELNAME,
+ PointerGetDatum(name),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "table \"%s\" does not exist", name);
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION)
- {
elog(ERROR, "relation \"%s\" is of type \"%c\"",
- name,
- ((Form_pg_class) GETSTRUCT(tuple))->relkind);
- }
+ name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
if (!reindex_relation(tuple->t_data->t_oid, force))
elog(NOTICE, "table \"%s\" wasn't reindexed", name);
+
+ ReleaseSysCache(tuple);
}
/*
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index ec8aec7005f..5d4d3f09bf7 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -48,7 +48,6 @@ void
CreateProceduralLanguage(CreatePLangStmt *stmt)
{
char languageName[NAMEDATALEN];
- HeapTuple langTup;
HeapTuple procTup;
Oid typev[FUNC_MAX_ARGS];
@@ -77,10 +76,9 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
*/
case_translate_language_name(stmt->plname, languageName);
- langTup = SearchSysCacheTuple(LANGNAME,
- PointerGetDatum(languageName),
- 0, 0, 0);
- if (HeapTupleIsValid(langTup))
+ if (SearchSysCacheExists(LANGNAME,
+ PointerGetDatum(languageName),
+ 0, 0, 0))
elog(ERROR, "Language %s already exists", languageName);
/* ----------------
@@ -89,21 +87,17 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
* ----------------
*/
memset(typev, 0, sizeof(typev));
- procTup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(stmt->plhandler),
- Int32GetDatum(0),
- PointerGetDatum(typev),
- 0);
+ procTup = SearchSysCache(PROCNAME,
+ PointerGetDatum(stmt->plhandler),
+ Int32GetDatum(0),
+ PointerGetDatum(typev),
+ 0);
if (!HeapTupleIsValid(procTup))
- {
elog(ERROR, "PL handler function %s() doesn't exist",
stmt->plhandler);
- }
if (((Form_pg_proc) GETSTRUCT(procTup))->prorettype != InvalidOid)
- {
elog(ERROR, "PL handler function %s() isn't of return type Opaque",
stmt->plhandler);
- }
/* ----------------
* Insert the new language into pg_language
@@ -123,6 +117,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
values[i++] = DirectFunctionCall1(textin,
CStringGetDatum(stmt->plcompiler));
+ ReleaseSysCache(procTup);
+
rel = heap_openr(LanguageRelationName, RowExclusiveLock);
tupDesc = rel->rd_att;
@@ -173,9 +169,9 @@ DropProceduralLanguage(DropPLangStmt *stmt)
rel = heap_openr(LanguageRelationName, RowExclusiveLock);
- langTup = SearchSysCacheTupleCopy(LANGNAME,
- PointerGetDatum(languageName),
- 0, 0, 0);
+ langTup = SearchSysCacheCopy(LANGNAME,
+ PointerGetDatum(languageName),
+ 0, 0, 0);
if (!HeapTupleIsValid(langTup))
elog(ERROR, "Language %s doesn't exist", languageName);
diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c
index a8ad2620ef7..fdcd0e7e744 100644
--- a/src/backend/commands/remove.c
+++ b/src/backend/commands/remove.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.54 2000/10/16 17:08:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.55 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,11 +73,11 @@ RemoveOperator(char *operatorName, /* operator name */
relation = heap_openr(OperatorRelationName, RowExclusiveLock);
- tup = SearchSysCacheTupleCopy(OPERNAME,
- PointerGetDatum(operatorName),
- ObjectIdGetDatum(typeId1),
- ObjectIdGetDatum(typeId2),
- CharGetDatum(oprtype));
+ tup = SearchSysCacheCopy(OPERNAME,
+ PointerGetDatum(operatorName),
+ ObjectIdGetDatum(typeId1),
+ ObjectIdGetDatum(typeId2),
+ CharGetDatum(oprtype));
if (HeapTupleIsValid(tup))
{
@@ -254,14 +254,11 @@ RemoveType(char *typeName) /* type name to be removed */
relation = heap_openr(TypeRelationName, RowExclusiveLock);
- tup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(typeName),
- 0, 0, 0);
+ tup = SearchSysCache(TYPENAME,
+ PointerGetDatum(typeName),
+ 0, 0, 0);
if (!HeapTupleIsValid(tup))
- {
- heap_close(relation, RowExclusiveLock);
elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
- }
typeOid = tup->t_data->t_oid;
@@ -271,19 +268,20 @@ RemoveType(char *typeName) /* type name to be removed */
heap_delete(relation, &tup->t_self, NULL);
- /* Now, Delete the "array of" that type */
+ ReleaseSysCache(tup);
+
+ /* Also, delete the "array of" that type */
shadow_type = makeArrayTypeName(typeName);
- tup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(shadow_type),
- 0, 0, 0);
+ tup = SearchSysCache(TYPENAME,
+ PointerGetDatum(shadow_type),
+ 0, 0, 0);
if (!HeapTupleIsValid(tup))
- {
- heap_close(relation, RowExclusiveLock);
elog(ERROR, "RemoveType: type '%s' does not exist", shadow_type);
- }
heap_delete(relation, &tup->t_self, NULL);
+ ReleaseSysCache(tup);
+
heap_close(relation, RowExclusiveLock);
}
@@ -321,12 +319,11 @@ RemoveFunction(char *functionName, /* function name to be removed */
argList[i] = InvalidOid;
else
{
- tup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(typnam),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
+ argList[i] = GetSysCacheOid(TYPENAME,
+ PointerGetDatum(typnam),
+ 0, 0, 0);
+ if (!OidIsValid(argList[i]))
elog(ERROR, "RemoveFunction: type '%s' not found", typnam);
- argList[i] = tup->t_data->t_oid;
}
}
@@ -337,11 +334,12 @@ RemoveFunction(char *functionName, /* function name to be removed */
}
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
- tup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(functionName),
- Int32GetDatum(nargs),
- PointerGetDatum(argList),
- 0);
+
+ tup = SearchSysCache(PROCNAME,
+ PointerGetDatum(functionName),
+ Int32GetDatum(nargs),
+ PointerGetDatum(argList),
+ 0);
if (!HeapTupleIsValid(tup))
func_error("RemoveFunction", functionName, nargs, argList, NULL);
@@ -359,6 +357,8 @@ RemoveFunction(char *functionName, /* function name to be removed */
heap_delete(relation, &tup->t_self, NULL);
+ ReleaseSysCache(tup);
+
heap_close(relation, RowExclusiveLock);
}
@@ -370,7 +370,6 @@ RemoveAggregate(char *aggName, char *aggType)
Oid basetypeID = InvalidOid;
bool defined;
-
/*
* if a basetype is passed in, then attempt to find an aggregate for
* that specific type.
@@ -405,10 +404,11 @@ RemoveAggregate(char *aggName, char *aggType)
}
relation = heap_openr(AggregateRelationName, RowExclusiveLock);
- tup = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggName),
- ObjectIdGetDatum(basetypeID),
- 0, 0);
+
+ tup = SearchSysCache(AGGNAME,
+ PointerGetDatum(aggName),
+ ObjectIdGetDatum(basetypeID),
+ 0, 0);
if (!HeapTupleIsValid(tup))
{
@@ -431,5 +431,7 @@ RemoveAggregate(char *aggName, char *aggType)
heap_delete(relation, &tup->t_self, NULL);
+ ReleaseSysCache(tup);
+
heap_close(relation, RowExclusiveLock);
}
diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c
index 6a9de4abf00..3722948047b 100644
--- a/src/backend/commands/rename.c
+++ b/src/backend/commands/rename.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.52 2000/11/08 22:09:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.53 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -58,8 +58,7 @@ renameatt(char *relname,
Relation targetrelation;
Relation attrelation;
HeapTuple reltup,
- oldatttup,
- newatttup;
+ atttup;
Oid relid;
/*
@@ -113,9 +112,9 @@ renameatt(char *relname,
if (childrelid == relid)
continue;
- reltup = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(childrelid),
- 0, 0, 0);
+ reltup = SearchSysCache(RELOID,
+ ObjectIdGetDatum(childrelid),
+ 0, 0, 0);
if (!HeapTupleIsValid(reltup))
{
elog(ERROR, "renameatt: can't find catalog entry for inheriting class with oid %u",
@@ -125,6 +124,7 @@ renameatt(char *relname,
StrNCpy(childname,
NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname),
NAMEDATALEN);
+ ReleaseSysCache(reltup);
/* note we need not recurse again! */
renameatt(childname, oldattname, newattname, 0);
}
@@ -132,42 +132,38 @@ renameatt(char *relname,
attrelation = heap_openr(AttributeRelationName, RowExclusiveLock);
- oldatttup = SearchSysCacheTupleCopy(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(oldattname),
- 0, 0);
- if (!HeapTupleIsValid(oldatttup))
+ atttup = SearchSysCacheCopy(ATTNAME,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(oldattname),
+ 0, 0);
+ if (!HeapTupleIsValid(atttup))
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);
- newatttup = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(newattname),
- 0, 0);
/* should not already exist */
- if (HeapTupleIsValid(newatttup))
- {
- heap_freetuple(oldatttup);
+ if (SearchSysCacheExists(ATTNAME,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(newattname),
+ 0, 0))
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);
- heap_update(attrelation, &oldatttup->t_self, oldatttup, NULL);
+ heap_update(attrelation, &atttup->t_self, atttup, NULL);
/* keep system catalog indices current */
{
Relation irelations[Num_pg_attr_indices];
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);
}
- heap_freetuple(oldatttup);
+ heap_freetuple(atttup);
heap_close(attrelation, RowExclusiveLock);
}
@@ -179,7 +175,7 @@ renamerel(const char *oldrelname, const char *newrelname)
{
Relation targetrelation;
Relation relrelation; /* for RELATION relation */
- HeapTuple oldreltup;
+ HeapTuple reltup;
Oid reloid;
char relkind;
Relation irelations[Num_pg_class_indices];
@@ -238,27 +234,27 @@ renamerel(const char *oldrelname, const char *newrelname)
*/
relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
- oldreltup = SearchSysCacheTupleCopy(RELNAME,
- PointerGetDatum(oldrelname),
- 0, 0, 0);
- if (!HeapTupleIsValid(oldreltup))
+ reltup = SearchSysCacheCopy(RELNAME,
+ PointerGetDatum(oldrelname),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(reltup))
elog(ERROR, "renamerel: relation \"%s\" does not exist", oldrelname);
if (RelnameFindRelid(newrelname) != InvalidOid)
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...)
*/
- StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(oldreltup))->relname),
+ StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname),
newrelname, NAMEDATALEN);
- heap_update(relrelation, &oldreltup->t_self, oldreltup, NULL);
+ heap_update(relrelation, &reltup->t_self, reltup, NULL);
/* keep the system catalog indices current */
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);
heap_close(relrelation, NoLock);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 33340291e1c..22dfcac0524 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.79 2000/11/08 22:09:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.80 2000/11/16 22:30:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -154,11 +154,11 @@ CreateTrigger(CreateTrigStmt *stmt)
* Find and validate the trigger function.
*/
MemSet(fargtypes, 0, FUNC_MAX_ARGS * sizeof(Oid));
- tuple = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(stmt->funcname),
- Int32GetDatum(0),
- PointerGetDatum(fargtypes),
- 0);
+ tuple = SearchSysCache(PROCNAME,
+ PointerGetDatum(stmt->funcname),
+ Int32GetDatum(0),
+ PointerGetDatum(fargtypes),
+ 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "CreateTrigger: function %s() does not exist",
stmt->funcname);
@@ -167,6 +167,8 @@ CreateTrigger(CreateTrigStmt *stmt)
stmt->funcname);
funcoid = tuple->t_data->t_oid;
funclang = ((Form_pg_proc) GETSTRUCT(tuple))->prolang;
+ ReleaseSysCache(tuple);
+
if (funclang != ClanguageId &&
funclang != NEWClanguageId &&
funclang != INTERNALlanguageId &&
@@ -174,14 +176,15 @@ CreateTrigger(CreateTrigStmt *stmt)
{
HeapTuple langTup;
- langTup = SearchSysCacheTuple(LANGOID,
- ObjectIdGetDatum(funclang),
- 0, 0, 0);
+ langTup = SearchSysCache(LANGOID,
+ ObjectIdGetDatum(funclang),
+ 0, 0, 0);
if (!HeapTupleIsValid(langTup))
elog(ERROR, "CreateTrigger: cache lookup for PL %u failed",
funclang);
if (((Form_pg_language) GETSTRUCT(langTup))->lanispl == false)
elog(ERROR, "CreateTrigger: only builtin, C and PL functions are supported");
+ ReleaseSysCache(langTup);
}
/*
@@ -268,9 +271,9 @@ CreateTrigger(CreateTrigStmt *stmt)
* rebuild relcache entries.
*/
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
- tuple = SearchSysCacheTupleCopy(RELNAME,
- PointerGetDatum(stmt->relname),
- 0, 0, 0);
+ tuple = SearchSysCacheCopy(RELNAME,
+ PointerGetDatum(stmt->relname),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "CreateTrigger: relation %s not found in pg_class",
stmt->relname);
@@ -353,9 +356,9 @@ DropTrigger(DropTrigStmt *stmt)
* rebuild relcache entries.
*/
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
- tuple = SearchSysCacheTupleCopy(RELNAME,
- PointerGetDatum(stmt->relname),
- 0, 0, 0);
+ tuple = SearchSysCacheCopy(RELNAME,
+ PointerGetDatum(stmt->relname),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "DropTrigger: relation %s not found in pg_class",
stmt->relname);
@@ -426,9 +429,9 @@ RelationRemoveTriggers(Relation rel)
Relation ridescs[Num_pg_class_indices];
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
- tup = SearchSysCacheTupleCopy(RELOID,
- RelationGetRelid(rel),
- 0, 0, 0);
+ tup = SearchSysCacheCopy(RELOID,
+ RelationGetRelid(rel),
+ 0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class",
RelationGetRelid(rel));
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 55064bf5126..a33098b2e0b 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.69 2000/10/19 03:55:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.70 2000/11/16 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -363,9 +363,9 @@ AlterUser(AlterUserStmt *stmt)
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
- tuple = SearchSysCacheTuple(SHADOWNAME,
- PointerGetDatum(stmt->user),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(stmt->user),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
heap_close(pg_shadow_rel, AccessExclusiveLock);
@@ -470,10 +470,13 @@ AlterUser(AlterUserStmt *stmt)
CatalogOpenIndices(Num_pg_shadow_indices,
Name_pg_shadow_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_shadow_indices, pg_shadow_rel,
- tuple);
+ new_tuple);
CatalogCloseIndices(Num_pg_shadow_indices, idescs);
}
+ ReleaseSysCache(tuple);
+ heap_freetuple(new_tuple);
+
/*
* Write the updated pg_shadow data to the flat password file.
*/
@@ -525,9 +528,9 @@ DropUser(DropUserStmt *stmt)
int32 usesysid;
const char *user = strVal(lfirst(item));
- tuple = SearchSysCacheTuple(SHADOWNAME,
- PointerGetDatum(user),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(user),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
heap_close(pg_shadow_rel, AccessExclusiveLock);
@@ -579,6 +582,8 @@ DropUser(DropUserStmt *stmt)
*/
heap_delete(pg_shadow_rel, &tuple->t_self, NULL);
+ ReleaseSysCache(tuple);
+
/*
* Remove user from groups
*
@@ -633,24 +638,21 @@ CheckPgUserAclNotNull()
{
HeapTuple htup;
- htup = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(ShadowRelationName),
- 0, 0, 0);
+ htup = SearchSysCache(RELNAME,
+ PointerGetDatum(ShadowRelationName),
+ 0, 0, 0);
if (!HeapTupleIsValid(htup))
- {
- /* BIG problem */
- elog(ERROR, "IsPgUserAclNull: \"%s\" not found",
+ elog(ERROR, "CheckPgUserAclNotNull: \"%s\" not found",
ShadowRelationName);
- }
if (heap_attisnull(htup, Anum_pg_class_relacl))
- {
elog(ERROR,
"To use passwords, you have to revoke permissions on %s "
"so normal users cannot read the passwords. "
"Try 'REVOKE ALL ON \"%s\" FROM PUBLIC'.",
ShadowRelationName, ShadowRelationName);
- }
+
+ ReleaseSysCache(htup);
}
@@ -716,24 +718,21 @@ CreateGroup(CreateGroupStmt *stmt)
/*
* Translate the given user names to ids
*/
-
foreach(item, stmt->initUsers)
{
const char *groupuser = strVal(lfirst(item));
Value *v;
- tuple = SearchSysCacheTuple(SHADOWNAME,
- PointerGetDatum(groupuser),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(groupuser),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
- heap_close(pg_group_rel, AccessExclusiveLock);
elog(ERROR, "CREATE GROUP: user \"%s\" does not exist", groupuser);
- }
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
if (!member(v, newlist))
newlist = lcons(v, newlist);
+ ReleaseSysCache(tuple);
}
/* build an array to insert */
@@ -817,20 +816,19 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
pg_group_dsc = RelationGetDescr(pg_group_rel);
/*
- * Verify that group exists. If we find a tuple, will take that the
- * rest of the way and make our modifications on it.
+ * Fetch existing tuple for group.
*/
- if (!HeapTupleIsValid(group_tuple = SearchSysCacheTupleCopy(GRONAME, PointerGetDatum(stmt->name), 0, 0, 0)))
- {
- heap_close(pg_group_rel, AccessExclusiveLock);
+ group_tuple = SearchSysCache(GRONAME,
+ PointerGetDatum(stmt->name),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(group_tuple))
elog(ERROR, "%s: group \"%s\" does not exist", tag, stmt->name);
- }
-
- AssertState(stmt->action == +1 || stmt->action == -1);
/*
* Now decide what to do.
*/
+ AssertState(stmt->action == +1 || stmt->action == -1);
+
if (stmt->action == +1) /* add users, might also be invoked by
* create user */
{
@@ -876,15 +874,14 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
if (strcmp(tag, "ALTER GROUP") == 0)
{
/* Get the uid of the proposed user to add. */
- tuple = SearchSysCacheTuple(SHADOWNAME,
- PointerGetDatum(strVal(lfirst(item))),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(strVal(lfirst(item))),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
- heap_close(pg_group_rel, AccessExclusiveLock);
- elog(ERROR, "%s: user \"%s\" does not exist", tag, strVal(lfirst(item)));
- }
+ elog(ERROR, "%s: user \"%s\" does not exist",
+ tag, strVal(lfirst(item)));
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
+ ReleaseSysCache(tuple);
}
else if (strcmp(tag, "CREATE USER") == 0)
{
@@ -999,15 +996,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
if (!is_dropuser)
{
/* Get the uid of the proposed user to drop. */
- tuple = SearchSysCacheTuple(SHADOWNAME,
- PointerGetDatum(strVal(lfirst(item))),
- 0, 0, 0);
+ tuple = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(strVal(lfirst(item))),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
- heap_close(pg_group_rel, AccessExclusiveLock);
elog(ERROR, "ALTER GROUP: user \"%s\" does not exist", strVal(lfirst(item)));
- }
v = makeInteger(((Form_pg_shadow) GETSTRUCT(tuple))->usesysid);
+ ReleaseSysCache(tuple);
}
else
{
@@ -1056,9 +1051,9 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
} /* endif group not null */
} /* endif alter group drop user */
- heap_close(pg_group_rel, AccessExclusiveLock);
+ ReleaseSysCache(group_tuple);
- pfree(group_tuple);
+ heap_close(pg_group_rel, AccessExclusiveLock);
}
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 403d80942de..3aeae1409bd 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.172 2000/11/16 05:50:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.173 2000/11/16 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
@@ -356,7 +356,6 @@ getrels(NameData *VacRelP)
static void
vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
{
- HeapTuple tuple;
Relation onerel;
VacPageListData vacuum_pages; /* List of pages to vacuum and/or clean
* indices */
@@ -384,10 +383,9 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
* Race condition -- if the pg_class tuple has gone away since the
* last time we saw it, we don't need to vacuum it.
*/
- tuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
+ if (!SearchSysCacheExists(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0))
{
if (!is_toastrel)
CommitTransactionCommand();
@@ -2237,17 +2235,17 @@ update_relstats(Oid relid, int num_pages, int num_tuples, bool hasindex,
*/
rd = heap_openr(RelationRelationName, RowExclusiveLock);
- ctup = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
+ ctup = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
if (!HeapTupleIsValid(ctup))
elog(ERROR, "pg_class entry for relid %u vanished during vacuuming",
relid);
/* get the buffer cache tuple */
rtup.t_self = ctup->t_self;
+ ReleaseSysCache(ctup);
heap_fetch(rd, SnapshotNow, &rtup, &buffer);
- heap_freetuple(ctup);
/* overwrite the existing statistics in the tuple */
pgcform = (Form_pg_class) GETSTRUCT(&rtup);
@@ -2481,13 +2479,14 @@ get_index_desc(Relation onerel, int nindices, Relation *Irel)
for (i = 0; i < nindices; i++)
{
- cachetuple = SearchSysCacheTuple(INDEXRELID,
+ cachetuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(RelationGetRelid(Irel[i])),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(cachetuple))
elog(ERROR, "get_index_desc: index %u not found",
RelationGetRelid(Irel[i]));
indexInfo[i] = BuildIndexInfo(cachetuple);
+ ReleaseSysCache(cachetuple);
}
return indexInfo;
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index ecdda594188..3b05a78e83a 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.68 2000/11/12 00:36:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.69 2000/11/16 22:30:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -740,9 +740,9 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo)
* Get the pg_index tuple for the index
* ----------------
*/
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexOid),
- 0, 0, 0);
+ indexTuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexOid),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "ExecOpenIndices: index %u not found", indexOid);
@@ -752,6 +752,8 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo)
*/
ii = BuildIndexInfo(indexTuple);
+ ReleaseSysCache(indexTuple);
+
relationDescs[i] = indexDesc;
indexInfoArray[i] = ii;
i++;
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index ca9c48e294d..98b28c61e10 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.40 2000/11/12 00:36:57 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.41 2000/11/16 22:30:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -183,14 +183,11 @@ init_sql_fcache(FmgrInfo *finfo)
/* ----------------
* get the procedure tuple corresponding to the given function Oid
- *
- * NB: use SearchSysCacheTupleCopy to ensure tuple lives long enough
* ----------------
*/
- procedureTuple = SearchSysCacheTupleCopy(PROCOID,
- ObjectIdGetDatum(foid),
- 0, 0, 0);
-
+ procedureTuple = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(foid),
+ 0, 0, 0);
if (!HeapTupleIsValid(procedureTuple))
elog(ERROR, "init_sql_fcache: Cache lookup failed for procedure %u",
foid);
@@ -201,10 +198,9 @@ init_sql_fcache(FmgrInfo *finfo)
* get the return type from the procedure tuple
* ----------------
*/
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(procedureStruct->prorettype),
- 0, 0, 0);
-
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(procedureStruct->prorettype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "init_sql_fcache: Cache lookup failed for type %u",
procedureStruct->prorettype);
@@ -286,7 +282,8 @@ init_sql_fcache(FmgrInfo *finfo)
pfree(src);
- heap_freetuple(procedureTuple);
+ ReleaseSysCache(typeTuple);
+ ReleaseSysCache(procedureTuple);
finfo->fn_extra = (void *) fcache;
}
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index fae1a5b0d87..827001384f6 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -34,7 +34,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.71 2000/08/24 03:29:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.72 2000/11/16 22:30:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -51,6 +51,7 @@
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
#include "parser/parse_type.h"
+#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/tuplesort.h"
#include "utils/datum.h"
@@ -105,7 +106,7 @@ typedef struct AggStatePerAggData
* We need the len and byval info for the agg's input, result, and
* transition data types in order to know how to copy/delete values.
*/
- int inputtypeLen,
+ int16 inputtypeLen,
resulttypeLen,
transtypeLen;
bool inputtypeByVal,
@@ -827,7 +828,6 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
char *aggname = aggref->aggname;
HeapTuple aggTuple;
Form_pg_aggregate aggform;
- Type typeInfo;
Oid transfn_oid,
finalfn_oid;
@@ -837,23 +837,23 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
/* Fill in the peraggstate data */
peraggstate->aggref = aggref;
- aggTuple = SearchSysCacheTupleCopy(AGGNAME,
- PointerGetDatum(aggname),
- ObjectIdGetDatum(aggref->basetype),
- 0, 0);
+ aggTuple = SearchSysCache(AGGNAME,
+ PointerGetDatum(aggname),
+ ObjectIdGetDatum(aggref->basetype),
+ 0, 0);
if (!HeapTupleIsValid(aggTuple))
elog(ERROR, "ExecAgg: cache lookup failed for aggregate %s(%s)",
aggname,
- typeidTypeName(aggref->basetype));
+ aggref->basetype ?
+ typeidTypeName(aggref->basetype) : (char *) "");
aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
- typeInfo = typeidType(aggform->aggfinaltype);
- peraggstate->resulttypeLen = typeLen(typeInfo);
- peraggstate->resulttypeByVal = typeByVal(typeInfo);
-
- typeInfo = typeidType(aggform->aggtranstype);
- peraggstate->transtypeLen = typeLen(typeInfo);
- peraggstate->transtypeByVal = typeByVal(typeInfo);
+ get_typlenbyval(aggform->aggfinaltype,
+ &peraggstate->resulttypeLen,
+ &peraggstate->resulttypeByVal);
+ get_typlenbyval(aggform->aggtranstype,
+ &peraggstate->transtypeLen,
+ &peraggstate->transtypeByVal);
peraggstate->initValue =
AggNameGetInitVal(aggname,
@@ -901,23 +901,22 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
Form_pg_operator pgopform;
peraggstate->inputType = inputType;
- typeInfo = typeidType(inputType);
- peraggstate->inputtypeLen = typeLen(typeInfo);
- peraggstate->inputtypeByVal = typeByVal(typeInfo);
+ get_typlenbyval(inputType,
+ &peraggstate->inputtypeLen,
+ &peraggstate->inputtypeByVal);
eq_operator = oper("=", inputType, inputType, true);
if (!HeapTupleIsValid(eq_operator))
- {
elog(ERROR, "Unable to identify an equality operator for type '%s'",
typeidTypeName(inputType));
- }
pgopform = (Form_pg_operator) GETSTRUCT(eq_operator);
fmgr_info(pgopform->oprcode, &(peraggstate->equalfn));
+ ReleaseSysCache(eq_operator);
peraggstate->sortOperator = any_ordering_op(inputType);
peraggstate->sortstate = NULL;
}
- heap_freetuple(aggTuple);
+ ReleaseSysCache(aggTuple);
}
return TRUE;
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index 8fc319a77f0..88b4cd27335 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -15,7 +15,7 @@
* locate group boundaries.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.38 2000/08/24 03:29:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.39 2000/11/16 22:30:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,6 +28,8 @@
#include "executor/nodeGroup.h"
#include "parser/parse_oper.h"
#include "parser/parse_type.h"
+#include "utils/lsyscache.h"
+#include "utils/syscache.h"
static TupleTableSlot *ExecGroupEveryTuple(Group *node);
static TupleTableSlot *ExecGroupOneTuple(Group *node);
@@ -498,12 +500,11 @@ execTuplesMatchPrepare(TupleDesc tupdesc,
eq_operator = oper("=", typid, typid, true);
if (!HeapTupleIsValid(eq_operator))
- {
elog(ERROR, "Unable to identify an equality operator for type '%s'",
typeidTypeName(typid));
- }
pgopform = (Form_pg_operator) GETSTRUCT(eq_operator);
fmgr_info(pgopform->oprcode, &eqfunctions[i]);
+ ReleaseSysCache(eq_operator);
}
return eqfunctions;
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 9cd85195cdc..1969c5f0bd6 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
- * $Id: nodeHash.c,v 1.52 2000/08/24 03:29:03 tgl Exp $
+ * $Id: nodeHash.c,v 1.53 2000/11/16 22:30:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,8 +29,8 @@
#include "executor/nodeHashjoin.h"
#include "miscadmin.h"
#include "parser/parse_expr.h"
-#include "parser/parse_type.h"
#include "utils/memutils.h"
+#include "utils/lsyscache.h"
static int hashFunc(Datum key, int len, bool byVal);
@@ -237,7 +237,6 @@ ExecHashTableCreate(Hash *node)
int totalbuckets;
int bucketsize;
int i;
- Type typeInfo;
MemoryContext oldcxt;
/* ----------------
@@ -353,9 +352,9 @@ ExecHashTableCreate(Hash *node)
* Get info about the datatype of the hash key.
* ----------------
*/
- typeInfo = typeidType(exprType(node->hashkey));
- hashtable->typByVal = typeByVal(typeInfo);
- hashtable->typLen = typeLen(typeInfo);
+ get_typlenbyval(exprType(node->hashkey),
+ &hashtable->typLen,
+ &hashtable->typByVal);
/* ----------------
* Create temporary memory contexts in which to keep the hashtable
@@ -546,7 +545,9 @@ ExecHashGetBucket(HashJoinTable hashtable,
}
else
{
- bucketno = hashFunc(keyval, hashtable->typLen, hashtable->typByVal)
+ bucketno = hashFunc(keyval,
+ (int) hashtable->typLen,
+ hashtable->typByVal)
% hashtable->totalbuckets;
}
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index 9d4ca0a8d54..dbeaa7a2a53 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.38 2000/09/12 21:06:48 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.39 2000/11/16 22:30:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -147,26 +147,29 @@ MJFormSkipQual(List *qualList, char *replaceopname)
* if we search with the actual operand types.
* ----------------
*/
- optup = get_operator_tuple(op->opno);
+ optup = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(op->opno),
+ 0, 0, 0);
if (!HeapTupleIsValid(optup)) /* shouldn't happen */
elog(ERROR, "MJFormSkipQual: operator %u not found", op->opno);
opform = (Form_pg_operator) GETSTRUCT(optup);
oprleft = opform->oprleft;
oprright = opform->oprright;
+ ReleaseSysCache(optup);
/* ----------------
* Now look up the matching "<" or ">" operator. If there isn't one,
* whoever marked the "=" operator mergejoinable was a loser.
* ----------------
*/
- optup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(replaceopname),
- ObjectIdGetDatum(oprleft),
- ObjectIdGetDatum(oprright),
- CharGetDatum('b'));
+ optup = SearchSysCache(OPERNAME,
+ PointerGetDatum(replaceopname),
+ ObjectIdGetDatum(oprleft),
+ ObjectIdGetDatum(oprright),
+ CharGetDatum('b'));
if (!HeapTupleIsValid(optup))
elog(ERROR,
- "MJFormSkipQual: mergejoin operator %u has no matching %s op",
+ "MJFormSkipQual: mergejoin operator %u has no matching %s op",
op->opno, replaceopname);
opform = (Form_pg_operator) GETSTRUCT(optup);
@@ -177,6 +180,7 @@ MJFormSkipQual(List *qualList, char *replaceopname)
op->opno = optup->t_data->t_oid;
op->opid = opform->oprcode;
op->op_fcache = NULL;
+ ReleaseSysCache(optup);
}
return qualCopy;
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 07a05561a64..74a5dc44415 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -3,7 +3,7 @@
* spi.c
* Server Programming Interface
*
- * $Id: spi.c,v 1.48 2000/10/26 21:35:15 tgl Exp $
+ * $Id: spi.c,v 1.49 2000/11/16 22:30:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -447,6 +447,7 @@ char *
SPI_gettype(TupleDesc tupdesc, int fnumber)
{
HeapTuple typeTuple;
+ char *result;
SPI_result = 0;
if (tupdesc->natts < fnumber || fnumber <= 0)
@@ -455,9 +456,9 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
return NULL;
}
- typeTuple = SearchSysCacheTuple(TYPEOID,
+ typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
{
@@ -465,7 +466,9 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
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
diff --git a/src/backend/lib/dllist.c b/src/backend/lib/dllist.c
index f38251934c4..175c02c3e7c 100644
--- a/src/backend/lib/dllist.c
+++ b/src/backend/lib/dllist.c
@@ -2,7 +2,6 @@
*
* dllist.c
* this is a simple doubly linked list implementation
- * replaces the old simplelists stuff
* the elements of the lists are void*
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
@@ -10,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.18 2000/06/08 22:37:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.19 2000/11/16 22:30:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,25 +32,33 @@ DLNewList(void)
{
Dllist *l;
- l = malloc(sizeof(Dllist));
+ l = (Dllist *) malloc(sizeof(Dllist));
l->dll_head = 0;
l->dll_tail = 0;
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!
*/
void
-DLFreeList(Dllist *l)
+DLFreeList(Dllist *list)
{
Dlelem *curr;
- while ((curr = DLRemHead(l)) != 0)
+ while ((curr = DLRemHead(list)) != 0)
free(curr);
- free(l);
+ free(list);
}
Dlelem *
@@ -59,7 +66,7 @@ DLNewElem(void *val)
{
Dlelem *e;
- e = malloc(sizeof(Dlelem));
+ e = (Dlelem *) malloc(sizeof(Dlelem));
e->dle_next = 0;
e->dle_prev = 0;
e->dle_val = val;
@@ -68,59 +75,18 @@ DLNewElem(void *val)
}
void
-DLFreeElem(Dlelem *e)
-{
- free(e);
-}
-
-Dlelem *
-DLGetHead(Dllist *l)
-{
- return l ? l->dll_head : 0;
-}
-
-/* get the value stored in the first element */
-#ifdef NOT_USED
-void *
-DLGetHeadVal(Dllist *l)
+DLInitElem(Dlelem *e, void *val)
{
- Dlelem *e = DLGetHead(l);
-
- return e ? e->dle_val : 0;
-}
-
-#endif
-
-Dlelem *
-DLGetTail(Dllist *l)
-{
- return l ? l->dll_tail : 0;
-}
-
-/* get the value stored in the last element */
-#ifdef NOT_USED
-void *
-DLGetTailVal(Dllist *l)
-{
- Dlelem *e = DLGetTail(l);
-
- return e ? e->dle_val : 0;
-}
-
-#endif
-
-#ifdef NOT_USED
-Dlelem *
-DLGetPred(Dlelem *e) /* get predecessor */
-{
- return e ? e->dle_prev : 0;
+ e->dle_next = 0;
+ e->dle_prev = 0;
+ e->dle_val = val;
+ e->dle_list = 0;
}
-#endif
-Dlelem *
-DLGetSucc(Dlelem *e) /* get successor */
+void
+DLFreeElem(Dlelem *e)
{
- return e ? e->dle_next : 0;
+ free(e);
}
void
@@ -131,16 +97,16 @@ DLRemove(Dlelem *e)
if (e->dle_prev)
e->dle_prev->dle_next = e->dle_next;
else
-/* must be the head element */
{
+ /* must be the head element */
Assert(e == l->dll_head);
l->dll_head = e->dle_next;
}
if (e->dle_next)
e->dle_next->dle_prev = e->dle_prev;
else
-/* must be the tail element */
{
+ /* must be the tail element */
Assert(e == l->dll_tail);
l->dll_tail = e->dle_prev;
}
@@ -194,12 +160,12 @@ DLRemHead(Dllist *l)
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 */
l->dll_tail = 0;
+ result->dle_next = 0;
+ result->dle_list = 0;
+
return result;
}
@@ -217,12 +183,12 @@ DLRemTail(Dllist *l)
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 */
l->dll_head = 0;
+ result->dle_prev = 0;
+ result->dle_list = 0;
+
return result;
}
@@ -241,8 +207,8 @@ DLMoveToFront(Dlelem *e)
if (e->dle_next)
e->dle_next->dle_prev = e->dle_prev;
else
-/* must be the tail element */
{
+ /* must be the tail element */
Assert(e == l->dll_tail);
l->dll_tail = e->dle_prev;
}
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 45e1c03738c..95bf730963f 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -8,7 +8,7 @@
*
*
* 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
* Creator functions in POSTGRES 4.2 are generated automatically. Most of
@@ -20,7 +20,10 @@
* Andrew Yu Oct 20, 1994 file creation
*/
#include "postgres.h"
+
#include "nodes/makefuncs.h"
+#include "utils/lsyscache.h"
+
/*
* makeOper -
@@ -144,6 +147,26 @@ makeConst(Oid consttype,
}
/*
+ * 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 -
* creates an Attr node
*/
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index db318a1b312..7abca0990e6 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* 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
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -1236,8 +1236,8 @@ _outJoinInfo(StringInfo str, JoinInfo *node)
static void
_outDatum(StringInfo str, Datum value, Oid type)
{
+ int16 typeLength;
bool byValue;
- int typeLength;
Size length;
char *s;
int i;
@@ -1246,8 +1246,7 @@ _outDatum(StringInfo str, Datum value, Oid type)
* find some information about the type and the "real" length of the
* datum.
*/
- byValue = get_typbyval(type);
- typeLength = get_typlen(type);
+ get_typlenbyval(type, &typeLength, &byValue);
length = datumGetSize(value, byValue, typeLength);
if (byValue)
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 5ed42accdb0..43577f94f99 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.97 2000/09/29 18:21:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.98 2000/11/16 22:30:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -808,9 +808,9 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
bool indexkey_on_left)
{
Oid expr_op = ((Oper *) clause->oper)->opno;
- Oid commuted_op;
- Operator oldop,
- newop;
+ Oid commuted_op,
+ new_op;
+ Operator oldoptup;
Form_pg_operator oldopform;
char *opname;
Oid ltype,
@@ -835,13 +835,16 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
* Get the nominal input types of the given operator and the actual
* type (before binary-compatible relabeling) of the index key.
*/
- oldop = get_operator_tuple(expr_op);
- if (! HeapTupleIsValid(oldop))
+ oldoptup = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(expr_op),
+ 0, 0, 0);
+ if (! HeapTupleIsValid(oldoptup))
return InvalidOid; /* probably can't happen */
- oldopform = (Form_pg_operator) GETSTRUCT(oldop);
- opname = NameStr(oldopform->oprname);
+ oldopform = (Form_pg_operator) GETSTRUCT(oldoptup);
+ opname = pstrdup(NameStr(oldopform->oprname));
ltype = oldopform->oprleft;
rtype = oldopform->oprright;
+ ReleaseSysCache(oldoptup);
if (indexkey_on_left)
{
@@ -875,13 +878,11 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
* (In theory this might find a non-semantically-comparable operator,
* 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_expr_op != expr_op)
+ if (new_op != expr_op)
{
/*
@@ -889,14 +890,14 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
* name; now does it match the index?
*/
if (indexkey_on_left)
- commuted_op = new_expr_op;
+ commuted_op = new_op;
else
- commuted_op = get_commutator(new_expr_op);
+ commuted_op = get_commutator(new_op);
if (commuted_op == InvalidOid)
return InvalidOid;
if (op_class(commuted_op, opclass, relam))
- return new_expr_op;
+ return new_op;
}
}
@@ -2079,16 +2080,11 @@ prefix_quals(Var *leftop, Oid expr_op,
static Oid
find_operator(const char *opname, Oid datatype)
{
- HeapTuple optup;
-
- optup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(opname),
- ObjectIdGetDatum(datatype),
- ObjectIdGetDatum(datatype),
- CharGetDatum('b'));
- if (!HeapTupleIsValid(optup))
- return InvalidOid;
- return optup->t_data->t_oid;
+ return GetSysCacheOid(OPERNAME,
+ PointerGetDatum(opname),
+ ObjectIdGetDatum(datatype),
+ ObjectIdGetDatum(datatype),
+ CharGetDatum('b'));
}
/*
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 4069ed66e58..bfb97bc1eb5 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.100 2000/11/12 00:36:58 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.101 2000/11/16 22:30:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -396,17 +396,19 @@ create_indexscan_plan(Query *root,
HeapTuple indexTuple;
Form_pg_index index;
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(lfirsti(ixid)),
- 0, 0, 0);
+ indexTuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(lfirsti(ixid)),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "create_plan: index %u not found", lfirsti(ixid));
index = (Form_pg_index) GETSTRUCT(indexTuple);
if (index->indislossy)
{
lossy = true;
+ ReleaseSysCache(indexTuple);
break;
}
+ ReleaseSysCache(indexTuple);
}
/*
@@ -904,18 +906,19 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path)
Form_pg_index index;
/* Get the relam from the index's pg_class entry */
- indexTuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexid),
- 0, 0, 0);
+ indexTuple = SearchSysCache(RELOID,
+ ObjectIdGetDatum(indexid),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "fix_indxqual_references: index %u not found in pg_class",
indexid);
relam = ((Form_pg_class) GETSTRUCT(indexTuple))->relam;
+ ReleaseSysCache(indexTuple);
/* Need the index's pg_index entry for other stuff */
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexid),
- 0, 0, 0);
+ indexTuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexid),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "fix_indxqual_references: index %u not found in pg_index",
indexid);
@@ -927,6 +930,8 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path)
relam,
index));
+ ReleaseSysCache(indexTuple);
+
indexids = lnext(indexids);
}
return fixed_quals;
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index acee58b7f07..3bea06e2af6 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.51 2000/09/29 18:21:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.52 2000/11/16 22:30:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,6 +31,7 @@
#include "parser/parse_oper.h"
#include "parser/parse_type.h"
#include "utils/lsyscache.h"
+#include "utils/syscache.h"
static void mark_baserels_for_outer_join(Query *root, Relids rels,
@@ -636,6 +637,8 @@ process_implied_equality(Query *root, Node *item1, Node *item2,
BOOLOID); /* operator result type */
clause->args = makeList2(item1, item2);
+ ReleaseSysCache(eq_operator);
+
/*
* 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-
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 296164acb89..c36e7fe7b81 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.44 2000/10/26 21:36:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.45 2000/11/16 22:30:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,7 +23,7 @@
#include "optimizer/subselect.h"
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
-#include "utils/lsyscache.h"
+#include "utils/syscache.h"
Index PlannerQueryLevel; /* level of current query */
@@ -271,8 +271,11 @@ make_subplan(SubLink *slink)
pfree(var); /* var is only needed for new_param */
Assert(IsA(oper, Oper));
- tup = get_operator_tuple(oper->opno);
- Assert(HeapTupleIsValid(tup));
+ tup = SearchSysCache(OPEROID,
+ 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);
/*
@@ -283,6 +286,8 @@ make_subplan(SubLink *slink)
exprType(lefthand), opform->oprleft);
right = make_operand("", (Node *) prm,
prm->paramtype, opform->oprright);
+ ReleaseSysCache(tup);
+
newoper = lappend(newoper,
make_opclause(oper,
(Var *) left,
@@ -401,15 +406,14 @@ make_subplan(SubLink *slink)
Node *left,
*right;
- /*
- * 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);
+ con = makeNullConst(te->resdom->restype);
Assert(IsA(oper, Oper));
- tup = get_operator_tuple(oper->opno);
- Assert(HeapTupleIsValid(tup));
+ tup = SearchSysCache(OPEROID,
+ 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);
/*
@@ -420,6 +424,8 @@ make_subplan(SubLink *slink)
exprType(lefthand), opform->oprleft);
right = make_operand("", (Node *) con,
con->consttype, opform->oprright);
+ ReleaseSysCache(tup);
+
newoper = lappend(newoper,
make_opclause(oper,
(Var *) left,
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 822c0c79f05..658c6c5e312 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.39 2000/10/05 19:11:30 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.40 2000/11/16 22:30:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -238,14 +238,7 @@ expand_targetlist(List *tlist, int command_type,
#ifdef _DROP_COLUMN_HACK__
if (COLUMN_IS_DROPPED(att_tup))
- {
- temp_var = (Var *) makeConst(atttype, 0,
- PointerGetDatum(NULL),
- true,
- false,
- false, /* not a set */
- false);
- }
+ temp_var = (Var *) makeNullConst(atttype);
else
#endif /* _DROP_COLUMN_HACK__ */
temp_var = makeVar(result_relation,
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index f52ec6d2d87..c8df8b26fe4 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* 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
* AUTHOR DATE MAJOR EVENT
@@ -28,7 +28,6 @@
#include "optimizer/clauses.h"
#include "optimizer/tlist.h"
#include "optimizer/var.h"
-#include "parser/parse_type.h"
#include "parser/parsetree.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
@@ -995,7 +994,8 @@ get_rels_atts(Node *clause,
void
CommuteClause(Expr *clause)
{
- HeapTuple heapTup;
+ Oid opoid;
+ HeapTuple optup;
Form_pg_operator commuTup;
Oper *commu;
Node *temp;
@@ -1004,19 +1004,22 @@ CommuteClause(Expr *clause)
length(clause->args) != 2)
elog(ERROR, "CommuteClause: applied to non-binary-operator clause");
- heapTup = (HeapTuple)
- get_operator_tuple(get_commutator(((Oper *) clause->oper)->opno));
+ opoid = ((Oper *) clause->oper)->opno;
- if (heapTup == (HeapTuple) NULL)
- elog(ERROR, "CommuteClause: no commutator for operator %u",
- ((Oper *) clause->oper)->opno);
+ optup = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(get_commutator(opoid)),
+ 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->oprresult);
+ ReleaseSysCache(optup);
+
/*
* re-form the clause in-place!
*/
@@ -1434,9 +1437,11 @@ simplify_op_or_func(Expr *expr, List *args)
Oid result_typeid;
HeapTuple func_tuple;
Form_pg_proc funcform;
- Type resultType;
+ bool proiscachable;
+ bool proisstrict;
+ bool proretset;
+ int16 resultTypLen;
bool resultTypByVal;
- int resultTypLen;
Expr *newexpr;
ExprContext *econtext;
Datum const_val;
@@ -1491,36 +1496,37 @@ simplify_op_or_func(Expr *expr, List *args)
* we could use func_iscachable() here, but we need several fields
* out of the func tuple, so might as well just look it up once.
*/
- func_tuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(funcid),
- 0, 0, 0);
+ func_tuple = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(funcid),
+ 0, 0, 0);
if (!HeapTupleIsValid(func_tuple))
elog(ERROR, "Function OID %u does not exist", funcid);
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;
/*
* Also check to make sure it doesn't return a set.
*/
- if (funcform->proretset)
+ if (proretset)
return NULL;
/*
* Now that we know if the function is strict, we can finish the
* 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.
* Return a NULL constant of the right type.
*/
- resultType = typeidType(result_typeid);
- return (Expr *) makeConst(result_typeid, typeLen(resultType),
- (Datum) 0, true,
- typeByVal(resultType),
- false, false);
+ return (Expr *) makeNullConst(result_typeid);
}
/*
@@ -1548,9 +1554,7 @@ simplify_op_or_func(Expr *expr, List *args)
newexpr->args = args;
/* Get info needed about result datatype */
- resultType = typeidType(result_typeid);
- resultTypByVal = typeByVal(resultType);
- resultTypLen = typeLen(resultType);
+ get_typlenbyval(result_typeid, &resultTypLen, &resultTypByVal);
/*
* It is OK to pass a dummy econtext because none of the ExecEvalExpr()
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 0d32e82ed9a..055cd3788b9 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.61 2000/09/29 18:21:23 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.62 2000/11/16 22:30:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,9 +48,9 @@ relation_info(Oid relationObjectId,
HeapTuple relationTuple;
Form_pg_class relation;
- relationTuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relationObjectId),
- 0, 0, 0);
+ relationTuple = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relationObjectId),
+ 0, 0, 0);
if (!HeapTupleIsValid(relationTuple))
elog(ERROR, "relation_info: Relation %u not found",
relationObjectId);
@@ -62,6 +62,7 @@ relation_info(Oid relationObjectId,
*hasindex = (relation->relhasindex) ? true : false;
*pages = relation->relpages;
*tuples = relation->reltuples;
+ ReleaseSysCache(relationTuple);
}
/*
@@ -100,9 +101,9 @@ find_secondary_indexes(Oid relationObjectId)
Oid relam;
uint16 amorderstrategy;
- indexTuple = SearchSysCacheTupleCopy(INDEXRELID,
- ObjectIdGetDatum(indexoid),
- 0, 0, 0);
+ indexTuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexoid),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "find_secondary_indexes: index %u not found",
indexoid);
@@ -162,20 +163,22 @@ find_secondary_indexes(Oid relationObjectId)
Form_pg_amop amop;
amopTuple =
- SearchSysCacheTuple(AMOPSTRATEGY,
- ObjectIdGetDatum(relam),
- ObjectIdGetDatum(index->indclass[i]),
- UInt16GetDatum(amorderstrategy),
- 0);
+ SearchSysCache(AMOPSTRATEGY,
+ ObjectIdGetDatum(relam),
+ ObjectIdGetDatum(index->indclass[i]),
+ UInt16GetDatum(amorderstrategy),
+ 0);
if (!HeapTupleIsValid(amopTuple))
elog(ERROR, "find_secondary_indexes: no amop %u %u %d",
- relam, index->indclass[i], (int) amorderstrategy);
+ relam, index->indclass[i],
+ (int) amorderstrategy);
amop = (Form_pg_amop) GETSTRUCT(amopTuple);
info->ordering[i] = amop->amopopr;
+ ReleaseSysCache(amopTuple);
}
}
- heap_freetuple(indexTuple);
+ ReleaseSysCache(indexTuple);
indexinfos = lcons(info, indexinfos);
}
@@ -315,13 +318,16 @@ find_inheritance_children(Oid inhparent)
bool
has_subclass(Oid relationId)
{
- HeapTuple tuple =
- SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relationId),
- 0, 0, 0);
+ HeapTuple tuple;
+ bool result;
+ tuple = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relationId),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- elog(ERROR, "has_subclass: Relation %u not found",
- relationId);
- return ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass;
+ elog(ERROR, "has_subclass: Relation %u not found", relationId);
+
+ result = ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass;
+ ReleaseSysCache(tuple);
+ return result;
}
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 63f39f2e4cb..478ae973e5c 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: analyze.c,v 1.165 2000/11/08 22:09:58 tgl Exp $
+ * $Id: analyze.c,v 1.166 2000/11/16 22:30:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2598,9 +2598,8 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
Form_pg_attribute *pkrel_attrs;
List *indexoidlist,
*indexoidscan;
- Form_pg_index indexStruct = NULL;
int i;
- int found=0;
+ bool found = false;
/* ----------
* Open the referenced table and get the attributes list
@@ -2616,7 +2615,7 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
* Get the list of index OIDs for the table from the relcache,
* and look up each one in the pg_index syscache for each unique
* one, and then compare the attributes we were given to those
- * defined.
+ * defined.
* ----------
*/
indexoidlist = RelationGetIndexList(pkrel);
@@ -2625,27 +2624,34 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
{
Oid indexoid = lfirsti(indexoidscan);
HeapTuple indexTuple;
- List *attrl;
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexoid),
- 0, 0, 0);
+ Form_pg_index indexStruct;
+
+ indexTuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexoid),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
indexoid);
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
- if (indexStruct->indisunique) {
+ if (indexStruct->indisunique)
+ {
+ List *attrl;
+
/* go through the fkconstraint->pk_attrs list */
- foreach(attrl, fkconstraint->pk_attrs) {
+ foreach(attrl, fkconstraint->pk_attrs)
+ {
Ident *attr=lfirst(attrl);
- found=0;
+ found = false;
for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
{
int pkattno = indexStruct->indkey[i];
- if (pkattno>0) {
+ if (pkattno>0)
+ {
char *name = NameStr(pkrel_attrs[pkattno - 1]->attname);
- if (strcmp(name, attr->name)==0) {
- found=1;
+ if (strcmp(name, attr->name)==0)
+ {
+ found = true;
break;
}
}
@@ -2654,9 +2660,9 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint)
break;
}
}
+ ReleaseSysCache(indexTuple);
if (found)
break;
- indexStruct = NULL;
}
if (!found)
elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
@@ -2681,6 +2687,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint)
Form_pg_attribute *pkrel_attrs;
List *indexoidlist,
*indexoidscan;
+ HeapTuple indexTuple = NULL;
Form_pg_index indexStruct = NULL;
int i;
@@ -2705,17 +2712,17 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint)
foreach(indexoidscan, indexoidlist)
{
Oid indexoid = lfirsti(indexoidscan);
- HeapTuple indexTuple;
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexoid),
- 0, 0, 0);
+ indexTuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexoid),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
indexoid);
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
if (indexStruct->indisprimary)
break;
+ ReleaseSysCache(indexTuple);
indexStruct = NULL;
}
@@ -2747,6 +2754,8 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint)
fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr);
}
+ ReleaseSysCache(indexTuple);
+
heap_close(pkrel, AccessShareLock);
}
@@ -2861,6 +2870,7 @@ static void
transformColumnType(ParseState *pstate, ColumnDef *column)
{
TypeName *typename = column->typename;
+ Type ctype = typenameType(typename->name);
/*
* If the column doesn't have an explicitly specified typmod, check to
@@ -2871,7 +2881,7 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
*/
if (typename->typmod == -1)
{
- switch (typeTypeId(typenameType(typename->name)))
+ switch (typeTypeId(ctype))
{
case BPCHAROID:
/* "char" -> "char(1)" */
@@ -2891,11 +2901,13 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
* XXX this is a hangover from ancient Berkeley code that probably
* doesn't work anymore anyway.
*/
- if (typeTypeRelid(typenameType(typename->name)) != InvalidOid)
+ if (typeTypeRelid(ctype) != InvalidOid)
{
/* (Eventually add in here that the set can only
* contain one element.)
*/
typename->setof = true;
}
+
+ ReleaseSysCache(ctype);
}
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index e7d8fe8d3b7..1dc31dc1f07 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.42 2000/09/29 18:21:36 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.43 2000/11/16 22:30:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -190,18 +190,18 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
List *args, bool agg_star, bool agg_distinct,
int precedence)
{
- HeapTuple theAggTuple;
+ HeapTuple aggtuple;
Form_pg_aggregate aggform;
Aggref *aggref;
- theAggTuple = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggname),
- ObjectIdGetDatum(basetype),
- 0, 0);
+ aggtuple = SearchSysCache(AGGNAME,
+ PointerGetDatum(aggname),
+ ObjectIdGetDatum(basetype),
+ 0, 0);
/* shouldn't happen --- caller should have checked already */
- if (!HeapTupleIsValid(theAggTuple))
+ if (!HeapTupleIsValid(aggtuple))
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.
@@ -225,6 +225,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
aggref->aggstar = agg_star;
aggref->aggdistinct = agg_distinct;
+ ReleaseSysCache(aggtuple);
+
pstate->p_hasAggs = true;
return aggref;
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index cbd19f0aae4..c8f55c98e84 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.72 2000/11/12 00:37:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.73 2000/11/16 22:30:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -953,9 +953,7 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
- grpcl->sortop = oprid(oper("<",
- tle->resdom->restype,
- tle->resdom->restype, false));
+ grpcl->sortop = any_ordering_op(tle->resdom->restype);
glist = lappend(glist, grpcl);
}
@@ -1151,9 +1149,10 @@ addTargetToSortList(TargetEntry *tle, List *sortlist, List *targetlist,
sortcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
if (opname)
- sortcl->sortop = oprid(oper(opname,
- tle->resdom->restype,
- tle->resdom->restype, false));
+ sortcl->sortop = oper_oid(opname,
+ tle->resdom->restype,
+ tle->resdom->restype,
+ false);
else
sortcl->sortop = any_ordering_op(tle->resdom->restype);
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index f0d3427d17e..131d65cbcd0 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.48 2000/11/09 04:14:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.49 2000/11/16 22:30:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -84,6 +84,8 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
pfree(val);
}
+ ReleaseSysCache(targetType);
+
result = (Node *) newcon;
}
else if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId))
@@ -124,9 +126,8 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
* conversion function.
*/
FuncCall *n = makeNode(FuncCall);
- Type targetType = typeidType(targetTypeId);
- n->funcname = typeTypeName(targetType);
+ n->funcname = typeidTypeName(targetTypeId);
n->args = lcons(node, NIL);
n->agg_star = false;
n->agg_distinct = false;
@@ -136,7 +137,7 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
/* safety check that we got the right thing */
if (exprType(result) != targetTypeId)
elog(ERROR, "coerce_type: conversion function %s produced %s",
- typeTypeName(targetType),
+ typeidTypeName(targetTypeId),
typeidTypeName(exprType(result)));
/*
@@ -233,17 +234,21 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
oid_array[0] = inputTypeId;
- ftup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(typeidTypeName(targetTypeId)),
- Int32GetDatum(1),
- PointerGetDatum(oid_array),
- 0);
+ ftup = SearchSysCache(PROCNAME,
+ PointerGetDatum(typeidTypeName(targetTypeId)),
+ Int32GetDatum(1),
+ PointerGetDatum(oid_array),
+ 0);
if (!HeapTupleIsValid(ftup))
return false;
/* Make sure the function's result type is as expected, too */
pform = (Form_pg_proc) GETSTRUCT(ftup);
if (pform->prorettype != targetTypeId)
+ {
+ ReleaseSysCache(ftup);
return false;
+ }
+ ReleaseSysCache(ftup);
}
return true;
@@ -272,7 +277,6 @@ coerce_type_typmod(ParseState *pstate, Node *node,
{
char *funcname;
Oid oid_array[FUNC_MAX_ARGS];
- HeapTuple ftup;
/*
* We assume that only typmod values greater than 0 indicate a forced
@@ -288,13 +292,11 @@ coerce_type_typmod(ParseState *pstate, Node *node,
oid_array[1] = INT4OID;
/* attempt to find with arguments exactly as specified... */
- ftup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(funcname),
- Int32GetDatum(2),
- PointerGetDatum(oid_array),
- 0);
-
- if (HeapTupleIsValid(ftup))
+ if (SearchSysCacheExists(PROCNAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(2),
+ PointerGetDatum(oid_array),
+ 0))
{
A_Const *cons = makeNode(A_Const);
FuncCall *func = makeNode(FuncCall);
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index ecf88ceea7e..97ed8123f67 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.87 2000/11/16 17:27:10 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.88 2000/11/16 22:30:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -386,7 +386,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
optup = oper(op,
exprType(lexpr),
exprType(tent->expr),
- FALSE);
+ false);
opform = (Form_pg_operator) GETSTRUCT(optup);
if (opform->oprresult != BOOLOID)
@@ -399,6 +399,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
InvalidOid, /* opid */
opform->oprresult);
sublink->oper = lappend(sublink->oper, newop);
+ ReleaseSysCache(optup);
}
if (left_list != NIL)
elog(ERROR, "Subselect has too few fields");
@@ -740,7 +741,8 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
{
Func *func;
Const *second_arg;
- HeapTuple tup;
+ HeapTuple procTuple;
+ HeapTuple typeTuple;
Form_pg_proc procStruct;
Form_pg_type typeStruct;
@@ -771,12 +773,12 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
/*
* Lookup the function in pg_proc
*/
- tup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(func->funcid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
+ procTuple = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(func->funcid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(procTuple))
elog(ERROR, "cache lookup for proc %u failed", func->funcid);
- procStruct = (Form_pg_proc) GETSTRUCT(tup);
+ procStruct = (Form_pg_proc) GETSTRUCT(procTuple);
/*
* It must be a function with two arguments where the first is of the
@@ -787,29 +789,39 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
procStruct->prorettype != procStruct->proargtypes[0] ||
procStruct->proargtypes[1] != INT4OID ||
procStruct->prorettype != ((Expr *) expr)->typeOid)
+ {
+ ReleaseSysCache(procTuple);
return false;
+ }
/*
* Furthermore, the name of the function must be the same as the
* argument/result type's name.
*/
- tup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(procStruct->prorettype),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(procStruct->prorettype),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "cache lookup for type %u failed",
procStruct->prorettype);
- typeStruct = (Form_pg_type) GETSTRUCT(tup);
+ typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
if (strncmp(NameStr(procStruct->proname),
NameStr(typeStruct->typname),
NAMEDATALEN) != 0)
+ {
+ ReleaseSysCache(procTuple);
+ ReleaseSysCache(typeTuple);
return false;
+ }
/*
* OK, it is indeed a length-coercion function.
*/
if (coercedTypmod != NULL)
*coercedTypmod = DatumGetInt32(second_arg->constvalue);
+
+ ReleaseSysCache(procTuple);
+ ReleaseSysCache(typeTuple);
return true;
}
@@ -865,6 +877,8 @@ parser_typecast_constant(Value *expr, TypeName *typename)
if (string_palloced)
pfree(const_string);
+ ReleaseSysCache(tp);
+
return (Node *) con;
}
@@ -881,11 +895,9 @@ parser_typecast_expression(ParseState *pstate,
Node *expr, TypeName *typename)
{
Oid inputType = exprType(expr);
- Type tp;
Oid targetType;
- tp = typenameType(TypeNameToInternalName(typename));
- targetType = typeTypeId(tp);
+ targetType = typenameTypeId(TypeNameToInternalName(typename));
if (inputType == InvalidOid)
return expr; /* do nothing if NULL input */
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index ea0544f701e..688c5bfa306 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.93 2000/11/11 19:49:26 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.94 2000/11/16 22:30:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -354,19 +354,19 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
CandidateList candidates;
/* try for exact match first... */
- if (SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(funcname),
- ObjectIdGetDatum(basetype),
- 0, 0))
+ if (SearchSysCacheExists(AGGNAME,
+ PointerGetDatum(funcname),
+ ObjectIdGetDatum(basetype),
+ 0, 0))
return (Node *) ParseAgg(pstate, funcname, basetype,
fargs, agg_star, agg_distinct,
precedence);
/* check for aggregate-that-accepts-any-type (eg, COUNT) */
- if (SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(funcname),
- ObjectIdGetDatum(0),
- 0, 0))
+ if (SearchSysCacheExists(AGGNAME,
+ PointerGetDatum(funcname),
+ ObjectIdGetDatum(0),
+ 0, 0))
return (Node *) ParseAgg(pstate, funcname, 0,
fargs, agg_star, agg_distinct,
precedence);
@@ -450,7 +450,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
if (rte->relname == NULL)
elog(ERROR,
"function applied to tuple is not supported for subSELECTs");
- toid = typeTypeId(typenameType(rte->relname));
+ toid = typenameTypeId(rte->relname);
/* replace it in the arg list */
lfirst(i) = makeVar(vnum, 0, toid, -1, sublevels_up);
@@ -531,15 +531,14 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
*/
if (nargs == 1)
{
- Type tp;
+ Oid targetType;
- tp = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(funcname),
- 0, 0, 0);
- if (HeapTupleIsValid(tp))
+ targetType = GetSysCacheOid(TYPENAME,
+ PointerGetDatum(funcname),
+ 0, 0, 0);
+ if (OidIsValid(targetType))
{
Oid sourceType = oid_array[0];
- Oid targetType = typeTypeId(tp);
Node *arg1 = lfirst(fargs);
if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) ||
@@ -573,6 +572,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
if (typeTypeFlag(tp) == 'c')
elog(ERROR, "No such attribute or function '%s'",
funcname);
+ ReleaseSysCache(tp);
}
/* Else generate a detailed complaint */
@@ -1037,11 +1037,11 @@ func_get_detail(char *funcname,
HeapTuple ftup;
/* attempt to find with arguments exactly as specified... */
- ftup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(argtypes),
- 0);
+ ftup = SearchSysCache(PROCNAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(argtypes),
+ 0);
if (HeapTupleIsValid(ftup))
{
@@ -1085,11 +1085,11 @@ func_get_detail(char *funcname,
if (ncandidates == 1)
{
*true_typeids = current_function_typeids->args;
- ftup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
+ ftup = SearchSysCache(PROCNAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
PointerGetDatum(*true_typeids),
- 0);
+ 0);
Assert(HeapTupleIsValid(ftup));
break;
}
@@ -1107,12 +1107,13 @@ func_get_detail(char *funcname,
if (*true_typeids != NULL)
{
/* was able to choose a best candidate */
- ftup = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(*true_typeids),
- 0);
+ ftup = SearchSysCache(PROCNAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(*true_typeids),
+ 0);
Assert(HeapTupleIsValid(ftup));
+ break;
}
/*
@@ -1143,6 +1144,7 @@ func_get_detail(char *funcname,
*funcid = ftup->t_data->t_oid;
*rettype = pform->prorettype;
*retset = pform->proretset;
+ ReleaseSysCache(ftup);
return true;
}
return false;
@@ -1284,7 +1286,7 @@ find_inheritors(Oid relid, Oid **supervec)
relid = lfirsti(elt);
rd = heap_open(relid, NoLock);
- trelid = typeTypeId(typenameType(RelationGetRelationName(rd)));
+ trelid = typenameTypeId(RelationGetRelationName(rd));
heap_close(rd, NoLock);
*relidvec++ = trelid;
}
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index d23c5c1e7c7..1d846bd4bba 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.48 2000/10/31 10:22:11 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.49 2000/11/16 22:30:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -67,7 +67,6 @@ make_operand(char *opname,
Oid target_typeId)
{
Node *result;
- Type target_type = typeidType(target_typeId);
if (tree != NULL)
{
@@ -80,15 +79,7 @@ make_operand(char *opname,
else
{
/* otherwise, this is a NULL value */
- Const *con = makeNode(Const);
-
- con->consttype = target_typeId;
- con->constlen = typeLen(target_type);
- con->constvalue = (Datum) NULL;
- con->constisnull = true;
- con->constbyval = typeByVal(target_type);
- con->constisset = false;
- result = (Node *) con;
+ result = (Node *) makeNullConst(target_typeId);
}
return result;
@@ -137,7 +128,7 @@ make_op(char *opname, Node *ltree, Node *rtree)
/* otherwise, binary operator */
else
{
- tup = oper(opname, ltypeId, rtypeId, FALSE);
+ tup = oper(opname, ltypeId, rtypeId, false);
opform = (Form_pg_operator) GETSTRUCT(tup);
left = make_operand(opname, ltree, ltypeId, opform->oprleft);
right = make_operand(opname, rtree, rtypeId, opform->oprright);
@@ -159,6 +150,8 @@ make_op(char *opname, Node *ltree, Node *rtree)
else
result->args = makeList2(left, right);
+ ReleaseSysCache(tup);
+
return result;
} /* make_op() */
@@ -183,10 +176,10 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno)
HeapTuple tp;
Form_pg_attribute att_tup;
- tp = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(rte->relid),
- Int16GetDatum(attrno),
- 0, 0);
+ tp = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(rte->relid),
+ Int16GetDatum(attrno),
+ 0, 0);
/* this shouldn't happen... */
if (!HeapTupleIsValid(tp))
elog(ERROR, "Relation %s does not have attribute %d",
@@ -194,6 +187,7 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno)
att_tup = (Form_pg_attribute) GETSTRUCT(tp);
vartypeid = att_tup->atttypid;
type_mod = att_tup->atttypmod;
+ ReleaseSysCache(tp);
}
else
{
@@ -249,7 +243,8 @@ transformArraySubscripts(ParseState *pstate,
Oid typearray,
typeelement,
typeresult;
- HeapTuple type_tuple;
+ HeapTuple type_tuple_array,
+ type_tuple_element;
Form_pg_type type_struct_array,
type_struct_element;
bool isSlice = forceSlice;
@@ -261,13 +256,13 @@ transformArraySubscripts(ParseState *pstate,
/* Get the type tuple for the array */
typearray = exprType(arrayBase);
- type_tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typearray),
- 0, 0, 0);
- if (!HeapTupleIsValid(type_tuple))
+ type_tuple_array = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typearray),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(type_tuple_array))
elog(ERROR, "transformArraySubscripts: Cache lookup failed for array type %u",
typearray);
- type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple);
+ type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array);
typeelement = type_struct_array->typelem;
if (typeelement == InvalidOid)
@@ -275,13 +270,13 @@ transformArraySubscripts(ParseState *pstate,
NameStr(type_struct_array->typname));
/* Get the type tuple for the array element type */
- type_tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typeelement),
- 0, 0, 0);
- if (!HeapTupleIsValid(type_tuple))
+ type_tuple_element = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typeelement),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(type_tuple_element))
elog(ERROR, "transformArraySubscripts: Cache lookup failed for array element type %u",
typeelement);
- type_struct_element = (Form_pg_type) GETSTRUCT(type_tuple);
+ type_struct_element = (Form_pg_type) GETSTRUCT(type_tuple_element);
/*
* A list containing only single subscripts refers to a single array
@@ -398,6 +393,9 @@ transformArraySubscripts(ParseState *pstate,
aref->refexpr = arrayBase;
aref->refassgnexpr = assignFrom;
+ ReleaseSysCache(type_tuple_array);
+ ReleaseSysCache(type_tuple_element);
+
return aref;
}
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 7d3919a1fc6..a44a740dc92 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.43 2000/11/11 19:49:26 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.44 2000/11/16 22:30:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,25 +38,21 @@ static void op_error(char *op, Oid arg1, Oid arg2);
static void unary_op_error(char *op, Oid arg, bool is_left_op);
+/* Select an ordering operator for the given datatype */
Oid
any_ordering_op(Oid restype)
{
- Operator order_op;
Oid order_opid;
- order_op = oper("<", restype, restype, TRUE);
- if (!HeapTupleIsValid(order_op))
- {
+ order_opid = oper_oid("<", restype, restype, true);
+ if (!OidIsValid(order_opid))
elog(ERROR, "Unable to identify an ordering operator '%s' for type '%s'"
"\n\tUse an explicit ordering operator or modify the query",
"<", typeidTypeName(restype));
- }
- order_opid = oprid(order_op);
-
return order_opid;
}
-/* given operator, return the operator OID */
+/* given operator tuple, return the operator OID */
Oid
oprid(Operator op)
{
@@ -502,9 +498,10 @@ oper_select_candidate(int nargs,
/* oper_exact()
- * Given operator, and arguments, return oper struct or NULL.
- * Inputs:
- * arg1, arg2: Type IDs
+ * Given operator, types of arg1 and arg2, return oper struct or NULL.
+ *
+ * NOTE: on success, the returned object is a syscache entry. The caller
+ * must ReleaseSysCache() the entry when done with it.
*/
static Operator
oper_exact(char *op, Oid arg1, Oid arg2)
@@ -517,20 +514,21 @@ oper_exact(char *op, Oid arg1, Oid arg2)
else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
arg2 = arg1;
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(arg1),
- ObjectIdGetDatum(arg2),
- CharGetDatum('b'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(arg1),
+ ObjectIdGetDatum(arg2),
+ CharGetDatum('b'));
return (Operator) tup;
-} /* oper_exact() */
+}
/* oper_inexact()
- * Given operator, types of arg1, and arg2, return oper struct or NULL.
- * Inputs:
- * arg1, arg2: Type IDs
+ * Given operator, types of arg1 and arg2, return oper struct or NULL.
+ *
+ * NOTE: on success, the returned object is a syscache entry. The caller
+ * must ReleaseSysCache() the entry when done with it.
*/
static Operator
oper_inexact(char *op, Oid arg1, Oid arg2)
@@ -556,11 +554,11 @@ oper_inexact(char *op, Oid arg1, Oid arg2)
/* Or found exactly one? Then proceed... */
else if (ncandidates == 1)
{
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(candidates->args[0]),
- ObjectIdGetDatum(candidates->args[1]),
- CharGetDatum('b'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(candidates->args[0]),
+ ObjectIdGetDatum(candidates->args[1]),
+ CharGetDatum('b'));
Assert(HeapTupleIsValid(tup));
}
@@ -572,43 +570,68 @@ oper_inexact(char *op, Oid arg1, Oid arg2)
targetOids = oper_select_candidate(2, inputOids, candidates);
if (targetOids != NULL)
{
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(targetOids[0]),
- ObjectIdGetDatum(targetOids[1]),
- CharGetDatum('b'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(targetOids[0]),
+ ObjectIdGetDatum(targetOids[1]),
+ CharGetDatum('b'));
}
else
tup = NULL;
}
return (Operator) tup;
-} /* oper_inexact() */
+}
-/* oper()
- * Given operator, types of arg1, and arg2, return oper struct.
- * Inputs:
- * arg1, arg2: Type IDs
+/* oper() -- search for a binary operator
+ * Given operator name, types of arg1 and arg2, return oper struct.
+ *
+ * If no matching operator found, return NULL if noError is true,
+ * raise an error if it is false.
+ *
+ * NOTE: on success, the returned object is a syscache entry. The caller
+ * must ReleaseSysCache() the entry when done with it.
*/
Operator
-oper(char *opname, Oid ltypeId, Oid rtypeId, bool noWarnings)
+oper(char *opname, Oid ltypeId, Oid rtypeId, bool noError)
{
HeapTuple tup;
/* check for exact match on this operator... */
if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId)))
- {
- }
+ return (Operator) tup;
+
/* try to find a match on likely candidates... */
- else if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId)))
- {
- }
- else if (!noWarnings)
+ if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId)))
+ return (Operator) tup;
+
+ if (!noError)
op_error(opname, ltypeId, rtypeId);
- return (Operator) tup;
-} /* oper() */
+ return (Operator) NULL;
+}
+
+/* oper_oid() -- get OID of a binary operator
+ *
+ * This is a convenience routine that extracts only the operator OID
+ * from the result of oper(). InvalidOid is returned if the lookup
+ * fails and noError is true.
+ */
+Oid
+oper_oid(char *op, Oid arg1, Oid arg2, bool noError)
+{
+ Operator optup;
+ Oid result;
+ optup = oper(op, arg1, arg2, noError);
+ if (optup != NULL)
+ {
+ result = oprid(optup);
+ ReleaseSysCache(optup);
+ return result;
+ }
+ return InvalidOid;
+}
/* unary_oper_get_candidates()
* given opname, find all possible types for which
@@ -671,8 +694,13 @@ unary_oper_get_candidates(char *opname,
} /* unary_oper_get_candidates() */
-/* Given unary right-side operator (operator on right), return oper struct */
-/* arg-- type id */
+/* Given unary right operator (operator on right), return oper struct
+ *
+ * Always raises error on failure.
+ *
+ * NOTE: on success, the returned object is a syscache entry. The caller
+ * must ReleaseSysCache() the entry when done with it.
+ */
Operator
right_oper(char *op, Oid arg)
{
@@ -682,11 +710,11 @@ right_oper(char *op, Oid arg)
Oid *targetOid;
/* Try for exact match */
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(arg),
- ObjectIdGetDatum(InvalidOid),
- CharGetDatum('r'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(arg),
+ ObjectIdGetDatum(InvalidOid),
+ CharGetDatum('r'));
if (!HeapTupleIsValid(tup))
{
@@ -696,21 +724,21 @@ right_oper(char *op, Oid arg)
unary_op_error(op, arg, FALSE);
else if (ncandidates == 1)
{
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(candidates->args[0]),
- ObjectIdGetDatum(InvalidOid),
- CharGetDatum('r'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(candidates->args[0]),
+ ObjectIdGetDatum(InvalidOid),
+ CharGetDatum('r'));
}
else
{
targetOid = oper_select_candidate(1, &arg, candidates);
if (targetOid != NULL)
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(targetOid[0]),
- ObjectIdGetDatum(InvalidOid),
- CharGetDatum('r'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(targetOid[0]),
+ ObjectIdGetDatum(InvalidOid),
+ CharGetDatum('r'));
}
if (!HeapTupleIsValid(tup))
@@ -721,8 +749,13 @@ right_oper(char *op, Oid arg)
} /* right_oper() */
-/* Given unary left-side operator (operator on left), return oper struct */
-/* arg--type id */
+/* Given unary left operator (operator on left), return oper struct
+ *
+ * Always raises error on failure.
+ *
+ * NOTE: on success, the returned object is a syscache entry. The caller
+ * must ReleaseSysCache() the entry when done with it.
+ */
Operator
left_oper(char *op, Oid arg)
{
@@ -732,11 +765,11 @@ left_oper(char *op, Oid arg)
Oid *targetOid;
/* Try for exact match */
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(InvalidOid),
- ObjectIdGetDatum(arg),
- CharGetDatum('l'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(InvalidOid),
+ ObjectIdGetDatum(arg),
+ CharGetDatum('l'));
if (!HeapTupleIsValid(tup))
{
@@ -746,21 +779,21 @@ left_oper(char *op, Oid arg)
unary_op_error(op, arg, TRUE);
else if (ncandidates == 1)
{
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(InvalidOid),
- ObjectIdGetDatum(candidates->args[0]),
- CharGetDatum('l'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(InvalidOid),
+ ObjectIdGetDatum(candidates->args[0]),
+ CharGetDatum('l'));
}
else
{
targetOid = oper_select_candidate(1, &arg, candidates);
if (targetOid != NULL)
- tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(InvalidOid),
- ObjectIdGetDatum(targetOid[0]),
- CharGetDatum('l'));
+ tup = SearchSysCache(OPERNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(InvalidOid),
+ ObjectIdGetDatum(targetOid[0]),
+ CharGetDatum('l'));
}
if (!HeapTupleIsValid(tup))
@@ -778,24 +811,17 @@ left_oper(char *op, Oid arg)
static void
op_error(char *op, Oid arg1, Oid arg2)
{
- Type tp1 = NULL,
- tp2 = NULL;
-
- if (typeidIsValid(arg1))
- tp1 = typeidType(arg1);
- else
+ if (!typeidIsValid(arg1))
elog(ERROR, "Left hand side of operator '%s' has an unknown type"
"\n\tProbably a bad attribute name", op);
- if (typeidIsValid(arg2))
- tp2 = typeidType(arg2);
- else
+ if (!typeidIsValid(arg2))
elog(ERROR, "Right hand side of operator %s has an unknown type"
"\n\tProbably a bad attribute name", op);
elog(ERROR, "Unable to identify an operator '%s' for types '%s' and '%s'"
"\n\tYou will have to retype this query using an explicit cast",
- op, typeTypeName(tp1), typeTypeName(tp2));
+ op, typeidTypeName(arg1), typeidTypeName(arg2));
}
/* unary_op_error()
@@ -805,20 +831,14 @@ op_error(char *op, Oid arg1, Oid arg2)
static void
unary_op_error(char *op, Oid arg, bool is_left_op)
{
- Type tp1 = NULL;
-
- if (typeidIsValid(arg))
- tp1 = typeidType(arg);
- else
- {
+ if (!typeidIsValid(arg))
elog(ERROR, "Argument of %s operator '%s' has an unknown type"
"\n\tProbably a bad attribute name",
(is_left_op ? "left" : "right"),
op);
- }
elog(ERROR, "Unable to identify a %s operator '%s' for type '%s'"
"\n\tYou may need to add parentheses or an explicit cast",
(is_left_op ? "left" : "right"),
- op, typeTypeName(tp1));
+ op, typeidTypeName(arg));
}
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index c582bd54abe..5a699624097 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.32 2000/06/08 22:37:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.33 2000/11/16 22:30:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,63 +28,45 @@
bool
typeidIsValid(Oid id)
{
- return (SearchSysCacheTuple(TYPEOID,
+ return SearchSysCacheExists(TYPEOID,
ObjectIdGetDatum(id),
- 0, 0, 0) != NULL);
-}
-
-/* return a type name, given a typeid */
-char *
-typeidTypeName(Oid id)
-{
- HeapTuple tup;
- Form_pg_type typetuple;
-
- if (!(tup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(id),
- 0, 0, 0)))
- {
- elog(ERROR, "Unable to locate type oid %u in catalog", id);
- return NULL;
- }
- typetuple = (Form_pg_type) GETSTRUCT(tup);
- /* pstrdup here because result may need to outlive the syscache entry */
- return pstrdup(NameStr(typetuple->typname));
+ 0, 0, 0);
}
/* return a Type structure, given a type id */
+/* NB: caller must ReleaseSysCache the type tuple when done with it */
Type
typeidType(Oid id)
{
HeapTuple tup;
- if (!(tup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(id),
- 0, 0, 0)))
- {
+ tup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
elog(ERROR, "Unable to locate type oid %u in catalog", id);
- return NULL;
- }
return (Type) tup;
}
/* return a Type structure, given type name */
+/* NB: caller must ReleaseSysCache the type tuple when done with it */
Type
typenameType(char *s)
{
HeapTuple tup;
if (s == NULL)
- elog(ERROR, "type(): Null type");
+ elog(ERROR, "typenameType: Null typename");
- if (!(tup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(s),
- 0, 0, 0)))
+ tup = SearchSysCache(TYPENAME,
+ PointerGetDatum(s),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
elog(ERROR, "Unable to locate type name '%s' in catalog", s);
return (Type) tup;
}
-/* given type, return the type OID */
+/* given type (as type struct), return the type OID */
Oid
typeTypeId(Type tp)
{
@@ -134,6 +116,54 @@ typeTypeFlag(Type t)
return typ->typtype;
}
+Oid
+typeTypeRelid(Type typ)
+{
+ Form_pg_type typtup;
+
+ typtup = (Form_pg_type) GETSTRUCT(typ);
+
+ return typtup->typrelid;
+}
+
+#ifdef NOT_USED
+Oid
+typeTypElem(Type typ)
+{
+ Form_pg_type typtup;
+
+ typtup = (Form_pg_type) GETSTRUCT(typ);
+
+ return typtup->typelem;
+}
+#endif
+
+#ifdef NOT_USED
+/* Given a type structure, return the in-conversion function of the type */
+Oid
+typeInfunc(Type typ)
+{
+ Form_pg_type typtup;
+
+ typtup = (Form_pg_type) GETSTRUCT(typ);
+
+ return typtup->typinput;
+}
+#endif
+
+#ifdef NOT_USED
+/* Given a type structure, return the out-conversion function of the type */
+Oid
+typeOutfunc(Type typ)
+{
+ Form_pg_type typtup;
+
+ typtup = (Form_pg_type) GETSTRUCT(typ);
+
+ return typtup->typoutput;
+}
+#endif
+
/* Given a type structure and a string, returns the internal form of
that string */
Datum
@@ -160,109 +190,72 @@ typeidOutfunc(Oid type_id)
Form_pg_type type;
Oid outfunc;
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(type_id),
- 0, 0, 0);
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type_id),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "typeidOutfunc: Invalid type - oid = %u", type_id);
type = (Form_pg_type) GETSTRUCT(typeTuple);
outfunc = type->typoutput;
+ ReleaseSysCache(typeTuple);
return outfunc;
}
#endif
+/* return a type name, given a typeid */
+char *
+typeidTypeName(Oid id)
+{
+ HeapTuple tup;
+ Form_pg_type typetuple;
+ char *result;
+
+ tup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "Unable to locate type oid %u in catalog", id);
+ typetuple = (Form_pg_type) GETSTRUCT(tup);
+ /*
+ * pstrdup here because result may need to outlive the syscache entry
+ * (eg, it might end up as part of a parse tree that will outlive
+ * the current transaction...)
+ */
+ result = pstrdup(NameStr(typetuple->typname));
+ ReleaseSysCache(tup);
+ return result;
+}
+
+/* given a typeid, return the type's typrelid (associated relation, if any) */
Oid
typeidTypeRelid(Oid type_id)
{
HeapTuple typeTuple;
Form_pg_type type;
+ Oid result;
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(type_id),
- 0, 0, 0);
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type_id),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "typeidTypeRelid: Invalid type - oid = %u", type_id);
type = (Form_pg_type) GETSTRUCT(typeTuple);
- return type->typrelid;
-}
-
-Oid
-typeTypeRelid(Type typ)
-{
- Form_pg_type typtup;
-
- typtup = (Form_pg_type) GETSTRUCT(typ);
-
- return typtup->typrelid;
-}
-
-#ifdef NOT_USED
-Oid
-typeTypElem(Type typ)
-{
- Form_pg_type typtup;
-
- typtup = (Form_pg_type) GETSTRUCT(typ);
-
- return typtup->typelem;
-}
-#endif
-
-#ifdef NOT_USED
-/* Given the attribute type of an array return the attribute type of
- an element of the array */
-Oid
-GetArrayElementType(Oid typearray)
-{
- HeapTuple type_tuple;
- Form_pg_type type_struct_array;
-
- type_tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typearray),
- 0, 0, 0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(ERROR, "GetArrayElementType: Cache lookup failed for type %u",
- typearray);
-
- /* get the array type struct from the type tuple */
- type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple);
-
- if (type_struct_array->typelem == InvalidOid)
- {
- elog(ERROR, "GetArrayElementType: type %s is not an array",
- NameStr(type_struct_array->typname));
- }
-
- return type_struct_array->typelem;
+ result = type->typrelid;
+ ReleaseSysCache(typeTuple);
+ return result;
}
-#endif
-#ifdef NOT_USED
-/* Given a type structure, return the in-conversion function of the type */
+/* given a type name, return the type's typeid */
Oid
-typeInfunc(Type typ)
+typenameTypeId(char *s)
{
- Form_pg_type typtup;
-
- typtup = (Form_pg_type) GETSTRUCT(typ);
+ Type typ = typenameType(s);
+ Oid result;
- return typtup->typinput;
+ result = typ->t_data->t_oid;
+ ReleaseSysCache(typ);
+ return result;
}
-#endif
-
-#ifdef NOT_USED
-/* Given a type structure, return the out-conversion function of the type */
-Oid
-typeOutfunc(Type typ)
-{
- Form_pg_type typtup;
-
- typtup = (Form_pg_type) GETSTRUCT(typ);
-
- return typtup->typoutput;
-}
-#endif
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index cffe624deb4..3e1f8f4a68d 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -7,12 +7,13 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.50 2000/10/05 19:11:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.51 2000/11/16 22:30:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/tlist.h"
#include "parser/parsetree.h"
@@ -555,20 +556,6 @@ AddNotQual(Query *parsetree, Node *qual)
}
-/* Build a NULL constant expression of the given type */
-static Node *
-make_null(Oid type)
-{
- Const *c = makeNode(Const);
-
- c->consttype = type;
- c->constlen = get_typlen(type);
- c->constvalue = PointerGetDatum(NULL);
- c->constisnull = true;
- c->constbyval = get_typbyval(type);
- return (Node *) c;
-}
-
/* Find a targetlist entry by resno */
static Node *
FindMatchingNew(List *tlist, int attno)
@@ -656,7 +643,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
else
{
/* Otherwise replace unmatched var with a null */
- return make_null(var->vartype);
+ return (Node *) makeNullConst(var->vartype);
}
}
else
@@ -796,7 +783,7 @@ HandleRIRAttributeRule_mutator(Node *node,
{ /* HACK: disallow SET variables */
*context->modified = TRUE;
*context->badsql = TRUE;
- return make_null(var->vartype);
+ return (Node *) makeNullConst(var->vartype);
}
else
{
@@ -813,7 +800,7 @@ HandleRIRAttributeRule_mutator(Node *node,
n = FindMatchingTLEntry(context->targetlist,
name_to_look_for);
if (n == NULL)
- return make_null(var->vartype);
+ return (Node *) makeNullConst(var->vartype);
/* Make a copy of the tlist item to return */
n = copyObject(n);
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index ba409f4fbf6..760614461cd 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.40 2000/09/29 18:21:24 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.41 2000/11/16 22:30:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,21 +35,26 @@ RewriteGetRuleEventRel(char *rulename)
{
HeapTuple htup;
Oid eventrel;
+ char *result;
- htup = SearchSysCacheTuple(RULENAME,
- PointerGetDatum(rulename),
- 0, 0, 0);
+ htup = SearchSysCache(RULENAME,
+ PointerGetDatum(rulename),
+ 0, 0, 0);
if (!HeapTupleIsValid(htup))
elog(ERROR, "Rule or view \"%s\" not found",
((strncmp(rulename, "_RET", 4) == 0) ? (rulename + 4) : rulename));
eventrel = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class;
- htup = SearchSysCacheTuple(RELOID,
- PointerGetDatum(eventrel),
- 0, 0, 0);
+ ReleaseSysCache(htup);
+
+ htup = SearchSysCache(RELOID,
+ PointerGetDatum(eventrel),
+ 0, 0, 0);
if (!HeapTupleIsValid(htup))
elog(ERROR, "Relation %u not found", eventrel);
- return NameStr(((Form_pg_class) GETSTRUCT(htup))->relname);
+ result = pstrdup(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
+ ReleaseSysCache(htup);
+ return result;
}
/*
@@ -75,9 +80,9 @@ RemoveRewriteRule(char *ruleName)
/*
* Find the tuple for the target rule.
*/
- tuple = SearchSysCacheTupleCopy(RULENAME,
- PointerGetDatum(ruleName),
- 0, 0, 0);
+ tuple = SearchSysCacheCopy(RULENAME,
+ PointerGetDatum(ruleName),
+ 0, 0, 0);
/*
* complain if no rule with such name existed
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index 264021da223..30e4ba6e603 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.44 2000/09/29 18:21:24 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.45 2000/11/16 22:30:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,19 +18,15 @@
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "rewrite/rewriteSupport.h"
-#include "utils/catcache.h"
#include "utils/syscache.h"
-int
+bool
IsDefinedRewriteRule(char *ruleName)
{
- HeapTuple tuple;
-
- tuple = SearchSysCacheTuple(RULENAME,
+ return SearchSysCacheExists(RULENAME,
PointerGetDatum(ruleName),
0, 0, 0);
- return HeapTupleIsValid(tuple);
}
/*
@@ -59,10 +55,11 @@ SetRelationRuleStatus(Oid relationId, bool relHasRules,
* Find the tuple to update in pg_class, using syscache for the lookup.
*/
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
- tuple = SearchSysCacheTupleCopy(RELOID,
- ObjectIdGetDatum(relationId),
- 0, 0, 0);
- Assert(HeapTupleIsValid(tuple));
+ tuple = SearchSysCacheCopy(RELOID,
+ ObjectIdGetDatum(relationId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "SetRelationRuleStatus: cache lookup failed for relation %u", relationId);
/* Do the update */
((Form_pg_class) GETSTRUCT(tuple))->relhasrules = relHasRules;
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index 05640b5be8f..c888ea012ac 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.44 2000/10/24 20:59:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.45 2000/11/16 22:30:30 tgl Exp $
*
* NOTES
* This cruft is the server side of PQfn.
@@ -202,14 +202,12 @@ update_fp_info(Oid func_id, struct fp_info * fip)
MemSet((char *) fip, 0, (int) sizeof(struct fp_info));
fip->funcid = InvalidOid;
- func_htp = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(func_id),
- 0, 0, 0);
+ func_htp = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(func_id),
+ 0, 0, 0);
if (!HeapTupleIsValid(func_htp))
- {
elog(ERROR, "update_fp_info: cache lookup for function %u failed",
func_id);
- }
pp = (Form_pg_proc) GETSTRUCT(func_htp);
rettype = pp->prorettype;
argtypes = pp->proargtypes;
@@ -220,38 +218,38 @@ update_fp_info(Oid func_id, struct fp_info * fip)
{
if (OidIsValid(argtypes[i]))
{
- type_htp = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(argtypes[i]),
- 0, 0, 0);
+ type_htp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(argtypes[i]),
+ 0, 0, 0);
if (!HeapTupleIsValid(type_htp))
- {
elog(ERROR, "update_fp_info: bad argument type %u for %u",
argtypes[i], func_id);
- }
tp = (Form_pg_type) GETSTRUCT(type_htp);
fip->argbyval[i] = tp->typbyval;
fip->arglen[i] = tp->typlen;
+ ReleaseSysCache(type_htp);
} /* else it had better be VAR_LENGTH_ARG */
}
if (OidIsValid(rettype))
{
- type_htp = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(rettype),
- 0, 0, 0);
+ type_htp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(rettype),
+ 0, 0, 0);
if (!HeapTupleIsValid(type_htp))
- {
elog(ERROR, "update_fp_info: bad return type %u for %u",
rettype, func_id);
- }
tp = (Form_pg_type) GETSTRUCT(type_htp);
fip->retbyval = tp->typbyval;
fip->retlen = tp->typlen;
+ ReleaseSysCache(type_htp);
} /* else it had better by VAR_LENGTH_RESULT */
fip->xid = GetCurrentTransactionId();
fip->cid = GetCurrentCommandId();
+ ReleaseSysCache(func_htp);
+
/*
* This must be last!
*/
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 63a43315286..e725ff391f4 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.102 2000/11/14 18:37:43 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.103 2000/11/16 22:30:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -102,9 +102,9 @@ CheckDropPermissions(char *name, char rightkind)
break;
Assert(rentry->kind != '\0');
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(name),
- 0, 0, 0);
+ tuple = SearchSysCache(RELNAME,
+ PointerGetDatum(name),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "%s \"%s\" does not exist", rentry->name, name);
@@ -120,6 +120,8 @@ CheckDropPermissions(char *name, char rightkind)
if (!allowSystemTableMods && IsSystemRelationName(name))
elog(ERROR, "%s \"%s\" is a system %s",
rentry->name, name, rentry->name);
+
+ ReleaseSysCache(tuple);
}
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 1a2b2ef953e..a8bc5e349a3 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.52 2000/11/03 19:01:36 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.53 2000/11/16 22:30:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -174,12 +174,13 @@ aclparse(char *s, AclItem *aip, unsigned *modechg)
switch (aip->ai_idtype)
{
case ACL_IDTYPE_UID:
- htup = SearchSysCacheTuple(SHADOWNAME,
- PointerGetDatum(name),
- 0, 0, 0);
+ htup = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(name),
+ 0, 0, 0);
if (!HeapTupleIsValid(htup))
elog(ERROR, "aclparse: non-existent user \"%s\"", name);
aip->ai_id = ((Form_pg_shadow) GETSTRUCT(htup))->usesysid;
+ ReleaseSysCache(htup);
break;
case ACL_IDTYPE_GID:
aip->ai_id = get_grosysid(name);
@@ -272,9 +273,9 @@ aclitemout(PG_FUNCTION_ARGS)
switch (aip->ai_idtype)
{
case ACL_IDTYPE_UID:
- htup = SearchSysCacheTuple(SHADOWSYSID,
- ObjectIdGetDatum(aip->ai_id),
- 0, 0, 0);
+ htup = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(aip->ai_id),
+ 0, 0, 0);
if (!HeapTupleIsValid(htup))
{
/* Generate numeric UID if we don't find an entry */
@@ -286,9 +287,12 @@ aclitemout(PG_FUNCTION_ARGS)
pfree(tmp);
}
else
+ {
strncat(p, (char *) &((Form_pg_shadow)
GETSTRUCT(htup))->usename,
sizeof(NameData));
+ ReleaseSysCache(htup);
+ }
break;
case ACL_IDTYPE_GID:
strcat(p, "group ");
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 44f58840c36..47c1b814c4d 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.65 2000/11/14 23:28:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.66 2000/11/16 22:30:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1590,9 +1590,9 @@ system_cache_lookup(Oid element_type,
HeapTuple typeTuple;
Form_pg_type typeStruct;
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(element_type),
- 0, 0, 0);
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(element_type),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "array_out: Cache lookup failed for type %u",
element_type);
@@ -1607,6 +1607,7 @@ system_cache_lookup(Oid element_type,
*proc = typeStruct->typinput;
else
*proc = typeStruct->typoutput;
+ ReleaseSysCache(typeTuple);
}
/*
diff --git a/src/backend/utils/adt/format_type.c b/src/backend/utils/adt/format_type.c
index f32122173d8..6022dc78519 100644
--- a/src/backend/utils/adt/format_type.c
+++ b/src/backend/utils/adt/format_type.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.5 2000/08/26 21:53:41 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.6 2000/11/16 22:30:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -98,9 +98,9 @@ format_type_internal(Oid type_oid, int32 typemod)
if (type_oid == InvalidOid)
return pstrdup("-");
- tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(type_oid),
- 0, 0, 0);
-
+ tuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(type_oid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
return pstrdup("???");
@@ -108,9 +108,11 @@ format_type_internal(Oid type_oid, int32 typemod)
typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen;
if (array_base_type != 0 && typlen < 0)
{
- tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(array_base_type),
- 0, 0, 0);
+ /* Switch our attention to the array element type */
+ ReleaseSysCache(tuple);
+ tuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(array_base_type),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
return pstrdup("???[]");
is_array = true;
@@ -211,6 +213,8 @@ format_type_internal(Oid type_oid, int32 typemod)
if (is_array)
buf = psnprintf(strlen(buf) + 3, "%s[]", buf);
+ ReleaseSysCache(tuple);
+
return buf;
}
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 84c4694115d..4a2bb3c4fd6 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.58 2000/07/09 21:30:12 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.59 2000/11/16 22:30:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,13 +55,12 @@ regprocin(PG_FUNCTION_ARGS)
if (pro_name_or_oid[0] >= '0' &&
pro_name_or_oid[0] <= '9')
{
- proctup = SearchSysCacheTuple(PROCOID,
- DirectFunctionCall1(oidin,
+ result = (RegProcedure)
+ GetSysCacheOid(PROCOID,
+ DirectFunctionCall1(oidin,
CStringGetDatum(pro_name_or_oid)),
- 0, 0, 0);
- if (HeapTupleIsValid(proctup))
- result = (RegProcedure) proctup->t_data->t_oid;
- else
+ 0, 0, 0);
+ if (!RegProcedureIsValid(result))
elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
}
else
@@ -176,9 +175,9 @@ regprocout(PG_FUNCTION_ARGS)
if (!IsBootstrapProcessingMode())
{
- proctup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(proid),
- 0, 0, 0);
+ proctup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(proid),
+ 0, 0, 0);
if (HeapTupleIsValid(proctup))
{
@@ -186,6 +185,7 @@ regprocout(PG_FUNCTION_ARGS)
s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname);
StrNCpy(result, s, NAMEDATALEN);
+ ReleaseSysCache(proctup);
}
else
{
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 723adcda35c..5bfea0ff42f 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -6,7 +6,7 @@
*
* 1999 Jan Wieck
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.17 2000/09/25 22:34:20 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.18 2000/11/16 22:30:31 tgl Exp $
*
* ----------
*/
@@ -3300,24 +3300,26 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
HeapTuple opr_tup;
Form_pg_operator opr_struct;
- opr_tup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum("="),
- ObjectIdGetDatum(typeid),
- ObjectIdGetDatum(typeid),
- CharGetDatum('b'));
-
+ opr_tup = SearchSysCache(OPERNAME,
+ PointerGetDatum("="),
+ ObjectIdGetDatum(typeid),
+ ObjectIdGetDatum(typeid),
+ CharGetDatum('b'));
if (!HeapTupleIsValid(opr_tup))
elog(ERROR, "ri_AttributesEqual(): cannot find '=' operator "
"for type %u", typeid);
opr_struct = (Form_pg_operator) GETSTRUCT(opr_tup);
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
- (char *) &typeid, HASH_ENTER, &found);
+ (char *) &typeid,
+ HASH_ENTER,
+ &found);
if (entry == NULL)
elog(FATAL, "can't insert into RI operator cache");
entry->typeid = typeid;
fmgr_info(opr_struct->oprcode, &(entry->oprfmgrinfo));
+ ReleaseSysCache(opr_tup);
}
/* ----------
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index cc25a5a026a..3cd543b5e68 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.68 2000/11/05 00:15:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.69 2000/11/16 22:30:31 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -374,8 +374,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
* Fetch the pg_index tuple by the Oid of the index
* ----------
*/
- ht_idx = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexrelid), 0, 0, 0);
+ ht_idx = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
if (!HeapTupleIsValid(ht_idx))
elog(ERROR, "syscache lookup for index %u failed", indexrelid);
idxrec = (Form_pg_index) GETSTRUCT(ht_idx);
@@ -384,8 +385,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
* Fetch the pg_class tuple of the index relation
* ----------
*/
- ht_idxrel = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(idxrec->indexrelid), 0, 0, 0);
+ ht_idxrel = SearchSysCache(RELOID,
+ ObjectIdGetDatum(idxrec->indexrelid),
+ 0, 0, 0);
if (!HeapTupleIsValid(ht_idxrel))
elog(ERROR, "syscache lookup for relid %u failed", idxrec->indexrelid);
idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
@@ -394,8 +396,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
* Fetch the pg_class tuple of the indexed relation
* ----------
*/
- ht_indrel = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(idxrec->indrelid), 0, 0, 0);
+ ht_indrel = SearchSysCache(RELOID,
+ ObjectIdGetDatum(idxrec->indrelid),
+ 0, 0, 0);
if (!HeapTupleIsValid(ht_indrel))
elog(ERROR, "syscache lookup for relid %u failed", idxrec->indrelid);
indrelrec = (Form_pg_class) GETSTRUCT(ht_indrel);
@@ -484,12 +487,13 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
HeapTuple proctup;
Form_pg_proc procStruct;
- proctup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(idxrec->indproc), 0, 0, 0);
+ proctup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(idxrec->indproc),
+ 0, 0, 0);
if (!HeapTupleIsValid(proctup))
elog(ERROR, "cache lookup for proc %u failed", idxrec->indproc);
-
procStruct = (Form_pg_proc) GETSTRUCT(proctup);
+
appendStringInfo(&buf, "%s(%s) ",
quote_identifier(pstrdup(NameStr(procStruct->proname))),
keybuf.data);
@@ -508,6 +512,7 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, "%s",
quote_identifier(SPI_getvalue(spi_tup, spi_ttc,
spi_fno)));
+ ReleaseSysCache(proctup);
}
else
/* ----------
@@ -523,15 +528,19 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, ")");
/* ----------
- * Create the result in upper executor memory
+ * Create the result in upper executor memory, and free objects
* ----------
*/
len = buf.len + VARHDRSZ;
indexdef = SPI_palloc(len);
VARATT_SIZEP(indexdef) = len;
memcpy(VARDATA(indexdef), buf.data, buf.len);
+
pfree(buf.data);
pfree(keybuf.data);
+ ReleaseSysCache(ht_idx);
+ ReleaseSysCache(ht_idxrel);
+ ReleaseSysCache(ht_indrel);
/* ----------
* Disconnect from SPI manager
@@ -568,13 +577,14 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
* Get the pg_shadow entry and print the result
* ----------
*/
- usertup = SearchSysCacheTuple(SHADOWSYSID,
- ObjectIdGetDatum(uid),
- 0, 0, 0);
+ usertup = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(uid),
+ 0, 0, 0);
if (HeapTupleIsValid(usertup))
{
user_rec = (Form_pg_shadow) GETSTRUCT(usertup);
StrNCpy(NameStr(*result), NameStr(user_rec->usename), NAMEDATALEN);
+ ReleaseSysCache(usertup);
}
else
sprintf(NameStr(*result), "unknown (UID=%d)", uid);
@@ -1392,10 +1402,11 @@ get_rule_expr(Node *node, deparse_context *context)
HeapTuple tp;
Form_pg_operator optup;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
- Assert(HeapTupleIsValid(tp));
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup for operator %u failed", opno);
optup = (Form_pg_operator) GETSTRUCT(tp);
switch (optup->oprkind)
{
@@ -1414,6 +1425,7 @@ get_rule_expr(Node *node, deparse_context *context)
default:
elog(ERROR, "get_rule_expr: bogus oprkind");
}
+ ReleaseSysCache(tp);
}
appendStringInfoChar(buf, ')');
break;
@@ -1524,9 +1536,9 @@ get_rule_expr(Node *node, deparse_context *context)
/* we do NOT parenthesize the arg expression, for now */
get_rule_expr(fselect->arg, context);
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(exprType(fselect->arg)),
- 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(exprType(fselect->arg)),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup of type %u failed",
exprType(fselect->arg));
@@ -1538,6 +1550,7 @@ get_rule_expr(Node *node, deparse_context *context)
fieldname = get_relid_attribute_name(typrelid,
fselect->fieldnum);
appendStringInfo(buf, ".%s", quote_identifier(fieldname));
+ ReleaseSysCache(typetup);
}
break;
@@ -1550,9 +1563,9 @@ get_rule_expr(Node *node, deparse_context *context)
appendStringInfoChar(buf, '(');
get_rule_expr(relabel->arg, context);
- typetup = SearchSysCacheTuple(TYPEOID,
+ typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(relabel->resulttype),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup of type %u failed",
relabel->resulttype);
@@ -1560,6 +1573,7 @@ get_rule_expr(Node *node, deparse_context *context)
extval = pstrdup(NameStr(typeStruct->typname));
appendStringInfo(buf, ")::%s", quote_identifier(extval));
pfree(extval);
+ ReleaseSysCache(typetup);
}
break;
@@ -1616,14 +1630,14 @@ get_func_expr(Expr *expr, deparse_context *context)
/*
* Get the functions pg_proc tuple
*/
- proctup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(func->funcid),
- 0, 0, 0);
+ proctup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(func->funcid),
+ 0, 0, 0);
if (!HeapTupleIsValid(proctup))
elog(ERROR, "cache lookup for proc %u failed", func->funcid);
procStruct = (Form_pg_proc) GETSTRUCT(proctup);
- proname = pstrdup(NameStr(procStruct->proname));
+ proname = NameStr(procStruct->proname);
/*
* nullvalue() and nonnullvalue() should get turned into special
@@ -1636,6 +1650,7 @@ get_func_expr(Expr *expr, deparse_context *context)
appendStringInfoChar(buf, '(');
get_rule_expr((Node *) lfirst(expr->args), context);
appendStringInfo(buf, " ISNULL)");
+ ReleaseSysCache(proctup);
return;
}
if (strcmp(proname, "nonnullvalue") == 0)
@@ -1643,6 +1658,7 @@ get_func_expr(Expr *expr, deparse_context *context)
appendStringInfoChar(buf, '(');
get_rule_expr((Node *) lfirst(expr->args), context);
appendStringInfo(buf, " NOTNULL)");
+ ReleaseSysCache(proctup);
return;
}
}
@@ -1657,8 +1673,9 @@ get_func_expr(Expr *expr, deparse_context *context)
/*
* Strip off any RelabelType on the input, so we don't print
- * redundancies like x::bpchar::char(8). XXX Are there any cases
- * where this is a bad idea?
+ * redundancies like x::bpchar::char(8).
+ *
+ * XXX Are there any cases where this is a bad idea?
*/
if (IsA(arg, RelabelType))
arg = ((RelabelType *) arg)->arg;
@@ -1696,6 +1713,8 @@ get_func_expr(Expr *expr, deparse_context *context)
}
else
appendStringInfo(buf, "%s", quote_identifier(proname));
+
+ ReleaseSysCache(proctup);
return;
}
@@ -1711,6 +1730,8 @@ get_func_expr(Expr *expr, deparse_context *context)
get_rule_expr((Node *) lfirst(l), context);
}
appendStringInfoChar(buf, ')');
+
+ ReleaseSysCache(proctup);
}
@@ -1766,9 +1787,9 @@ get_const_expr(Const *constval, deparse_context *context)
char *extval;
char *valptr;
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(constval->consttype),
- 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(constval->consttype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup of type %u failed", constval->consttype);
@@ -1785,6 +1806,7 @@ get_const_expr(Const *constval, deparse_context *context)
extval = pstrdup(NameStr(typeStruct->typname));
appendStringInfo(buf, "NULL::%s", quote_identifier(extval));
pfree(extval);
+ ReleaseSysCache(typetup);
return;
}
@@ -1843,6 +1865,8 @@ get_const_expr(Const *constval, deparse_context *context)
pfree(extval);
break;
}
+
+ ReleaseSysCache(typetup);
}
@@ -2198,14 +2222,18 @@ get_relation_name(Oid relid)
{
HeapTuple classtup;
Form_pg_class classStruct;
+ char *result;
- classtup = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid), 0, 0, 0);
+ classtup = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
if (!HeapTupleIsValid(classtup))
elog(ERROR, "cache lookup of relation %u failed", relid);
classStruct = (Form_pg_class) GETSTRUCT(classtup);
- return pstrdup(NameStr(classStruct->relname));
+ result = pstrdup(NameStr(classStruct->relname));
+ ReleaseSysCache(classtup);
+ return result;
}
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 818bc6ab082..63e4d9b46d2 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.81 2000/11/10 09:38:21 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.82 2000/11/16 22:30:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -324,12 +324,15 @@ scalarltsel(PG_FUNCTION_ARGS)
* Get left and right datatypes of the operator so we know what
* type the constant is.
*/
- oprtuple = get_operator_tuple(opid);
+ oprtuple = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opid),
+ 0, 0, 0);
if (!HeapTupleIsValid(oprtuple))
elog(ERROR, "scalarltsel: no tuple for operator %u", opid);
ltype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprleft;
rtype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprright;
contype = (flag & SEL_RIGHT) ? rtype : ltype;
+ ReleaseSysCache(oprtuple);
/* Now get info and stats about the attribute */
getattproperties(relid, attno,
@@ -482,11 +485,14 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
* Get left and right datatypes of the operator so we know what
* type the attribute is.
*/
- oprtuple = get_operator_tuple(opid);
+ oprtuple = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opid),
+ 0, 0, 0);
if (!HeapTupleIsValid(oprtuple))
elog(ERROR, "patternsel: no tuple for operator %u", opid);
ltype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprleft;
rtype = ((Form_pg_operator) GETSTRUCT(oprtuple))->oprright;
+ ReleaseSysCache(oprtuple);
/* the right-hand const is type text for all supported operators */
Assert(rtype == TEXTOID);
@@ -1189,10 +1195,10 @@ getattproperties(Oid relid, AttrNumber attnum,
HeapTuple atp;
Form_pg_attribute att_tup;
- atp = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
+ atp = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum),
+ 0, 0);
if (!HeapTupleIsValid(atp))
elog(ERROR, "getattproperties: no attribute tuple %u %d",
relid, (int) attnum);
@@ -1202,6 +1208,8 @@ getattproperties(Oid relid, AttrNumber attnum,
*typlen = att_tup->attlen;
*typbyval = att_tup->attbyval;
*typmod = att_tup->atttypmod;
+
+ ReleaseSysCache(atp);
}
/*
@@ -1250,11 +1258,10 @@ getattstatistics(Oid relid,
* have at hand! (For example, we might have a '>' operator rather
* than the '<' operator that will appear in staop.)
*/
- tuple = SearchSysCacheTupleCopy(STATRELID,
- ObjectIdGetDatum(relid),
- Int16GetDatum((int16) attnum),
- 0,
- 0);
+ tuple = SearchSysCache(STATRELID,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum((int16) attnum),
+ 0, 0);
if (!HeapTupleIsValid(tuple))
{
/* no such stats entry */
@@ -1267,14 +1274,15 @@ getattstatistics(Oid relid,
*commonfrac = ((Form_pg_statistic) GETSTRUCT(tuple))->stacommonfrac;
/* Get the type input proc for the column datatype */
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "getattstatistics: Cache lookup failed for type %u",
typid);
fmgr_info(((Form_pg_type) GETSTRUCT(typeTuple))->typinput, &inputproc);
typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
+ ReleaseSysCache(typeTuple);
/*
* Values are variable-length fields, so cannot access as struct
@@ -1351,7 +1359,8 @@ getattstatistics(Oid relid,
pfree(strval);
}
}
- heap_freetuple(tuple);
+
+ ReleaseSysCache(tuple);
return true;
}
@@ -1966,16 +1975,11 @@ string_lessthan(const char *str1, const char *str2, Oid datatype)
static Oid
find_operator(const char *opname, Oid datatype)
{
- HeapTuple optup;
-
- optup = SearchSysCacheTuple(OPERNAME,
- PointerGetDatum(opname),
- ObjectIdGetDatum(datatype),
- ObjectIdGetDatum(datatype),
- CharGetDatum('b'));
- if (!HeapTupleIsValid(optup))
- return InvalidOid;
- return optup->t_data->t_oid;
+ return GetSysCacheOid(OPERNAME,
+ PointerGetDatum(opname),
+ ObjectIdGetDatum(datatype),
+ ObjectIdGetDatum(datatype),
+ CharGetDatum('b'));
}
/*
diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c
index 9a5f05134cd..6f64847dcab 100644
--- a/src/backend/utils/adt/sets.c
+++ b/src/backend/utils/adt/sets.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.33 2000/08/24 03:29:06 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.34 2000/11/16 22:30:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -77,9 +77,11 @@ SetDefine(char *querystr, char *typename)
*/
CommandCounterIncrement();
- tup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(setoid),
- 0, 0, 0);
+ procrel = heap_openr(ProcedureRelationName, RowExclusiveLock);
+
+ tup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(setoid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "SetDefine: unable to define set %s", querystr);
@@ -105,25 +107,15 @@ SetDefine(char *querystr, char *typename)
replNull[i] = ' ';
/* change the pg_proc tuple */
- procrel = heap_openr(ProcedureRelationName, RowExclusiveLock);
+ newtup = heap_modifytuple(tup,
+ procrel,
+ replValue,
+ replNull,
+ repl);
- tup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(setoid),
- 0, 0, 0);
- if (HeapTupleIsValid(tup))
- {
- newtup = heap_modifytuple(tup,
- procrel,
- replValue,
- replNull,
- repl);
+ heap_update(procrel, &newtup->t_self, newtup, NULL);
- heap_update(procrel, &tup->t_self, newtup, NULL);
-
- setoid = newtup->t_data->t_oid;
- }
- else
- elog(ERROR, "SetDefine: could not find new set oid tuple");
+ setoid = newtup->t_data->t_oid;
if (RelationGetForm(procrel)->relhasindex)
{
@@ -133,9 +125,13 @@ SetDefine(char *querystr, char *typename)
CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup);
CatalogCloseIndices(Num_pg_proc_indices, idescs);
}
- heap_close(procrel, RowExclusiveLock);
+ heap_freetuple(newtup);
}
+ ReleaseSysCache(tup);
+
+ heap_close(procrel, RowExclusiveLock);
+
return setoid;
}
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 39e05d0fb09..3d8e7d80ba8 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.71 2000/11/10 00:33:10 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.72 2000/11/16 22:30:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,7 +28,8 @@
#include "utils/catcache.h"
#include "utils/syscache.h"
-static void CatCacheRemoveCTup(CatCache *cache, Dlelem *e);
+
+static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct);
static Index CatalogCacheComputeHashIndex(CatCache *cache,
ScanKey cur_skey);
static Index CatalogCacheComputeTupleHashIndex(CatCache *cache,
@@ -388,28 +389,17 @@ CatalogCacheComputeTupleHashIndex(CatCache *cache,
* --------------------------------
*/
static void
-CatCacheRemoveCTup(CatCache *cache, Dlelem *elt)
+CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
{
- CatCTup *ct;
- CatCTup *other_ct;
- Dlelem *other_elt;
-
- if (!elt) /* probably-useless safety check */
- return;
-
- /* We need to zap both linked-list elements as well as the tuple */
+ Assert(ct->refcount == 0);
- ct = (CatCTup *) DLE_VAL(elt);
- other_elt = ct->ct_node;
- other_ct = (CatCTup *) DLE_VAL(other_elt);
+ /* delink from linked lists */
+ DLRemove(&ct->lrulist_elem);
+ DLRemove(&ct->cache_elem);
- heap_freetuple(ct->ct_tup);
-
- DLRemove(other_elt);
- DLFreeElem(other_elt);
- pfree(other_ct);
- DLRemove(elt);
- DLFreeElem(elt);
+ /* free associated tuple data */
+ if (ct->tuple.t_data != NULL)
+ pfree(ct->tuple.t_data);
pfree(ct);
--cache->cc_ntup;
@@ -425,13 +415,11 @@ CatCacheRemoveCTup(CatCache *cache, Dlelem *elt)
* --------------------------------
*/
void
-CatalogCacheIdInvalidate(int cacheId, /* XXX */
+CatalogCacheIdInvalidate(int cacheId,
Index hashIndex,
ItemPointer pointer)
{
CatCache *ccp;
- CatCTup *ct;
- Dlelem *elt;
/* ----------------
* sanity checks
@@ -442,54 +430,101 @@ CatalogCacheIdInvalidate(int cacheId, /* XXX */
CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
/* ----------------
- * inspect every cache that could contain the tuple
+ * inspect caches to find the proper cache
* ----------------
*/
for (ccp = Caches; ccp; ccp = ccp->cc_next)
{
+ Dlelem *elt,
+ *nextelt;
+
if (cacheId != ccp->id)
continue;
/* ----------------
* inspect the hash bucket until we find a match or exhaust
* ----------------
*/
- for (elt = DLGetHead(ccp->cc_cache[hashIndex]);
- elt;
- elt = DLGetSucc(elt))
+ for (elt = DLGetHead(&ccp->cc_cache[hashIndex]); elt; elt = nextelt)
{
- ct = (CatCTup *) DLE_VAL(elt);
- if (ItemPointerEquals(pointer, &ct->ct_tup->t_self))
- break;
- }
-
- /* ----------------
- * if we found a matching tuple, invalidate it.
- * ----------------
- */
+ CatCTup *ct = (CatCTup *) DLE_VAL(elt);
- if (elt)
- {
- CatCacheRemoveCTup(ccp, elt);
+ nextelt = DLGetSucc(elt);
- CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
+ if (ItemPointerEquals(pointer, &ct->tuple.t_self))
+ {
+ if (ct->refcount > 0)
+ ct->dead = true;
+ else
+ CatCacheRemoveCTup(ccp, ct);
+ CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
+ /* could be multiple matches, so keep looking! */
+ }
}
-
- if (cacheId != InvalidCatalogCacheId)
- break;
+ break; /* need only search this one cache */
}
}
/* ----------------------------------------------------------------
* public functions
*
+ * AtEOXact_CatCache
* ResetSystemCache
- * InitSysCache
- * SearchSysCache
+ * InitCatCache
+ * SearchCatCache
+ * ReleaseCatCache
* RelationInvalidateCatalogCacheTuple
* ----------------------------------------------------------------
*/
+
+
+/* --------------------------------
+ * AtEOXact_CatCache
+ *
+ * Clean up catcaches at end of transaction (either commit or abort)
+ *
+ * We scan the caches to reset refcounts to zero. This is of course
+ * necessary in the abort case, since elog() may have interrupted routines.
+ * In the commit case, any nonzero counts indicate failure to call
+ * ReleaseSysCache, so we put out a notice for debugging purposes.
+ * --------------------------------
+ */
+void
+AtEOXact_CatCache(bool isCommit)
+{
+ CatCache *cache;
+
+ for (cache = Caches; cache; cache = cache->cc_next)
+ {
+ Dlelem *elt,
+ *nextelt;
+
+ for (elt = DLGetHead(&cache->cc_lrulist); elt; elt = nextelt)
+ {
+ CatCTup *ct = (CatCTup *) DLE_VAL(elt);
+
+ nextelt = DLGetSucc(elt);
+
+ if (ct->refcount != 0)
+ {
+ if (isCommit)
+ elog(NOTICE, "Cache reference leak: cache %s (%d), tuple %u has count %d",
+ cache->cc_relname, cache->id,
+ ct->tuple.t_data->t_oid,
+ ct->refcount);
+ ct->refcount = 0;
+ }
+
+ /* Clean up any now-deletable dead entries */
+ if (ct->dead)
+ CatCacheRemoveCTup(cache, ct);
+ }
+ }
+}
+
/* --------------------------------
* ResetSystemCache
+ *
+ * Reset caches when a shared cache inval event forces it
* --------------------------------
*/
void
@@ -503,34 +538,25 @@ ResetSystemCache(void)
* here we purge the contents of all the caches
*
* for each system cache
- * for each hash bucket
- * for each tuple in hash bucket
- * remove the tuple
+ * for each tuple
+ * remove the tuple, or at least mark it dead
* ----------------
*/
- for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next)
+ for (cache = Caches; cache; cache = cache->cc_next)
{
- int hash;
+ Dlelem *elt,
+ *nextelt;
- for (hash = 0; hash < NCCBUCK; hash += 1)
+ for (elt = DLGetHead(&cache->cc_lrulist); elt; elt = nextelt)
{
- Dlelem *elt,
- *nextelt;
+ CatCTup *ct = (CatCTup *) DLE_VAL(elt);
- for (elt = DLGetHead(cache->cc_cache[hash]); elt; elt = nextelt)
- {
- nextelt = DLGetSucc(elt);
- CatCacheRemoveCTup(cache, elt);
- }
- }
+ nextelt = DLGetSucc(elt);
- /* double-check that ntup is now zero */
- if (cache->cc_ntup != 0)
- {
- elog(NOTICE,
- "ResetSystemCache: cache %d has cc_ntup = %d, should be 0",
- cache->id, cache->cc_ntup);
- cache->cc_ntup = 0;
+ if (ct->refcount > 0)
+ ct->dead = true;
+ else
+ CatCacheRemoveCTup(cache, ct);
}
}
@@ -572,7 +598,7 @@ SystemCacheRelationFlushed(Oid relId)
}
/* --------------------------------
- * InitSysCache
+ * InitCatCache
*
* This allocates and initializes a cache for a system catalog relation.
* Actually, the cache is only partially initialized to avoid opening the
@@ -581,18 +607,18 @@ SystemCacheRelationFlushed(Oid relId)
* --------------------------------
*/
#ifdef CACHEDEBUG
-#define InitSysCache_DEBUG1 \
+#define InitCatCache_DEBUG1 \
do { \
- elog(DEBUG, "InitSysCache: rel=%s id=%d nkeys=%d size=%d\n", \
+ elog(DEBUG, "InitCatCache: rel=%s id=%d nkeys=%d size=%d\n", \
cp->cc_relname, cp->id, cp->cc_nkeys, cp->cc_size); \
} while(0)
#else
-#define InitSysCache_DEBUG1
+#define InitCatCache_DEBUG1
#endif
CatCache *
-InitSysCache(int id,
+InitCatCache(int id,
char *relname,
char *indname,
int nkeys,
@@ -624,25 +650,9 @@ InitSysCache(int id,
* and the LRU tuple list
* ----------------
*/
- {
-
- /*
- * We can only do this optimization because the number of hash
- * buckets never changes. Without it, we call palloc() too much.
- * We could move this to dllist.c, but the way we do this is not
- * dynamic/portable, so why allow other routines to use it.
- */
- Dllist *cache_begin = palloc((NCCBUCK + 1) * sizeof(Dllist));
-
- for (i = 0; i <= NCCBUCK; ++i)
- {
- cp->cc_cache[i] = &cache_begin[i];
- cp->cc_cache[i]->dll_head = 0;
- cp->cc_cache[i]->dll_tail = 0;
- }
- }
-
- cp->cc_lrulist = DLNewList();
+ DLInitList(&cp->cc_lrulist);
+ for (i = 0; i < NCCBUCK; ++i)
+ DLInitList(&cp->cc_cache[i]);
/* ----------------
* Caches is the pointer to the head of the list of all the
@@ -673,7 +683,7 @@ InitSysCache(int id,
* information, if appropriate.
* ----------------
*/
- InitSysCache_DEBUG1;
+ InitCatCache_DEBUG1;
/* ----------------
* back to the old context before we return...
@@ -742,14 +752,14 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
}
/* --------------------------------
- * SearchSysCache
+ * SearchCatCache
*
* This call searches a system cache for a tuple, opening the relation
* if necessary (the first access to a particular cache).
* --------------------------------
*/
HeapTuple
-SearchSysCache(CatCache *cache,
+SearchCatCache(CatCache *cache,
Datum v1,
Datum v2,
Datum v3,
@@ -757,10 +767,8 @@ SearchSysCache(CatCache *cache,
{
ScanKeyData cur_skey[4];
Index hash;
- CatCTup *ct = NULL;
- CatCTup *nct;
- CatCTup *nct2;
Dlelem *elt;
+ CatCTup *ct;
HeapTuple ntp;
Relation relation;
MemoryContext oldcxt;
@@ -792,48 +800,50 @@ SearchSysCache(CatCache *cache,
* scan the hash bucket until we find a match or exhaust our tuples
* ----------------
*/
- for (elt = DLGetHead(cache->cc_cache[hash]);
+ for (elt = DLGetHead(&cache->cc_cache[hash]);
elt;
elt = DLGetSucc(elt))
{
bool res;
ct = (CatCTup *) DLE_VAL(elt);
+
+ if (ct->dead)
+ continue; /* ignore dead entries */
+
/* ----------------
* see if the cached tuple matches our key.
* (should we be worried about time ranges? -cim 10/2/90)
* ----------------
*/
- HeapKeyTest(ct->ct_tup,
+ HeapKeyTest(&ct->tuple,
cache->cc_tupdesc,
cache->cc_nkeys,
cur_skey,
res);
- if (res)
- break;
- }
+ if (! res)
+ continue;
- /* ----------------
- * if we found a tuple in the cache, move it to the top of the
- * lru list, and return it. We also move it to the front of the
- * list for its hashbucket, in order to speed subsequent searches.
- * (The most frequently accessed elements in any hashbucket will
- * tend to be near the front of the hashbucket's list.)
- * ----------------
- */
- if (elt)
- {
- Dlelem *old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
+ /* ----------------
+ * we found a tuple in the cache: bump its refcount, move it to
+ * the front of the LRU list, and return it. We also move it
+ * to the front of the list for its hashbucket, in order to speed
+ * subsequent searches. (The most frequently accessed elements
+ * in any hashbucket will tend to be near the front of the
+ * hashbucket's list.)
+ * ----------------
+ */
+ ct->refcount++;
- DLMoveToFront(old_lru_elt);
- DLMoveToFront(elt);
+ DLMoveToFront(&ct->lrulist_elem);
+ DLMoveToFront(&ct->cache_elem);
#ifdef CACHEDEBUG
- CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d",
+ CACHE3_elog(DEBUG, "SearchCatCache(%s): found in bucket %d",
cache->cc_relname, hash);
#endif /* CACHEDEBUG */
- return ct->ct_tup;
+ return &ct->tuple;
}
/* ----------------
@@ -864,7 +874,7 @@ SearchSysCache(CatCache *cache,
* if it's safe to do so, use the index. Else do a heap scan.
* ----------------
*/
- ntp = NULL;
+ ct = NULL;
if ((RelationGetForm(relation))->relhasindex &&
!IsIgnoringSystemIndexes() &&
@@ -876,7 +886,7 @@ SearchSysCache(CatCache *cache,
HeapTupleData tuple;
Buffer buffer;
- CACHE2_elog(DEBUG, "SearchSysCache(%s): performing index scan",
+ CACHE2_elog(DEBUG, "SearchCatCache(%s): performing index scan",
cache->cc_relname);
idesc = index_openr(cache->cc_indname);
@@ -892,7 +902,8 @@ SearchSysCache(CatCache *cache,
{
/* Copy tuple into our context */
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
- ntp = heap_copytuple(&tuple);
+ ct = (CatCTup *) palloc(sizeof(CatCTup));
+ heap_copytuple_with_tuple(&tuple, &ct->tuple);
MemoryContextSwitchTo(oldcxt);
ReleaseBuffer(buffer);
break;
@@ -906,7 +917,7 @@ SearchSysCache(CatCache *cache,
HeapScanDesc sd;
int i;
- CACHE2_elog(DEBUG, "SearchSysCache(%s): performing heap scan",
+ CACHE2_elog(DEBUG, "SearchCatCache(%s): performing heap scan",
cache->cc_relname);
/*
@@ -925,7 +936,8 @@ SearchSysCache(CatCache *cache,
{
/* Copy tuple into our context */
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
- ntp = heap_copytuple(ntp);
+ ct = (CatCTup *) palloc(sizeof(CatCTup));
+ heap_copytuple_with_tuple(ntp, &ct->tuple);
MemoryContextSwitchTo(oldcxt);
/* We should not free the result of heap_getnext... */
}
@@ -934,77 +946,102 @@ SearchSysCache(CatCache *cache,
}
/* ----------------
- * scan is complete. if tup is valid, we can add it to the cache.
- * note we have already copied it into the cache memory context.
+ * close the relation
* ----------------
*/
- if (HeapTupleIsValid(ntp))
- {
- /* ----------------
- * allocate a new cache tuple holder, store the pointer
- * to the heap tuple there and initialize the list pointers.
- * ----------------
- */
- Dlelem *lru_elt;
-
- CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
+ heap_close(relation, AccessShareLock);
- oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
+ /* ----------------
+ * scan is complete. if tup was found, we can add it to the cache.
+ * ----------------
+ */
+ if (ct == NULL)
+ return NULL;
- /*
- * this is a little cumbersome here because we want the Dlelem's
- * in both doubly linked lists to point to one another. That makes
- * it easier to remove something from both the cache bucket and
- * the lru list at the same time
- */
- nct = (CatCTup *) palloc(sizeof(CatCTup));
- nct->ct_tup = ntp;
- elt = DLNewElem(nct);
- nct2 = (CatCTup *) palloc(sizeof(CatCTup));
- nct2->ct_tup = ntp;
- lru_elt = DLNewElem(nct2);
- nct2->ct_node = elt;
- nct->ct_node = lru_elt;
+ /* ----------------
+ * Finish initializing the CatCTup header, and add it to the
+ * linked lists.
+ * ----------------
+ */
+ CACHE1_elog(DEBUG, "SearchCatCache: found tuple");
- DLAddHead(cache->cc_lrulist, lru_elt);
- DLAddHead(cache->cc_cache[hash], elt);
+ ct->ct_magic = CT_MAGIC;
+ DLInitElem(&ct->lrulist_elem, (void *) ct);
+ DLInitElem(&ct->cache_elem, (void *) ct);
+ ct->refcount = 1; /* count this first reference */
+ ct->dead = false;
- MemoryContextSwitchTo(oldcxt);
+ DLAddHead(&cache->cc_lrulist, &ct->lrulist_elem);
+ DLAddHead(&cache->cc_cache[hash], &ct->cache_elem);
- /* ----------------
- * If we've exceeded the desired size of this cache,
- * throw away the least recently used entry.
- * ----------------
- */
- if (++cache->cc_ntup > cache->cc_maxtup)
+ /* ----------------
+ * If we've exceeded the desired size of this cache,
+ * try to throw away the least recently used entry.
+ * ----------------
+ */
+ if (++cache->cc_ntup > cache->cc_maxtup)
+ {
+ for (elt = DLGetTail(&cache->cc_lrulist);
+ elt;
+ elt = DLGetPred(elt))
{
- CatCTup *ct;
+ CatCTup *oldct = (CatCTup *) DLE_VAL(elt);
- elt = DLGetTail(cache->cc_lrulist);
- ct = (CatCTup *) DLE_VAL(elt);
-
- if (ct != nct) /* shouldn't be possible, but be safe... */
+ if (oldct->refcount == 0)
{
- CACHE2_elog(DEBUG, "SearchSysCache(%s): Overflow, LRU removal",
+ CACHE2_elog(DEBUG, "SearchCatCache(%s): Overflow, LRU removal",
cache->cc_relname);
-
- CatCacheRemoveCTup(cache, elt);
+ CatCacheRemoveCTup(cache, oldct);
+ break;
}
}
-
- CACHE4_elog(DEBUG, "SearchSysCache(%s): Contains %d/%d tuples",
- cache->cc_relname, cache->cc_ntup, cache->cc_maxtup);
- CACHE3_elog(DEBUG, "SearchSysCache(%s): put in bucket %d",
- cache->cc_relname, hash);
}
- /* ----------------
- * close the relation and return the tuple we found (or NULL)
- * ----------------
- */
- heap_close(relation, AccessShareLock);
+ CACHE4_elog(DEBUG, "SearchCatCache(%s): Contains %d/%d tuples",
+ cache->cc_relname, cache->cc_ntup, cache->cc_maxtup);
+ CACHE3_elog(DEBUG, "SearchCatCache(%s): put in bucket %d",
+ cache->cc_relname, hash);
+
+ return &ct->tuple;
+}
- return ntp;
+/* --------------------------------
+ * ReleaseCatCache()
+ *
+ * Decrement the reference count of a catcache entry (releasing the
+ * hold grabbed by a successful SearchCatCache).
+ *
+ * NOTE: if compiled with -DCATCACHE_FORCE_RELEASE then catcache entries
+ * will be freed as soon as their refcount goes to zero. In combination
+ * with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
+ * to catch references to already-released catcache entries.
+ * --------------------------------
+ */
+void
+ReleaseCatCache(HeapTuple tuple)
+{
+ CatCTup *ct = (CatCTup *) (((char *) tuple) -
+ offsetof(CatCTup, tuple));
+
+ /* Safety checks to ensure we were handed a cache entry */
+ Assert(ct->ct_magic == CT_MAGIC);
+ Assert(ct->refcount > 0);
+
+ ct->refcount--;
+
+ if (ct->refcount == 0
+#ifndef CATCACHE_FORCE_RELEASE
+ && ct->dead
+#endif
+ )
+ {
+ /* We can find the associated cache using the dllist pointers */
+ Dllist *lru = DLGetListHdr(&ct->lrulist_elem);
+ CatCache *cache = (CatCache *) (((char *) lru) -
+ offsetof(CatCache, cc_lrulist));
+
+ CatCacheRemoveCTup(cache, ct);
+ }
}
/* --------------------------------
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index b9bd9f8b9e9..e07445837a5 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.46 2000/10/05 19:48:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.47 2000/11/16 22:30:33 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@@ -32,14 +32,11 @@
bool
op_class(Oid opno, Oid opclass, Oid amopid)
{
- if (HeapTupleIsValid(SearchSysCacheTuple(AMOPOPID,
- ObjectIdGetDatum(opclass),
- ObjectIdGetDatum(opno),
- ObjectIdGetDatum(amopid),
- 0)))
- return true;
- else
- return false;
+ return SearchSysCacheExists(AMOPOPID,
+ ObjectIdGetDatum(opclass),
+ ObjectIdGetDatum(opno),
+ ObjectIdGetDatum(amopid),
+ 0);
}
/* ---------- ATTRIBUTE CACHES ---------- */
@@ -49,21 +46,26 @@ op_class(Oid opno, Oid opclass, Oid amopid)
*
* Given the relation id and the attribute number,
* return the "attname" field from the attribute relation.
+ *
+ * Note: returns a palloc'd copy of the string, or NULL if no such operator.
*/
char *
get_attname(Oid relid, AttrNumber attnum)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
+ tp = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum),
+ 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
+ char *result;
- return pstrdup(NameStr(att_tup->attname));
+ result = pstrdup(NameStr(att_tup->attname));
+ ReleaseSysCache(tp);
+ return result;
}
else
return NULL;
@@ -80,15 +82,18 @@ get_attnum(Oid relid, char *attname)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0, 0);
+ tp = SearchSysCache(ATTNAME,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(attname),
+ 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
+ AttrNumber result;
- return att_tup->attnum;
+ result = att_tup->attnum;
+ ReleaseSysCache(tp);
+ return result;
}
else
return InvalidAttrNumber;
@@ -105,15 +110,18 @@ get_atttype(Oid relid, AttrNumber attnum)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
+ tp = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum),
+ 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
+ Oid result;
- return att_tup->atttypid;
+ result = att_tup->atttypid;
+ ReleaseSysCache(tp);
+ return result;
}
else
return InvalidOid;
@@ -128,15 +136,18 @@ get_attisset(Oid relid, char *attname)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0, 0);
+ tp = SearchSysCache(ATTNAME,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(attname),
+ 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
+ bool result;
- return att_tup->attisset;
+ result = att_tup->attisset;
+ ReleaseSysCache(tp);
+ return result;
}
else
return false;
@@ -153,15 +164,18 @@ get_atttypmod(Oid relid, AttrNumber attnum)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
+ tp = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum),
+ 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
+ int32 result;
- return att_tup->atttypmod;
+ result = att_tup->atttypmod;
+ ReleaseSysCache(tp);
+ return result;
}
else
return -1;
@@ -185,12 +199,13 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
HeapTuple atp;
Form_pg_attribute att_tup;
double dispersion;
+ Oid atttypid;
int32 ntuples;
- atp = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0, 0);
+ atp = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum),
+ 0, 0);
if (!HeapTupleIsValid(atp))
{
/* this should not happen */
@@ -198,9 +213,14 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
relid, attnum);
return min_estimate;
}
+
att_tup = (Form_pg_attribute) GETSTRUCT(atp);
dispersion = att_tup->attdispersion;
+ atttypid = att_tup->atttypid;
+
+ ReleaseSysCache(atp);
+
if (dispersion > 0.0)
return dispersion; /* we have a specific estimate from VACUUM */
@@ -211,7 +231,7 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
*
* Are there any other cases we should wire in special estimates for?
*/
- if (att_tup->atttypid == BOOLOID)
+ if (atttypid == BOOLOID)
return 0.5;
/*
@@ -219,9 +239,9 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
* 1/numtuples). Either way, we need the relation size.
*/
- atp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
+ atp = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
if (!HeapTupleIsValid(atp))
{
/* this should not happen */
@@ -231,6 +251,8 @@ get_attdispersion(Oid relid, AttrNumber attnum, double min_estimate)
ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
+ ReleaseSysCache(atp);
+
if (ntuples == 0)
return min_estimate; /* no data available */
@@ -277,14 +299,17 @@ get_opcode(Oid opno)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
+ RegProcedure result;
- return optup->oprcode;
+ result = optup->oprcode;
+ ReleaseSysCache(tp);
+ return result;
}
else
return (RegProcedure) InvalidOid;
@@ -301,14 +326,17 @@ get_opname(Oid opno)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
+ char *result;
- return pstrdup(NameStr(optup->oprname));
+ result = pstrdup(NameStr(optup->oprname));
+ ReleaseSysCache(tp);
+ return result;
}
else
return NULL;
@@ -324,10 +352,11 @@ bool
op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
{
HeapTuple tp;
+ bool result = false;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
@@ -339,10 +368,11 @@ op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
{
*leftOp = optup->oprlsortop;
*rightOp = optup->oprrsortop;
- return true;
+ result = true;
}
+ ReleaseSysCache(tp);
}
- return false;
+ return result;
}
/*
@@ -355,10 +385,11 @@ Oid
op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
{
HeapTuple tp;
+ Oid result = InvalidOid;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
@@ -366,9 +397,10 @@ op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
if (optup->oprcanhash &&
optup->oprleft == ltype &&
optup->oprright == rtype)
- return opno;
+ result = opno;
+ ReleaseSysCache(tp);
}
- return InvalidOid;
+ return result;
}
/*
@@ -387,14 +419,6 @@ op_iscachable(Oid opno)
return func_iscachable((Oid) funcid);
}
-HeapTuple
-get_operator_tuple(Oid opno)
-{
- return SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
-}
-
/*
* get_commutator
*
@@ -405,14 +429,17 @@ get_commutator(Oid opno)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
+ Oid result;
- return optup->oprcom;
+ result = optup->oprcom;
+ ReleaseSysCache(tp);
+ return result;
}
else
return InvalidOid;
@@ -428,14 +455,17 @@ get_negator(Oid opno)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
+ Oid result;
- return optup->oprnegate;
+ result = optup->oprnegate;
+ ReleaseSysCache(tp);
+ return result;
}
else
return InvalidOid;
@@ -451,14 +481,17 @@ get_oprrest(Oid opno)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
+ RegProcedure result;
- return optup->oprrest;
+ result = optup->oprrest;
+ ReleaseSysCache(tp);
+ return result;
}
else
return (RegProcedure) InvalidOid;
@@ -474,14 +507,17 @@ get_oprjoin(Oid opno)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(OPEROID,
- ObjectIdGetDatum(opno),
- 0, 0, 0);
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
+ RegProcedure result;
- return optup->oprjoin;
+ result = optup->oprjoin;
+ ReleaseSysCache(tp);
+ return result;
}
else
return (RegProcedure) InvalidOid;
@@ -496,15 +532,18 @@ get_oprjoin(Oid opno)
Oid
get_func_rettype(Oid funcid)
{
- HeapTuple func_tuple;
+ HeapTuple tp;
+ Oid result;
- func_tuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(funcid),
- 0, 0, 0);
- if (!HeapTupleIsValid(func_tuple))
+ tp = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(funcid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
elog(ERROR, "Function OID %u does not exist", funcid);
- return ((Form_pg_proc) GETSTRUCT(func_tuple))->prorettype;
+ result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
+ ReleaseSysCache(tp);
+ return result;
}
/*
@@ -514,15 +553,18 @@ get_func_rettype(Oid funcid)
bool
func_iscachable(Oid funcid)
{
- HeapTuple func_tuple;
+ HeapTuple tp;
+ bool result;
- func_tuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(funcid),
- 0, 0, 0);
- if (!HeapTupleIsValid(func_tuple))
+ tp = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(funcid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
elog(ERROR, "Function OID %u does not exist", funcid);
- return ((Form_pg_proc) GETSTRUCT(func_tuple))->proiscachable;
+ result = ((Form_pg_proc) GETSTRUCT(tp))->proiscachable;
+ ReleaseSysCache(tp);
+ return result;
}
/* ---------- RELATION CACHE ---------- */
@@ -538,14 +580,17 @@ get_relnatts(Oid relid)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
+ tp = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+ int result;
- return reltup->relnatts;
+ result = reltup->relnatts;
+ ReleaseSysCache(tp);
+ return result;
}
else
return InvalidAttrNumber;
@@ -556,20 +601,25 @@ get_relnatts(Oid relid)
* get_rel_name
*
* Returns the name of a given relation.
+ *
+ * Note: returns a palloc'd copy of the string, or NULL if no such operator.
*/
char *
get_rel_name(Oid relid)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid),
- 0, 0, 0);
+ tp = SearchSysCache(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+ char *result;
- return pstrdup(NameStr(reltup->relname));
+ result = pstrdup(NameStr(reltup->relname));
+ ReleaseSysCache(tp);
+ return result;
}
else
return NULL;
@@ -587,14 +637,17 @@ get_typlen(Oid typid)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
+ tp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
+ int16 result;
- return typtup->typlen;
+ result = typtup->typlen;
+ ReleaseSysCache(tp);
+ return result;
}
else
return 0;
@@ -611,33 +664,66 @@ get_typbyval(Oid typid)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
+ tp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
+ bool result;
- return typtup->typbyval;
+ result = typtup->typbyval;
+ ReleaseSysCache(tp);
+ return result;
}
else
return false;
}
+/*
+ * get_typlenbyval
+ *
+ * A two-fer: given the type OID, return both typlen and typbyval.
+ *
+ * Since both pieces of info are needed to know how to copy a Datum,
+ * many places need both. Might as well get them with one cache lookup
+ * instead of two. Also, this routine raises an error instead of
+ * returning a bogus value when given a bad type OID.
+ */
+void
+get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
+{
+ HeapTuple tp;
+ Form_pg_type typtup;
+
+ tp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for type %u", typid);
+ typtup = (Form_pg_type) GETSTRUCT(tp);
+ *typlen = typtup->typlen;
+ *typbyval = typtup->typbyval;
+ ReleaseSysCache(tp);
+}
+
#ifdef NOT_USED
char
get_typalign(Oid typid)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
+ tp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
+ char result;
- return typtup->typalign;
+ result = typtup->typalign;
+ ReleaseSysCache(tp);
+ return result;
}
else
return 'i';
@@ -666,9 +752,9 @@ get_typdefault(Oid typid)
bool typByVal;
Datum returnValue;
- typeTuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
+ typeTuple = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
@@ -679,13 +765,17 @@ get_typdefault(Oid typid)
* First, see if there is a non-null typdefault field (usually there
* isn't)
*/
- typDefault = (struct varlena *) SysCacheGetAttr(TYPEOID,
- typeTuple,
- Anum_pg_type_typdefault,
- &isNull);
+ typDefault = (struct varlena *)
+ DatumGetPointer(SysCacheGetAttr(TYPEOID,
+ typeTuple,
+ Anum_pg_type_typdefault,
+ &isNull));
if (isNull)
+ {
+ ReleaseSysCache(typeTuple);
return PointerGetDatum(NULL);
+ }
/*
* Otherwise, extract/copy the value.
@@ -748,6 +838,8 @@ get_typdefault(Oid typid)
}
}
+ ReleaseSysCache(typeTuple);
+
return returnValue;
}
@@ -764,14 +856,17 @@ get_typtype(Oid typid)
{
HeapTuple tp;
- tp = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(typid),
- 0, 0, 0);
+ tp = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
+ char result;
- return typtup->typtype;
+ result = typtup->typtype;
+ ReleaseSysCache(tp);
+ return result;
}
else
return '\0';
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 7f35f192089..bb9a55b869a 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.56 2000/11/10 00:33:10 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.57 2000/11/16 22:30:33 tgl Exp $
*
* NOTES
* These routines allow the parser/planner/executor to perform
@@ -343,7 +343,7 @@ static struct cachedesc cacheinfo[] = {
};
static CatCache *SysCache[lengthof(cacheinfo)];
-static int32 SysCacheSize = lengthof(cacheinfo);
+static int SysCacheSize = lengthof(cacheinfo);
static bool CacheInitialized = false;
@@ -355,98 +355,67 @@ IsCacheInitialized(void)
/*
- * zerocaches
+ * InitCatalogCache - initialize the caches
*
- * Make sure the SysCache structure is zero'd.
+ * Note that no database access is done here; we only allocate memory
+ * and initialize the cache structure. Interrogation of the database
+ * to complete initialization of a cache happens only upon first use
+ * of that cache.
*/
void
-zerocaches()
+InitCatalogCache(void)
{
- MemSet((char *) SysCache, 0, SysCacheSize * sizeof(CatCache *));
-}
+ int cacheId;
+ Assert(!CacheInitialized);
-/*
- * InitCatalogCache - initialize the caches
- */
-void
-InitCatalogCache()
-{
- int cacheId; /* XXX type */
+ MemSet((char *) SysCache, 0, sizeof(SysCache));
- if (!AMI_OVERRIDE)
+ for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
{
- for (cacheId = 0; cacheId < SysCacheSize; cacheId += 1)
- {
- Assert(!PointerIsValid(SysCache[cacheId]));
-
- SysCache[cacheId] = InitSysCache(cacheId,
- cacheinfo[cacheId].name,
- cacheinfo[cacheId].indname,
- cacheinfo[cacheId].nkeys,
- cacheinfo[cacheId].key);
- if (!PointerIsValid(SysCache[cacheId]))
- {
- elog(ERROR,
- "InitCatalogCache: Can't init cache %s (%d)",
- cacheinfo[cacheId].name,
- cacheId);
- }
-
- }
+ SysCache[cacheId] = InitCatCache(cacheId,
+ cacheinfo[cacheId].name,
+ cacheinfo[cacheId].indname,
+ cacheinfo[cacheId].nkeys,
+ cacheinfo[cacheId].key);
+ if (!PointerIsValid(SysCache[cacheId]))
+ elog(ERROR, "InitCatalogCache: Can't init cache %s (%d)",
+ cacheinfo[cacheId].name, cacheId);
}
CacheInitialized = true;
}
/*
- * SearchSysCacheTuple
+ * SearchSysCache
*
- * A layer on top of SearchSysCache that does the initialization and
+ * A layer on top of SearchCatCache that does the initialization and
* key-setting for you.
*
* Returns the cache copy of the tuple if one is found, NULL if not.
- * The tuple is the 'cache' copy.
- *
- * CAUTION: The tuple that is returned must NOT be freed by the caller!
+ * The tuple is the 'cache' copy and must NOT be modified!
*
- * CAUTION: The returned tuple may be flushed from the cache during
- * subsequent cache lookup operations, or by shared cache invalidation.
- * Callers should not expect the pointer to remain valid for long.
+ * When the caller is done using the tuple, call ReleaseSysCache()
+ * to release the reference count grabbed by SearchSysCache(). If this
+ * is not done, the tuple will remain locked in cache until end of
+ * transaction, which is tolerable but not desirable.
*
- * XXX we ought to have some kind of referencecount mechanism for
- * cache entries, to ensure entries aren't deleted while in use.
+ * CAUTION: The tuple that is returned must NOT be freed by the caller!
*/
HeapTuple
-SearchSysCacheTuple(int cacheId,/* cache selection code */
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+SearchSysCache(int cacheId,
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- HeapTuple tp;
-
if (cacheId < 0 || cacheId >= SysCacheSize)
{
- elog(ERROR, "SearchSysCacheTuple: Bad cache id %d", cacheId);
+ elog(ERROR, "SearchSysCache: Bad cache id %d", cacheId);
return (HeapTuple) NULL;
}
- Assert(AMI_OVERRIDE || PointerIsValid(SysCache[cacheId]));
-
- if (!PointerIsValid(SysCache[cacheId]))
- {
- SysCache[cacheId] = InitSysCache(cacheId,
- cacheinfo[cacheId].name,
- cacheinfo[cacheId].indname,
- cacheinfo[cacheId].nkeys,
- cacheinfo[cacheId].key);
- if (!PointerIsValid(SysCache[cacheId]))
- elog(ERROR,
- "InitCatalogCache: Can't init cache %s(%d)",
- cacheinfo[cacheId].name,
- cacheId);
- }
+ Assert(PointerIsValid(SysCache[cacheId]));
/*
* If someone tries to look up a relname, translate temp relation
@@ -464,51 +433,75 @@ SearchSysCacheTuple(int cacheId,/* cache selection code */
key1 = CStringGetDatum(nontemp_relname);
}
- tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4);
- if (!HeapTupleIsValid(tp))
- {
-#ifdef CACHEDEBUG
- elog(DEBUG,
- "SearchSysCacheTuple: Search %s(%d) %d %d %d %d failed",
- cacheinfo[cacheId].name,
- cacheId, key1, key2, key3, key4);
-#endif
- return (HeapTuple) NULL;
- }
- return tp;
+ return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
}
+/*
+ * ReleaseSysCache
+ * Release previously grabbed reference count on a tuple
+ */
+void
+ReleaseSysCache(HeapTuple tuple)
+{
+ ReleaseCatCache(tuple);
+}
/*
- * SearchSysCacheTupleCopy
+ * SearchSysCacheCopy
*
- * This is like SearchSysCacheTuple, except it returns a palloc'd copy of
- * the tuple. The caller should heap_freetuple() the returned copy when
- * done with it. This routine should be used when the caller intends to
- * continue to access the tuple for more than a very short period of time.
+ * A convenience routine that does SearchSysCache and (if successful)
+ * returns a modifiable copy of the syscache entry. The original
+ * syscache entry is released before returning. The caller should
+ * heap_freetuple() the result when done with it.
*/
HeapTuple
-SearchSysCacheTupleCopy(int cacheId, /* cache selection code */
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+SearchSysCacheCopy(int cacheId,
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- HeapTuple cachetup;
-
- cachetup = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
- if (PointerIsValid(cachetup))
- return heap_copytuple(cachetup);
- else
- return cachetup; /* NULL */
+ HeapTuple tuple,
+ newtuple;
+
+ tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
+ if (!HeapTupleIsValid(tuple))
+ return tuple;
+ newtuple = heap_copytuple(tuple);
+ ReleaseSysCache(tuple);
+ return newtuple;
}
+/*
+ * GetSysCacheOid
+ *
+ * A convenience routine that does SearchSysCache and returns the OID
+ * of the found tuple, or InvalidOid if no tuple could be found.
+ * No lock is retained on the syscache entry.
+ */
+Oid
+GetSysCacheOid(int cacheId,
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
+{
+ HeapTuple tuple;
+ Oid result;
+
+ tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
+ if (!HeapTupleIsValid(tuple))
+ return InvalidOid;
+ result = tuple->t_data->t_oid;
+ ReleaseSysCache(tuple);
+ return result;
+}
/*
* SysCacheGetAttr
*
- * Given a tuple previously fetched by SearchSysCacheTuple() or
- * SearchSysCacheTupleCopy(), extract a specific attribute.
+ * Given a tuple previously fetched by SearchSysCache(),
+ * extract a specific attribute.
*
* This is equivalent to using heap_getattr() on a tuple fetched
* from a non-cached relation. Usually, this is only used for attributes
diff --git a/src/backend/utils/cache/temprel.c b/src/backend/utils/cache/temprel.c
index 31591663cee..0134b47a0f9 100644
--- a/src/backend/utils/cache/temprel.c
+++ b/src/backend/utils/cache/temprel.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.30 2000/11/08 22:10:01 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.31 2000/11/16 22:30:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,7 +34,6 @@
#include "catalog/heap.h"
#include "catalog/index.h"
#include "miscadmin.h"
-#include "utils/catcache.h"
#include "utils/temprel.h"
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 3913dddeec2..2dfddebd0a8 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.44 2000/07/05 23:11:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.45 2000/11/16 22:30:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -59,9 +59,9 @@ fmgr_dynamic(Oid functionId)
PGFunction user_fn;
bool isnull;
- procedureTuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(functionId),
- 0, 0, 0);
+ procedureTuple = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(functionId),
+ 0, 0, 0);
if (!HeapTupleIsValid(procedureTuple))
elog(ERROR, "fmgr_dynamic: function %u: cache lookup failed",
functionId);
@@ -88,6 +88,8 @@ fmgr_dynamic(Oid functionId)
pfree(prosrcstring);
pfree(probinstring);
+ ReleaseSysCache(procedureTuple);
+
return user_fn;
}
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index c7fbf251f9d..5287615eea0 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.46 2000/08/24 03:29:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.47 2000/11/16 22:30:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -134,9 +134,9 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
}
/* Otherwise we need the pg_proc entry */
- procedureTuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(functionId),
- 0, 0, 0);
+ procedureTuple = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(functionId),
+ 0, 0, 0);
if (!HeapTupleIsValid(procedureTuple))
elog(ERROR, "fmgr_info: function %u: cache lookup failed",
functionId);
@@ -149,6 +149,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
if (!procedureStruct->proistrusted)
{
finfo->fn_addr = fmgr_untrusted;
+ ReleaseSysCache(procedureTuple);
return;
}
@@ -202,14 +203,12 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
/*
* Might be a created procedural language; try to look it up.
*/
- languageTuple = SearchSysCacheTuple(LANGOID,
- ObjectIdGetDatum(language),
- 0, 0, 0);
+ languageTuple = SearchSysCache(LANGOID,
+ ObjectIdGetDatum(language),
+ 0, 0, 0);
if (!HeapTupleIsValid(languageTuple))
- {
elog(ERROR, "fmgr_info: cache lookup for language %u failed",
language);
- }
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
if (languageStruct->lanispl)
{
@@ -231,8 +230,11 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
elog(ERROR, "fmgr_info: function %u: unsupported language %u",
functionId, language);
}
+ ReleaseSysCache(languageTuple);
break;
}
+
+ ReleaseSysCache(procedureTuple);
}
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 026f2cc8114..ec223157c4b 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.56 2000/11/04 12:43:24 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.57 2000/11/16 22:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -340,12 +340,15 @@ SetSessionUserIdFromUserName(const char *username)
*/
AssertState(!IsBootstrapProcessingMode());
- userTup = SearchSysCacheTuple(SHADOWNAME,
- PointerGetDatum(username),
- 0, 0, 0);
+ userTup = SearchSysCache(SHADOWNAME,
+ PointerGetDatum(username),
+ 0, 0, 0);
if (!HeapTupleIsValid(userTup))
elog(FATAL, "user \"%s\" does not exist", username);
+
SetSessionUserId( ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid );
+
+ ReleaseSysCache(userTup);
}
@@ -355,13 +358,19 @@ SetSessionUserIdFromUserName(const char *username)
char *
GetUserName(Oid userid)
{
- HeapTuple tuple;
+ HeapTuple tuple;
+ char *result;
- tuple = SearchSysCacheTuple(SHADOWSYSID, ObjectIdGetDatum(userid), 0, 0, 0);
+ tuple = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(userid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "invalid user id %u", (unsigned) userid);
- return pstrdup( NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename) );
+ result = pstrdup( NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename) );
+
+ ReleaseSysCache(tuple);
+ return result;
}
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 3a9e5a1797b..bee4f7e9219 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.71 2000/11/14 18:37:44 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.72 2000/11/16 22:30:39 tgl Exp $
*
*
*-------------------------------------------------------------------------
@@ -320,10 +320,7 @@ InitPostgres(const char *dbname, const char *username)
/*
* Initialize all the system catalog caches.
- */
- zerocaches();
-
- /*
+ *
* Does not touch files since all routines are builtins (?) - thomas
* 1997-11-01
*/
diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c
index 1852b35e465..5139247291d 100644
--- a/src/backend/utils/misc/superuser.c
+++ b/src/backend/utils/misc/superuser.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.15 2000/09/06 14:15:22 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.16 2000/11/16 22:30:40 tgl Exp $
*
* DESCRIPTION
* See superuser().
@@ -29,10 +29,16 @@ superuser(void)
privileges.
--------------------------------------------------------------------------*/
HeapTuple utup;
+ bool result;
- utup = SearchSysCacheTuple(SHADOWSYSID,
- ObjectIdGetDatum(GetUserId()),
- 0, 0, 0);
- Assert(utup != NULL);
- return ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
+ utup = SearchSysCache(SHADOWSYSID,
+ ObjectIdGetDatum(GetUserId()),
+ 0, 0, 0);
+ if (HeapTupleIsValid(utup))
+ {
+ result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
+ ReleaseSysCache(utup);
+ return result;
+ }
+ return false;
}
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 1a0781dd921..a3c0784786d 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -78,7 +78,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.10 2000/05/30 04:24:54 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.11 2000/11/16 22:30:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -88,7 +88,6 @@
#include "access/heapam.h"
#include "access/nbtree.h"
#include "miscadmin.h"
-#include "parser/parse_type.h"
#include "utils/logtape.h"
#include "utils/lsyscache.h"
#include "utils/tuplesort.h"
@@ -506,7 +505,8 @@ tuplesort_begin_datum(Oid datumType,
bool randomAccess)
{
Tuplesortstate *state = tuplesort_begin_common(randomAccess);
- Type typeInfo;
+ int16 typlen;
+ bool typbyval;
state->comparetup = comparetup_datum;
state->copytup = copytup_datum;
@@ -519,9 +519,9 @@ tuplesort_begin_datum(Oid datumType,
/* lookup the function that implements the sort operator */
fmgr_info(get_opcode(sortOperator), &state->sortOpFn);
/* lookup necessary attributes of the datum type */
- typeInfo = typeidType(datumType);
- state->datumTypeLen = typeLen(typeInfo);
- state->datumTypeByVal = typeByVal(typeInfo);
+ get_typlenbyval(datumType, &typlen, &typbyval);
+ state->datumTypeLen = typlen;
+ state->datumTypeByVal = typbyval;
return state;
}
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 25a8174f294..28581ad425a 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: hashjoin.h,v 1.19 2000/08/22 04:06:21 tgl Exp $
+ * $Id: hashjoin.h,v 1.20 2000/11/16 22:30:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,8 +73,8 @@ typedef struct HashTableData
* and outer sides of the hash are the same type, or at least
* binary-compatible types.
*/
+ int16 typLen;
bool typByVal;
- int typLen;
/*
* During 1st scan of inner relation, we get tuples from executor. If
diff --git a/src/include/lib/dllist.h b/src/include/lib/dllist.h
index 9e357a7fd76..9306d4e6b67 100644
--- a/src/include/lib/dllist.h
+++ b/src/include/lib/dllist.h
@@ -2,12 +2,11 @@
*
* dllist.h
* simple doubly linked list primitives
- * the elements of the list are void* so the lists can contain
- * anything
+ * the elements of the list are void* so the lists can contain anything
* Dlelem can only be in one list at a time
*
*
- * Here's a small example of how to use Dllist's :
+ * Here's a small example of how to use Dllists:
*
* Dllist *lst;
* Dlelem *elt;
@@ -24,10 +23,18 @@
* DLFreeElem(elt); -- free the element since we don't
* use it anymore
*
+ *
+ * It is also possible to use Dllist objects that are embedded in larger
+ * structures instead of being separately malloc'd. To do this, use
+ * DLInitElem() to initialize a Dllist field within a larger object.
+ * Don't forget to DLRemove() each field from its list (if any) before
+ * freeing the larger object!
+ *
+ *
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: dllist.h,v 1.13 2000/06/08 22:37:46 momjian Exp $
+ * $Id: dllist.h,v 1.14 2000/11/16 22:30:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,7 +42,6 @@
#ifndef DLLIST_H
#define DLLIST_H
-
struct Dllist;
struct Dlelem;
@@ -53,21 +59,27 @@ typedef struct Dllist
Dlelem *dll_tail;
} Dllist;
-extern Dllist *DLNewList(void); /* initialize a new list */
-extern void DLFreeList(Dllist *); /* free up a list and all the
+extern Dllist *DLNewList(void); /* allocate and initialize a list header */
+extern void DLInitList(Dllist *list); /* init a header alloced by caller */
+extern void DLFreeList(Dllist *list); /* free up a list and all the
* nodes in it */
extern Dlelem *DLNewElem(void *val);
-extern void DLFreeElem(Dlelem *);
-extern Dlelem *DLGetHead(Dllist *);
-extern Dlelem *DLGetTail(Dllist *);
-extern Dlelem *DLRemTail(Dllist *l);
-extern Dlelem *DLGetSucc(Dlelem *); /* get successor */
-extern void DLRemove(Dlelem *); /* removes node from list */
+extern void DLInitElem(Dlelem *e, void *val);
+extern void DLFreeElem(Dlelem *e);
+extern void DLRemove(Dlelem *e); /* removes node from list */
extern void DLAddHead(Dllist *list, Dlelem *node);
extern void DLAddTail(Dllist *list, Dlelem *node);
extern Dlelem *DLRemHead(Dllist *list); /* remove and return the head */
-extern void DLMoveToFront(Dlelem *); /* move node to front of its list */
+extern Dlelem *DLRemTail(Dllist *list);
+extern void DLMoveToFront(Dlelem *e); /* move node to front of its list */
+
+/* These are macros for speed */
+#define DLGetHead(list) ((list)->dll_head)
+#define DLGetTail(list) ((list)->dll_tail)
+#define DLGetSucc(elem) ((elem)->dle_next)
+#define DLGetPred(elem) ((elem)->dle_prev)
+#define DLGetListHdr(elem) ((elem)->dle_list)
-#define DLE_VAL(x) (x->dle_val)
+#define DLE_VAL(elem) ((elem)->dle_val)
#endif /* DLLIST_H */
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index 1ec37fc7b6f..08b0007fcaf 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: makefuncs.h,v 1.25 2000/08/08 15:42:59 tgl Exp $
+ * $Id: makefuncs.h,v 1.26 2000/11/16 22:30:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,7 +42,8 @@ extern Const *makeConst(Oid consttype,
bool constisset,
bool constiscast);
-extern Attr *
- makeAttr(char *relname, char *attname);
+extern Const *makeNullConst(Oid consttype);
+
+extern Attr *makeAttr(char *relname, char *attname);
#endif /* MAKEFUNC_H */
diff --git a/src/include/parser/parse_oper.h b/src/include/parser/parse_oper.h
index 4162cd6d234..4e3c784c0dc 100644
--- a/src/include/parser/parse_oper.h
+++ b/src/include/parser/parse_oper.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_oper.h,v 1.11 2000/01/26 05:58:27 momjian Exp $
+ * $Id: parse_oper.h,v 1.12 2000/11/16 22:30:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,10 +18,13 @@
typedef HeapTuple Operator;
-extern Oid any_ordering_op(Oid restype);
-extern Oid oprid(Operator op);
-extern Operator oper(char *op, Oid arg1, Oid arg2, bool noWarnings);
+extern Operator oper(char *op, Oid arg1, Oid arg2, bool noError);
extern Operator right_oper(char *op, Oid arg);
extern Operator left_oper(char *op, Oid arg);
+extern Oid oper_oid(char *op, Oid arg1, Oid arg2, bool noError);
+extern Oid oprid(Operator op);
+
+extern Oid any_ordering_op(Oid restype);
+
#endif /* PARSE_OPER_H */
diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h
index e2cfd7f4a2d..0d8ba2f1bce 100644
--- a/src/include/parser/parse_type.h
+++ b/src/include/parser/parse_type.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_type.h,v 1.14 2000/06/08 22:37:53 momjian Exp $
+ * $Id: parse_type.h,v 1.15 2000/11/16 22:30:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,15 +21,18 @@ typedef HeapTuple Type;
extern bool typeidIsValid(Oid id);
extern Type typeidType(Oid id);
extern Type typenameType(char *s);
-extern char *typeidTypeName(Oid id);
+
extern Oid typeTypeId(Type tp);
extern int16 typeLen(Type t);
extern bool typeByVal(Type t);
extern char *typeTypeName(Type t);
extern char typeTypeFlag(Type t);
+extern Oid typeTypeRelid(Type typ);
extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod);
+
+extern char *typeidTypeName(Oid id);
extern Oid typeidTypeRelid(Oid type_id);
-extern Oid typeTypeRelid(Type typ);
+extern Oid typenameTypeId(char *s);
#define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid)
diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h
index 39605df47ad..20cf82cbd91 100644
--- a/src/include/rewrite/rewriteSupport.h
+++ b/src/include/rewrite/rewriteSupport.h
@@ -7,14 +7,14 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteSupport.h,v 1.13 2000/09/29 18:21:24 tgl Exp $
+ * $Id: rewriteSupport.h,v 1.14 2000/11/16 22:30:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef REWRITESUPPORT_H
#define REWRITESUPPORT_H
-extern int IsDefinedRewriteRule(char *ruleName);
+extern bool IsDefinedRewriteRule(char *ruleName);
extern void SetRelationRuleStatus(Oid relationId, bool relHasRules,
bool relIsBecomingView);
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index e55b6492d8c..ed78284a478 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: catcache.h,v 1.27 2000/11/10 00:33:12 tgl Exp $
+ * $Id: catcache.h,v 1.28 2000/11/16 22:30:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,18 +32,29 @@
typedef struct catctup
{
- HeapTuple ct_tup; /* A pointer to a tuple */
+ int ct_magic; /* for Assert checks */
+#define CT_MAGIC 0x57261502
+
/*
- * Each tuple in the cache has two catctup items, one in the LRU list
- * and one in the hashbucket list for its hash value. ct_node in each
- * one points to the other one.
+ * Each tuple in a cache is a member of two lists: one lists all the
+ * elements in that cache in LRU order, and the other lists just the
+ * elements in one hashbucket, also in LRU order.
+ *
+ * A tuple marked "dead" must not be returned by subsequent searches.
+ * However, it won't be physically deleted from the cache until its
+ * refcount goes to zero.
*/
- Dlelem *ct_node; /* the other catctup for this tuple */
+ Dlelem lrulist_elem; /* list member of global LRU list */
+ Dlelem cache_elem; /* list member of per-bucket list */
+ int refcount; /* number of active references */
+ bool dead; /* dead but not yet removed? */
+ HeapTupleData tuple; /* tuple management header */
} CatCTup;
+
/* voodoo constants */
#define NCCBUCK 500 /* CatCache buckets */
-#define MAXTUP 300 /* Maximum # of tuples stored per cache */
+#define MAXTUP 500 /* Maximum # of tuples stored per cache */
typedef struct catcache
@@ -60,8 +71,8 @@ typedef struct catcache
short cc_key[4]; /* AttrNumber of each key */
PGFunction cc_hashfunc[4]; /* hash function to use for each key */
ScanKeyData cc_skey[4]; /* precomputed key info for indexscans */
- Dllist *cc_lrulist; /* LRU list, most recent first */
- Dllist *cc_cache[NCCBUCK + 1]; /* hash buckets */
+ Dllist cc_lrulist; /* overall LRU list, most recent first */
+ Dllist cc_cache[NCCBUCK]; /* hash buckets */
} CatCache;
#define InvalidCatalogCacheId (-1)
@@ -70,12 +81,15 @@ typedef struct catcache
extern MemoryContext CacheMemoryContext;
extern void CreateCacheMemoryContext(void);
+extern void AtEOXact_CatCache(bool isCommit);
-extern CatCache *InitSysCache(int id, char *relname, char *indname,
+extern CatCache *InitCatCache(int id, char *relname, char *indname,
int nkeys, int *key);
-extern HeapTuple SearchSysCache(CatCache *cache,
+
+extern HeapTuple SearchCatCache(CatCache *cache,
Datum v1, Datum v2,
Datum v3, Datum v4);
+extern void ReleaseCatCache(HeapTuple tuple);
extern void ResetSystemCache(void);
extern void SystemCacheRelationFlushed(Oid relId);
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 516949d1de9..f8547baa884 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: lsyscache.h,v 1.26 2000/10/05 19:48:34 momjian Exp $
+ * $Id: lsyscache.h,v 1.27 2000/11/16 22:30:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,7 +29,6 @@ extern bool op_mergejoinable(Oid opno, Oid ltype, Oid rtype,
Oid *leftOp, Oid *rightOp);
extern Oid op_hashjoinable(Oid opno, Oid ltype, Oid rtype);
extern bool op_iscachable(Oid opno);
-extern HeapTuple get_operator_tuple(Oid opno);
extern Oid get_commutator(Oid opno);
extern Oid get_negator(Oid opno);
extern RegProcedure get_oprrest(Oid opno);
@@ -39,6 +38,7 @@ extern bool func_iscachable(Oid funcid);
extern char *get_rel_name(Oid relid);
extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid);
+extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
extern Datum get_typdefault(Oid typid);
#endif /* LSYSCACHE_H */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 5d17e8db44c..73abd53e134 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: syscache.h,v 1.26 2000/06/17 04:56:29 tgl Exp $
+ * $Id: syscache.h,v 1.27 2000/11/16 22:30:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -57,12 +57,22 @@
#define TYPENAME 26
#define TYPEOID 27
-extern void zerocaches(void);
extern void InitCatalogCache(void);
-extern HeapTuple SearchSysCacheTuple(int cacheId,
+
+extern HeapTuple SearchSysCache(int cacheId,
+ Datum key1, Datum key2, Datum key3, Datum key4);
+extern void ReleaseSysCache(HeapTuple tuple);
+
+/* convenience routines */
+extern HeapTuple SearchSysCacheCopy(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
-extern HeapTuple SearchSysCacheTupleCopy(int cacheId,
- Datum key1, Datum key2, Datum key3, Datum key4);
+extern Oid GetSysCacheOid(int cacheId,
+ Datum key1, Datum key2, Datum key3, Datum key4);
+
+/* macro for just probing for existence of a tuple via the syscache */
+#define SearchSysCacheExists(c,k1,k2,k3,k4) \
+ OidIsValid(GetSysCacheOid(c,k1,k2,k3,k4))
+
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
AttrNumber attributeNumber, bool *isNull);
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index c1516ea6928..81a4cd75d4b 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.14 2000/10/24 17:01:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.15 2000/11/16 22:30:49 tgl Exp $
*
**********************************************************************/
@@ -521,9 +521,9 @@ plperl_func_handler(PG_FUNCTION_ARGS)
/************************************************************
* Lookup the pg_proc tuple by Oid
************************************************************/
- procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
- 0, 0, 0);
+ procTup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
+ 0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
@@ -537,9 +537,9 @@ plperl_func_handler(PG_FUNCTION_ARGS)
* Get the required information for input conversion of the
* return value.
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(procStruct->prorettype),
- 0, 0, 0);
+ typeTup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(procStruct->prorettype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
free(prodesc->proname);
@@ -560,6 +560,8 @@ plperl_func_handler(PG_FUNCTION_ARGS)
prodesc->result_in_elem = (Oid) (typeStruct->typelem);
prodesc->result_in_len = typeStruct->typlen;
+ ReleaseSysCache(typeTup);
+
/************************************************************
* Get the required information for output conversion
* of all procedure arguments
@@ -567,9 +569,9 @@ plperl_func_handler(PG_FUNCTION_ARGS)
prodesc->nargs = procStruct->pronargs;
for (i = 0; i < prodesc->nargs; i++)
{
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->proargtypes[i]),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
free(prodesc->proname);
@@ -587,7 +589,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
fmgr_info(typeStruct->typoutput, &(prodesc->arg_out_func[i]));
prodesc->arg_out_elem[i] = (Oid) (typeStruct->typelem);
prodesc->arg_out_len[i] = typeStruct->typlen;
-
+ ReleaseSysCache(typeTup);
}
/************************************************************
@@ -617,6 +619,8 @@ plperl_func_handler(PG_FUNCTION_ARGS)
************************************************************/
hv_store(plperl_proc_hash, internal_proname, proname_len,
newSViv((IV) prodesc), 0);
+
+ ReleaseSysCache(procTup);
}
else
{
@@ -744,9 +748,9 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
/************************************************************
* Lookup the pg_proc tuple by Oid
************************************************************/
- procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
- 0, 0, 0);
+ procTup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
+ 0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
@@ -819,6 +823,8 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
hashent = Tcl_CreateHashEntry(plperl_proc_hash,
prodesc->proname, &hashnew);
Tcl_SetHashValue(hashent, (ClientData) prodesc);
+
+ ReleaseSysCache(procTup);
}
else
{
@@ -1068,9 +1074,9 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
* Lookup the attribute type in the syscache
* for the input function
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[attnum - 1]->atttypid),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed",
@@ -1079,6 +1085,7 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
}
typinput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typinput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
+ ReleaseSysCache(typeTup);
/************************************************************
* Set the attribute to NOT NULL and convert the contents
@@ -1538,9 +1545,9 @@ plperl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
************************************************************/
for (i = 0; i < nargs; i++)
{
- typeTup = SearchSysCacheTuple(TYPNAME,
- PointerGetDatum(args[i]),
- 0, 0, 0);
+ typeTup = SearchSysCache(TYPNAME,
+ PointerGetDatum(args[i]),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
elog(ERROR, "plperl: Cache lookup of type %s failed", args[i]);
qdesc->argtypes[i] = typeTup->t_data->t_oid;
@@ -1549,6 +1556,7 @@ plperl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
qdesc->argvalues[i] = (Datum) NULL;
qdesc->arglen[i] = (int) (((Form_pg_type) GETSTRUCT(typeTup))->typlen);
+ ReleaseSysCache(typeTup);
}
/************************************************************
@@ -2084,9 +2092,9 @@ plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
* Lookup the attribute type in the syscache
* for the output function
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed",
@@ -2095,6 +2103,7 @@ plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
+ ReleaseSysCache(typeTup);
/************************************************************
* If there is a value, set the variable
@@ -2156,9 +2165,9 @@ plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
* Lookup the attribute type in the syscache
* for the output function
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed",
@@ -2167,6 +2176,7 @@ plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
+ ReleaseSysCache(typeTup);
/************************************************************
* If there is a value, append the attribute name and the
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index bed95890968..c0fe5968970 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.23 2000/08/31 13:26:16 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.24 2000/11/16 22:30:50 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -53,7 +53,6 @@
#include "access/heapam.h"
#include "utils/syscache.h"
-#include "utils/catcache.h"
#include "catalog/catname.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
@@ -131,9 +130,9 @@ plpgsql_compile(Oid fn_oid, int functype)
* Lookup the pg_proc tuple by Oid
* ----------
*/
- procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(fn_oid),
- 0, 0, 0);
+ procTup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(fn_oid),
+ 0, 0, 0);
if (!HeapTupleIsValid(procTup))
elog(ERROR, "plpgsql: cache lookup for proc %u failed", fn_oid);
@@ -176,9 +175,9 @@ plpgsql_compile(Oid fn_oid, int functype)
* Lookup the functions return type
* ----------
*/
- typeTup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(procStruct->prorettype), 0, 0, 0);
-
+ typeTup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(procStruct->prorettype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
plpgsql_comperrinfo();
@@ -195,6 +194,7 @@ plpgsql_compile(Oid fn_oid, int functype)
function->fn_rettypelem = typeStruct->typelem;
fmgr_info(typeStruct->typinput, &(function->fn_retinput));
}
+ ReleaseSysCache(typeTup);
/* ----------
* Create the variables for the procedures parameters
@@ -208,9 +208,9 @@ plpgsql_compile(Oid fn_oid, int functype)
* Get the parameters type
* ----------
*/
- typeTup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(procStruct->proargtypes[i]), 0, 0, 0);
-
+ typeTup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(procStruct->proargtypes[i]),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
plpgsql_comperrinfo();
@@ -276,6 +276,7 @@ plpgsql_compile(Oid fn_oid, int functype)
arg_varnos[i] = var->varno;
}
+ ReleaseSysCache(typeTup);
}
break;
@@ -512,6 +513,7 @@ plpgsql_compile(Oid fn_oid, int functype)
function->datums[i] = plpgsql_Datums[i];
function->action = plpgsql_yylval.program;
+ ReleaseSysCache(procTup);
/* ----------
* Finally return the compiled function
@@ -608,8 +610,9 @@ plpgsql_parse_word(char *word)
* ----------
*/
typeXlated = xlateSqlType(cp);
- typeTup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(typeXlated), 0, 0, 0);
+ typeTup = SearchSysCache(TYPENAME,
+ PointerGetDatum(typeXlated),
+ 0, 0, 0);
if (HeapTupleIsValid(typeTup))
{
PLpgSQL_type *typ;
@@ -618,6 +621,7 @@ plpgsql_parse_word(char *word)
if (typeStruct->typrelid != InvalidOid)
{
+ ReleaseSysCache(typeTup);
pfree(cp);
return T_WORD;
}
@@ -634,6 +638,7 @@ plpgsql_parse_word(char *word)
plpgsql_yylval.dtype = typ;
+ ReleaseSysCache(typeTup);
pfree(cp);
return T_DTYPE;
}
@@ -933,8 +938,9 @@ plpgsql_parse_wordtype(char *word)
* ----------
*/
typeXlated = xlateSqlType(cp);
- typeTup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(typeXlated), 0, 0, 0);
+ typeTup = SearchSysCache(TYPENAME,
+ PointerGetDatum(typeXlated),
+ 0, 0, 0);
if (HeapTupleIsValid(typeTup))
{
PLpgSQL_type *typ;
@@ -943,6 +949,7 @@ plpgsql_parse_wordtype(char *word)
if (typeStruct->typrelid != InvalidOid)
{
+ ReleaseSysCache(typeTup);
pfree(cp);
return T_ERROR;
}
@@ -959,6 +966,7 @@ plpgsql_parse_wordtype(char *word)
plpgsql_yylval.dtype = typ;
+ ReleaseSysCache(typeTup);
pfree(cp);
return T_DTYPE;
}
@@ -1045,8 +1053,9 @@ plpgsql_parse_dblwordtype(char *string)
* First word could also be a table name
* ----------
*/
- classtup = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(word1), 0, 0, 0);
+ classtup = SearchSysCache(RELNAME,
+ PointerGetDatum(word1),
+ 0, 0, 0);
if (!HeapTupleIsValid(classtup))
{
pfree(word1);
@@ -1060,6 +1069,7 @@ plpgsql_parse_dblwordtype(char *string)
classStruct = (Form_pg_class) GETSTRUCT(classtup);
if (classStruct->relkind != 'r' && classStruct->relkind != 's')
{
+ ReleaseSysCache(classtup);
pfree(word1);
return T_ERROR;
}
@@ -1068,31 +1078,33 @@ plpgsql_parse_dblwordtype(char *string)
* Fetch the named table field and it's type
* ----------
*/
- attrtup = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(classtup->t_data->t_oid),
- PointerGetDatum(word2), 0, 0);
+ attrtup = SearchSysCache(ATTNAME,
+ ObjectIdGetDatum(classtup->t_data->t_oid),
+ PointerGetDatum(word2),
+ 0, 0);
if (!HeapTupleIsValid(attrtup))
{
+ ReleaseSysCache(classtup);
pfree(word1);
return T_ERROR;
}
attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup);
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(attrStruct->atttypid),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
{
plpgsql_comperrinfo();
elog(ERROR, "cache lookup for type %u of %s.%s failed",
attrStruct->atttypid, word1, word2);
}
+ typeStruct = (Form_pg_type) GETSTRUCT(typetup);
/* ----------
* Found that - build a compiler type struct and return it
* ----------
*/
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
-
typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
typ->typname = DatumGetCString(DirectFunctionCall1(nameout,
@@ -1105,6 +1117,9 @@ plpgsql_parse_dblwordtype(char *string)
plpgsql_yylval.dtype = typ;
+ ReleaseSysCache(classtup);
+ ReleaseSysCache(attrtup);
+ ReleaseSysCache(typetup);
pfree(word1);
return T_DTYPE;
}
@@ -1138,8 +1153,9 @@ plpgsql_parse_wordrowtype(char *string)
cp = strchr(word1, '%');
*cp = '\0';
- classtup = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(word1), 0, 0, 0);
+ classtup = SearchSysCache(RELNAME,
+ PointerGetDatum(word1),
+ 0, 0, 0);
if (!HeapTupleIsValid(classtup))
{
plpgsql_comperrinfo();
@@ -1156,8 +1172,9 @@ plpgsql_parse_wordrowtype(char *string)
* Fetch the tables pg_type tuple too
* ----------
*/
- typetup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(word1), 0, 0, 0);
+ typetup = SearchSysCache(TYPENAME,
+ PointerGetDatum(word1),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
{
plpgsql_comperrinfo();
@@ -1178,15 +1195,18 @@ plpgsql_parse_wordrowtype(char *string)
row->fieldnames = malloc(sizeof(char *) * row->nfields);
row->varnos = malloc(sizeof(int) * row->nfields);
+ ReleaseSysCache(typetup);
+
for (i = 0; i < row->nfields; i++)
{
/* ----------
* Get the attribute and it's type
* ----------
*/
- attrtup = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(classtup->t_data->t_oid),
- (Datum) (i + 1), 0, 0);
+ attrtup = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(classtup->t_data->t_oid),
+ Int16GetDatum(i + 1),
+ 0, 0);
if (!HeapTupleIsValid(attrtup))
{
plpgsql_comperrinfo();
@@ -1198,8 +1218,9 @@ plpgsql_parse_wordrowtype(char *string)
cp = DatumGetCString(DirectFunctionCall1(nameout,
NameGetDatum(&(attrStruct->attname))));
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(attrStruct->atttypid),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
{
plpgsql_comperrinfo();
@@ -1238,6 +1259,9 @@ plpgsql_parse_wordrowtype(char *string)
var->isnull = true;
var->shouldfree = false;
+ ReleaseSysCache(typetup);
+ ReleaseSysCache(attrtup);
+
plpgsql_adddatum((PLpgSQL_datum *) var);
/* ----------
@@ -1248,6 +1272,8 @@ plpgsql_parse_wordrowtype(char *string)
row->varnos[i] = var->varno;
}
+ ReleaseSysCache(classtup);
+
/* ----------
* Return the complete row definition
* ----------
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 9c094a0739a..565e304f649 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.31 2000/09/12 19:41:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.32 2000/11/16 22:30:50 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -1641,10 +1641,12 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
extval = "<NULL>";
else
{
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(var->datatype->typoid), 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(var->datatype->typoid),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
- elog(ERROR, "cache lookup for type %u failed (1)", var->datatype->typoid);
+ elog(ERROR, "cache lookup for type %u failed (1)",
+ var->datatype->typoid);
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
fmgr_info(typeStruct->typoutput, &finfo_output);
@@ -1652,6 +1654,7 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
var->value,
ObjectIdGetDatum(typeStruct->typelem),
Int32GetDatum(var->datatype->atttypmod)));
+ ReleaseSysCache(typetup);
}
plpgsql_dstring_append(&ds, extval);
break;
@@ -1961,21 +1964,24 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate,
* Get the C-String representation.
* ----------
*/
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(restype), 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(restype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed (1)", restype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
fmgr_info(typeStruct->typoutput, &finfo_output);
querystr = DatumGetCString(FunctionCall3(&finfo_output,
- query,
- ObjectIdGetDatum(typeStruct->typelem),
- Int32GetDatum(-1)));
+ query,
+ ObjectIdGetDatum(typeStruct->typelem),
+ Int32GetDatum(-1)));
if(!typeStruct->typbyval)
pfree((void *)query);
+ ReleaseSysCache(typetup);
+
/* ----------
* Call SPI_exec() without preparing a saved plan.
* The returncode can be any OK except for OK_SELECT.
@@ -2064,8 +2070,9 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
* Get the C-String representation.
* ----------
*/
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(restype), 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(restype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed (1)", restype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
@@ -2079,6 +2086,8 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
if(!typeStruct->typbyval)
pfree((void *)query);
+ ReleaseSysCache(typetup);
+
/* ----------
* Run the query
* ----------
@@ -2283,8 +2292,9 @@ exec_assign_value(PLpgSQL_execstate * estate,
*/
atttype = SPI_gettypeid(rec->tupdesc, i + 1);
atttypmod = rec->tupdesc->attrs[i]->atttypmod;
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(atttype), 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(atttype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed", atttype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
@@ -2299,6 +2309,7 @@ exec_assign_value(PLpgSQL_execstate * estate,
nulls[i] = 'n';
else
nulls[i] = ' ';
+ ReleaseSysCache(typetup);
}
/* ----------
@@ -2603,9 +2614,13 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate,
* so that we can free the expression context.
*/
if (! *isNull)
- retval = datumCopy(retval,
- get_typbyval(*rettype),
- get_typlen(*rettype));
+ {
+ int16 typeLength;
+ bool byValue;
+
+ get_typlenbyval(*rettype, &typeLength, &byValue);
+ retval = datumCopy(retval, byValue, typeLength);
+ }
FreeExprContext(econtext);
@@ -2726,8 +2741,9 @@ exec_cast_value(Datum value, Oid valtype,
FmgrInfo finfo_output;
char *extval;
- typetup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(valtype), 0, 0, 0);
+ typetup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(valtype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup for type %u failed", valtype);
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
@@ -2742,6 +2758,7 @@ exec_cast_value(Datum value, Oid valtype,
ObjectIdGetDatum(reqtypelem),
Int32GetDatum(reqtypmod));
pfree(extval);
+ ReleaseSysCache(typetup);
}
}
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 0c2ec992b7b..8658cac3065 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.28 2000/07/19 11:53:02 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.29 2000/11/16 22:30:52 tgl Exp $
*
**********************************************************************/
@@ -437,9 +437,9 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
/************************************************************
* Lookup the pg_proc tuple by Oid
************************************************************/
- procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
- 0, 0, 0);
+ procTup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
+ 0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
@@ -452,9 +452,9 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
/************************************************************
* Lookup the pg_language tuple by Oid
************************************************************/
- langTup = SearchSysCacheTuple(LANGOID,
- ObjectIdGetDatum(procStruct->prolang),
- 0, 0, 0);
+ langTup = SearchSysCache(LANGOID,
+ ObjectIdGetDatum(procStruct->prolang),
+ 0, 0, 0);
if (!HeapTupleIsValid(langTup))
{
free(prodesc->proname);
@@ -469,14 +469,15 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
interp = pltcl_safe_interp;
else
interp = pltcl_norm_interp;
+ ReleaseSysCache(langTup);
/************************************************************
* Get the required information for input conversion of the
* return value.
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(procStruct->prorettype),
- 0, 0, 0);
+ typeTup = SearchSysCache(TYPEOID,
+ ObjectIdGetDatum(procStruct->prorettype),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
free(prodesc->proname);
@@ -496,6 +497,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
fmgr_info(typeStruct->typinput, &(prodesc->result_in_func));
prodesc->result_in_elem = typeStruct->typelem;
+ ReleaseSysCache(typeTup);
+
/************************************************************
* Get the required information for output conversion
* of all procedure arguments
@@ -504,9 +507,9 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
proc_internal_args[0] = '\0';
for (i = 0; i < prodesc->nargs; i++)
{
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(procStruct->proargtypes[i]),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
free(prodesc->proname);
@@ -523,6 +526,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
strcat(proc_internal_args, " ");
sprintf(buf, "__PLTcl_Tup_%d", i + 1);
strcat(proc_internal_args, buf);
+ ReleaseSysCache(typeTup);
continue;
}
else
@@ -536,6 +540,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
strcat(proc_internal_args, " ");
sprintf(buf, "%d", i + 1);
strcat(proc_internal_args, buf);
+
+ ReleaseSysCache(typeTup);
}
/************************************************************
@@ -591,6 +597,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
hashent = Tcl_CreateHashEntry(pltcl_proc_hash,
prodesc->proname, &hashnew);
Tcl_SetHashValue(hashent, (ClientData) prodesc);
+
+ ReleaseSysCache(procTup);
}
else
{
@@ -800,9 +808,9 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
/************************************************************
* Lookup the pg_proc tuple by Oid
************************************************************/
- procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
- 0, 0, 0);
+ procTup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
+ 0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
@@ -815,9 +823,9 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
/************************************************************
* Lookup the pg_language tuple by Oid
************************************************************/
- langTup = SearchSysCacheTuple(LANGOID,
- ObjectIdGetDatum(procStruct->prolang),
- 0, 0, 0);
+ langTup = SearchSysCache(LANGOID,
+ ObjectIdGetDatum(procStruct->prolang),
+ 0, 0, 0);
if (!HeapTupleIsValid(langTup))
{
free(prodesc->proname);
@@ -832,6 +840,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
interp = pltcl_safe_interp;
else
interp = pltcl_norm_interp;
+ ReleaseSysCache(langTup);
/************************************************************
* Create the tcl command to define the internal
@@ -896,6 +905,8 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
hashent = Tcl_CreateHashEntry(pltcl_proc_hash,
prodesc->proname, &hashnew);
Tcl_SetHashValue(hashent, (ClientData) prodesc);
+
+ ReleaseSysCache(procTup);
}
else
{
@@ -1151,9 +1162,9 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
* Lookup the attribute type in the syscache
* for the input function
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[attnum - 1]->atttypid),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed",
@@ -1162,6 +1173,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
}
typinput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typinput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
+ ReleaseSysCache(typeTup);
/************************************************************
* Set the attribute to NOT NULL and convert the contents
@@ -1706,9 +1718,9 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
************************************************************/
for (i = 0; i < nargs; i++)
{
- typeTup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(args[i]),
- 0, 0, 0);
+ typeTup = SearchSysCache(TYPENAME,
+ PointerGetDatum(args[i]),
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
elog(ERROR, "pltcl: Cache lookup of type %s failed", args[i]);
qdesc->argtypes[i] = typeTup->t_data->t_oid;
@@ -1717,6 +1729,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
qdesc->argvalues[i] = (Datum) NULL;
qdesc->arglen[i] = (int) (((Form_pg_type) GETSTRUCT(typeTup))->typlen);
+ ReleaseSysCache(typeTup);
}
/************************************************************
@@ -2263,9 +2276,9 @@ pltcl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
* Lookup the attribute type in the syscache
* for the output function
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed",
@@ -2274,6 +2287,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
+ ReleaseSysCache(typeTup);
/************************************************************
* If there is a value, set the variable
@@ -2332,9 +2346,9 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
* Lookup the attribute type in the syscache
* for the output function
************************************************************/
- typeTup = SearchSysCacheTuple(TYPEOID,
+ typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
- 0, 0, 0);
+ 0, 0, 0);
if (!HeapTupleIsValid(typeTup))
{
elog(ERROR, "pltcl: Cache lookup for attribute '%s' type %u failed",
@@ -2343,6 +2357,7 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
typoutput = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typoutput);
typelem = (Oid) (((Form_pg_type) GETSTRUCT(typeTup))->typelem);
+ ReleaseSysCache(typeTup);
/************************************************************
* If there is a value, append the attribute name and the