/* left_oper() -- search for a unary left operator (prefix operator) * Given operator name and type of arg, return oper struct. * * IMPORTANT: the returned operator (if any) is only promised to be * coercion-compatible with the input datatype. Do not use this if * you need an exact- or binary-compatible match. * * If no matching operator found, return NULL if noError is true, * raise an error if it is false. pstate and location are used only to report * the error position; pass NULL/-1 if not available. * * NOTE: on success, the returned object is a syscache entry. The caller * must ReleaseSysCache() the entry when done with it. */ Operator left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location) { Oid operOid; FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND; HeapTuple tup = NULL; /* * First try for an "exact" match. */ operOid = OpernameGetOprid(op, InvalidOid, arg); if (!OidIsValid(operOid)) { /* * Otherwise, search for the most suitable candidate. */ FuncCandidateList clist; /* Get prefix operators of given name */ clist = OpernameGetCandidates(op, 'l'); /* No operators found? Then fail... */ if (clist != NULL) { /* * The returned list has args in the form (0, oprright). Move the * useful data into args[0] to keep oper_select_candidate simple. * XXX we are assuming here that we may scribble on the list! */ FuncCandidateList clisti; for (clisti = clist; clisti != NULL; clisti = clisti->next) { clisti->args[0] = clisti->args[1]; } /* * We must run oper_select_candidate even if only one candidate, * otherwise we may falsely return a non-type-compatible operator. */ fdresult = oper_select_candidate(1, &arg, clist, &operOid); } } if (OidIsValid(operOid)) tup = SearchSysCache(OPEROID, ObjectIdGetDatum(operOid), 0, 0, 0); if (!HeapTupleIsValid(tup) && !noError) op_error(pstate, op, 'l', InvalidOid, arg, fdresult, location); return (Operator) tup; }
/* oper() -- search for a binary operator * Given operator name, types of arg1 and arg2, return oper struct. * * IMPORTANT: the returned operator (if any) is only promised to be * coercion-compatible with the input datatypes. Do not use this if * you need an exact- or binary-compatible match; see compatible_oper. * * If no matching operator found, return NULL if noError is true, * raise an error if it is false. pstate and location are used only to report * the error position; pass NULL/-1 if not available. * * NOTE: on success, the returned object is a syscache entry. The caller * must ReleaseSysCache() the entry when done with it. */ Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location) { Oid operOid; FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND; HeapTuple tup = NULL; /* * First try for an "exact" match. */ operOid = binary_oper_exact(opname, ltypeId, rtypeId); if (!OidIsValid(operOid)) { /* * Otherwise, search for the most suitable candidate. */ FuncCandidateList clist; /* Get binary operators of given name */ clist = OpernameGetCandidates(opname, 'b'); /* No operators found? Then fail... */ if (clist != NULL) { /* * Unspecified type for one of the arguments? then use the other * (XXX this is probably dead code?) */ Oid inputOids[2]; if (rtypeId == InvalidOid) rtypeId = ltypeId; else if (ltypeId == InvalidOid) ltypeId = rtypeId; inputOids[0] = ltypeId; inputOids[1] = rtypeId; fdresult = oper_select_candidate(2, inputOids, clist, &operOid); } } if (OidIsValid(operOid)) tup = SearchSysCache(OPEROID, ObjectIdGetDatum(operOid), 0, 0, 0); if (!HeapTupleIsValid(tup) && !noError) op_error(pstate, opname, 'b', ltypeId, rtypeId, fdresult, location); return (Operator) tup; }
/* right_oper() -- search for a unary right operator (postfix operator) * Given operator name and type of arg, return oper struct. * * IMPORTANT: the returned operator (if any) is only promised to be * coercion-compatible with the input datatype. Do not use this if * you need an exact- or binary-compatible match. * * If no matching operator found, return NULL if noError is true, * raise an error if it is false. pstate and location are used only to report * the error position; pass NULL/-1 if not available. * * NOTE: on success, the returned object is a syscache entry. The caller * must ReleaseSysCache() the entry when done with it. */ Operator right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location) { Oid operOid; FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND; HeapTuple tup = NULL; /* * First try for an "exact" match. */ operOid = OpernameGetOprid(op, arg, InvalidOid); if (!OidIsValid(operOid)) { /* * Otherwise, search for the most suitable candidate. */ FuncCandidateList clist; /* Get postfix operators of given name */ clist = OpernameGetCandidates(op, 'r'); /* No operators found? Then fail... */ if (clist != NULL) { /* * We must run oper_select_candidate even if only one candidate, * otherwise we may falsely return a non-type-compatible operator. */ fdresult = oper_select_candidate(1, &arg, clist, &operOid); } } if (OidIsValid(operOid)) tup = SearchSysCache(OPEROID, ObjectIdGetDatum(operOid), 0, 0, 0); if (!HeapTupleIsValid(tup) && !noError) op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location); return (Operator) tup; }
/* right_oper() -- search for a unary right operator (postfix operator) * Given operator name and type of arg, return oper struct. * * IMPORTANT: the returned operator (if any) is only promised to be * coercion-compatible with the input datatype. Do not use this if * you need an exact- or binary-compatible match. * * If no matching operator found, return NULL if noError is true, * raise an error if it is false. pstate and location are used only to report * the error position; pass NULL/-1 if not available. * * NOTE: on success, the returned object is a syscache entry. The caller * must ReleaseSysCache() the entry when done with it. */ Operator right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location) { Oid operOid; OprCacheKey key; bool key_ok; FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND; HeapTuple tup = NULL; /* * Try to find the mapping in the lookaside cache. */ key_ok = make_oper_cache_key(pstate, &key, op, arg, InvalidOid, location); if (key_ok) { operOid = find_oper_cache_entry(&key); if (OidIsValid(operOid)) { tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid)); if (HeapTupleIsValid(tup)) return (Operator) tup; } } /* * First try for an "exact" match. */ operOid = OpernameGetOprid(op, arg, InvalidOid); if (!OidIsValid(operOid)) { /* * Otherwise, search for the most suitable candidate. */ FuncCandidateList clist; /* Get postfix operators of given name */ clist = OpernameGetCandidates(op, 'r', false); /* No operators found? Then fail... */ if (clist != NULL) { /* * We must run oper_select_candidate even if only one candidate, * otherwise we may falsely return a non-type-compatible operator. */ fdresult = oper_select_candidate(1, &arg, clist, &operOid); } } if (OidIsValid(operOid)) tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid)); if (HeapTupleIsValid(tup)) { if (key_ok) make_oper_cache_entry(&key, operOid); } else if (!noError) op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location); return (Operator) tup; }