diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/analyze.c | 54 | ||||
-rw-r--r-- | src/backend/parser/parse_agg.c | 18 | ||||
-rw-r--r-- | src/backend/parser/parse_clause.c | 13 | ||||
-rw-r--r-- | src/backend/parser/parse_coerce.c | 36 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 44 | ||||
-rw-r--r-- | src/backend/parser/parse_func.c | 64 | ||||
-rw-r--r-- | src/backend/parser/parse_node.c | 52 | ||||
-rw-r--r-- | src/backend/parser/parse_oper.c | 214 | ||||
-rw-r--r-- | src/backend/parser/parse_type.c | 219 |
9 files changed, 377 insertions, 337 deletions
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 |