/* Similar mechanism as in parse_oper.ci, in particular * in the static function oper_select_candidate */ Oid find_equality_operator(Oid ltypeId, Oid rtypeId) { List * const equals=list_make1(makeString("=")); FuncCandidateList clist; Oid inputOids[2] = {ltypeId,rtypeId}; int ncandidates; Oid result = binary_oper_exact(equals, ltypeId, rtypeId); if(result!=InvalidOid) return result; clist = OpernameGetCandidates(equals, 'b', false); ncandidates = func_match_argtypes(2, inputOids, clist, &clist); if (ncandidates == 0) return InvalidOid; else if (ncandidates == 1) return clist->oid; clist = func_select_candidate(2, inputOids, clist); if(clist) return clist->oid; else return InvalidOid; }
/* 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; }