diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index bc036a30b0d..fdf2f4c1a85 100644 --- a/src/backend/executor/nodeMergejoin.c +++ b/src/backend/executor/nodeMergejoin.c @@ -230,19 +230,19 @@ MJExamineQuals(List *mergeclauses, qual->opno); /* And get the matching support or comparison function */ + Assert(clause->ssup.comparator == NULL); sortfunc = get_opfamily_proc(opfamily, op_lefttype, op_righttype, BTSORTSUPPORT_PROC); if (OidIsValid(sortfunc)) { - /* The sort support function should provide a comparator */ + /* The sort support function can provide a comparator */ OidFunctionCall1(sortfunc, PointerGetDatum(&clause->ssup)); - Assert(clause->ssup.comparator != NULL); } - else + if (clause->ssup.comparator == NULL) { - /* opfamily doesn't provide sort support, get comparison func */ + /* support not available, get comparison func */ sortfunc = get_opfamily_proc(opfamily, op_lefttype, op_righttype, diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 4b5ef99531b..552e498cf57 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -245,62 +245,6 @@ get_ordering_op_properties(Oid opno, return result; } -/* - * get_sort_function_for_ordering_op - * Get the OID of the datatype-specific btree sort support function, - * or if there is none, the btree comparison function, - * associated with an ordering operator (a "<" or ">" operator). - * - * *sortfunc receives the support or comparison function OID. - * *issupport is set TRUE if it's a support func, FALSE if a comparison func. - * *reverse is set FALSE if the operator is "<", TRUE if it's ">" - * (indicating that comparison results must be negated before use). - * - * Returns TRUE if successful, FALSE if no btree function can be found. - * (This indicates that the operator is not a valid ordering operator.) - */ -bool -get_sort_function_for_ordering_op(Oid opno, Oid *sortfunc, - bool *issupport, bool *reverse) -{ - Oid opfamily; - Oid opcintype; - int16 strategy; - - /* Find the operator in pg_amop */ - if (get_ordering_op_properties(opno, - &opfamily, &opcintype, &strategy)) - { - /* Found a suitable opfamily, get matching support function */ - *sortfunc = get_opfamily_proc(opfamily, - opcintype, - opcintype, - BTSORTSUPPORT_PROC); - if (OidIsValid(*sortfunc)) - *issupport = true; - else - { - /* opfamily doesn't provide sort support, get comparison func */ - *sortfunc = get_opfamily_proc(opfamily, - opcintype, - opcintype, - BTORDER_PROC); - if (!OidIsValid(*sortfunc)) /* should not happen */ - elog(ERROR, "missing support function %d(%u,%u) in opfamily %u", - BTORDER_PROC, opcintype, opcintype, opfamily); - *issupport = false; - } - *reverse = (strategy == BTGreaterStrategyNumber); - return true; - } - - /* ensure outputs are set on failure */ - *sortfunc = InvalidOid; - *issupport = false; - *reverse = false; - return false; -} - /* * get_equality_op_for_ordering_op * Get the OID of the datatype-specific btree equality operator diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c index 347f448e0f3..2240fd01001 100644 --- a/src/backend/utils/sort/sortsupport.c +++ b/src/backend/utils/sort/sortsupport.c @@ -18,6 +18,7 @@ /* See sortsupport.h */ #define SORTSUPPORT_INCLUDE_DEFINITIONS +#include "access/nbtree.h" #include "fmgr.h" #include "utils/lsyscache.h" #include "utils/sortsupport.h" @@ -94,24 +95,43 @@ PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup) void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup) { - Oid sortFunction; - bool issupport; + Oid sortSupportFunction; + Oid opfamily; + Oid opcintype; + int16 strategy; - if (!get_sort_function_for_ordering_op(orderingOp, - &sortFunction, - &issupport, - &ssup->ssup_reverse)) + Assert(ssup->comparator == NULL); + + /* Find the operator in pg_amop */ + if (!get_ordering_op_properties(orderingOp, &opfamily, &opcintype, + &strategy)) elog(ERROR, "operator %u is not a valid ordering operator", orderingOp); + ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber); - if (issupport) + /* Look for a sort support function */ + sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype, + BTSORTSUPPORT_PROC); + if (OidIsValid(sortSupportFunction)) { - /* The sort support function should provide a comparator */ - OidFunctionCall1(sortFunction, PointerGetDatum(ssup)); - Assert(ssup->comparator != NULL); + /* + * The sort support function can provide a comparator, but it can + * also choose not to so (e.g. based on the selected collation). + */ + OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup)); } - else + + if (ssup->comparator == NULL) { + Oid sortFunction; + + sortFunction = get_opfamily_proc(opfamily, opcintype, opcintype, + BTORDER_PROC); + + if (!OidIsValid(sortFunction)) + elog(ERROR, "missing support function %d(%u,%u) in opfamily %u", + BTORDER_PROC, opcintype, opcintype, opfamily); + /* We'll use a shim to call the old-style btree comparator */ PrepareSortSupportComparisonShim(sortFunction, ssup); } diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index f46460a5757..07d24d4cb8a 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -50,8 +50,6 @@ extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy); extern bool get_ordering_op_properties(Oid opno, Oid *opfamily, Oid *opcintype, int16 *strategy); -extern bool get_sort_function_for_ordering_op(Oid opno, Oid *sortfunc, - bool *issupport, bool *reverse); extern Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse); extern Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type); extern List *get_mergejoin_opfamilies(Oid opno);