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,
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
/* See sortsupport.h */
#define SORTSUPPORT_INCLUDE_DEFINITIONS
+#include "access/nbtree.h"
#include "fmgr.h"
#include "utils/lsyscache.h"
#include "utils/sortsupport.h"
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);
}
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);