/* * ordering_oper - identify a suitable sorting operator ("<") for a datatype * * On failure, return NULL if noError, else report a standard error */ Operator ordering_oper(Oid argtype, bool noError) { TypeCacheEntry *typentry; Oid oproid; Operator optup; /* * Look for a "<" operator for the datatype. We require it to be an exact * or binary-compatible match, since most callers are not prepared to cope * with adding any run-time type coercion steps. * * Note: the search algorithm used by typcache.c ensures that if a "<" * operator is returned, it will be consistent with the "=" operator * returned by equality_oper. This is critical for sorting and grouping * purposes. */ typentry = lookup_type_cache(argtype, TYPECACHE_LT_OPR); oproid = typentry->lt_opr; /* * If the datatype is an array, then we can use array_lt ... but only if * there is a suitable less-than operator for the element type. (This * check is not in the raw typcache.c code ... should it be?) */ if (oproid == ARRAY_LT_OP) { Oid elem_type = get_element_type(argtype); if (OidIsValid(elem_type)) { optup = ordering_oper(elem_type, true); if (optup != NULL) ReleaseSysCache(optup); else oproid = InvalidOid; /* element type has no "<" */ } else oproid = InvalidOid; /* bogus array type? */ } if (OidIsValid(oproid)) { optup = SearchSysCache(OPEROID, ObjectIdGetDatum(oproid), 0, 0, 0); if (optup == NULL) /* should not fail */ elog(ERROR, "cache lookup failed for operator %u", oproid); return optup; } if (!noError) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("could not identify an ordering operator for type %s", format_type_be(argtype)), errhint("Use an explicit ordering operator or modify the query."))); return NULL; }
/* * execTuplesHashPrepare * Look up the equality and hashing functions needed for a TupleHashTable. * * This is similar to execTuplesMatchPrepare, but we also need to find the * hash functions associated with the equality operators. *eqfunctions and * *hashfunctions receive the palloc'd result arrays. */ void execTuplesHashPrepareSGB(TupleDesc tupdesc, int numCols, AttrNumber *matchColIdx, FmgrInfo **eqfunctions, FmgrInfo **hashfunctions, FmgrInfo **ltfunctions, FmgrInfo **minusfunctions) { int i; *eqfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo)); *hashfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo)); *ltfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo)); *minusfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo)); for (i = 0; i < numCols; i++) { AttrNumber att = matchColIdx[i]; Oid typid = tupdesc->attrs[att - 1]->atttypid; Operator optup; Oid eq_opr; Oid eq_function; Oid hash_function; Oid lt_function; Oid minus_function; /*GIVEN A TYPE GET THE = FUNCTION*/ /*eq_function = equality_oper_funcid(typid);*/ optup = equality_oper(typid, false); eq_opr = oprid(optup); eq_function = oprfuncid(optup); ReleaseSysCache(optup); /*GIVEN A TYPE GET THE HASH FUNCTION*/ hash_function = get_op_hash_function(eq_opr); if (!OidIsValid(hash_function)) /* should not happen */ elog(ERROR, "could not find hash function for hash operator %u", eq_opr); /*GIVEN A TYPE GET THE < FUNCTION*/ optup = ordering_oper(typid, false); lt_function = oprfuncid(optup); ReleaseSysCache(optup); /*GIVEN A TYPE GET THE - FUNCTION*/ optup = minus_oper(typid, false); /*minus_oper WAS ADDED BY YASIN*/ minus_function = oprfuncid(optup); /*get the function from the operator tuple*/ ReleaseSysCache(optup); fmgr_info(eq_function, &(*eqfunctions)[i]); fmgr_info(hash_function, &(*hashfunctions)[i]); fmgr_info(lt_function, &(*ltfunctions)[i]); fmgr_info(minus_function, &(*minusfunctions)[i]); } }
/* * ordering_oper_opid - convenience routine for oprid(ordering_oper()) * * This was formerly called any_ordering_op() */ Oid ordering_oper_opid(Oid argtype) { Operator optup; Oid result; optup = ordering_oper(argtype, false); result = oprid(optup); ReleaseSysCache(optup); return result; }
/* * ordering_oper_opid - convenience routine for oprfuncid(ordering_oper()) */ Oid ordering_oper_funcid(Oid argtype) { Operator optup; Oid result; optup = ordering_oper(argtype, false); result = oprfuncid(optup); ReleaseOperator(optup); return result; }
/*CHANGED BY YASIN*/ void execTuplesMatchAroundPrepare(TupleDesc tupdesc, int numCols, AttrNumber *matchColIdx, FmgrInfo **eqfunctions, FmgrInfo **ltfunctions, FmgrInfo **minusfunctions) { int i; *eqfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo)); *ltfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo)); *minusfunctions = (FmgrInfo *) palloc(numCols * sizeof(FmgrInfo)); for (i = 0; i < numCols; i++) { AttrNumber att = matchColIdx[i]; Oid typid = tupdesc->attrs[att - 1]->atttypid; Operator optup; Oid eq_function; Oid lt_function; Oid minus_function; /*GIVEN A TYPE GET THE = FUNCTION*/ /*eq_function = equality_oper_funcid(typid);*/ optup = equality_oper(typid, false); eq_function = oprfuncid(optup); ReleaseSysCache(optup); /*GIVEN A TYPE GET THE < FUNCTION*/ optup = ordering_oper(typid, false); lt_function = oprfuncid(optup); ReleaseSysCache(optup); /*GIVEN A TYPE GET THE - FUNCTION*/ optup = minus_oper(typid, false); /*minus_oper WAS ADDED BY YASIN*/ minus_function = oprfuncid(optup); /*get the function from the operator tuple*/ ReleaseSysCache(optup); fmgr_info(eq_function, &(*eqfunctions)[i]); fmgr_info(lt_function, &(*ltfunctions)[i]); fmgr_info(minus_function, &(*minusfunctions)[i]); } }