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:
@ -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'));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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-
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user