1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-14 08:21:07 +03:00

Change SearchSysCache coding conventions so that a reference count is

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

View File

@ -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'));
}
/*

View File

@ -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;

View File

@ -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-

View File

@ -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,

View File

@ -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,

View File

@ -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()

View File

@ -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;
}