aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/sort/sortsupport.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/sort/sortsupport.c')
-rw-r--r--src/backend/utils/sort/sortsupport.c79
1 files changed, 60 insertions, 19 deletions
diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c
index 2240fd01001..16342f388db 100644
--- a/src/backend/utils/sort/sortsupport.c
+++ b/src/backend/utils/sort/sortsupport.c
@@ -21,6 +21,7 @@
#include "access/nbtree.h"
#include "fmgr.h"
#include "utils/lsyscache.h"
+#include "utils/rel.h"
#include "utils/sortsupport.h"
@@ -86,28 +87,14 @@ PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
}
/*
- * Fill in SortSupport given an ordering operator (btree "<" or ">" operator).
- *
- * Caller must previously have zeroed the SortSupportData structure and then
- * filled in ssup_cxt, ssup_collation, and ssup_nulls_first. This will fill
- * in ssup_reverse as well as the comparator function pointer.
+ * Look up and call sortsupport function to setup SortSupport comparator;
+ * or if no such function exists or it declines to set up the appropriate
+ * state, prepare a suitable shim.
*/
-void
-PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
+static void
+FinishSortSupportFunction(Oid opfamily, Oid opcintype, SortSupport ssup)
{
Oid sortSupportFunction;
- Oid opfamily;
- Oid opcintype;
- int16 strategy;
-
- 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);
/* Look for a sort support function */
sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
@@ -136,3 +123,57 @@ PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
PrepareSortSupportComparisonShim(sortFunction, ssup);
}
}
+
+/*
+ * Fill in SortSupport given an ordering operator (btree "<" or ">" operator).
+ *
+ * Caller must previously have zeroed the SortSupportData structure and then
+ * filled in ssup_cxt, ssup_collation, and ssup_nulls_first. This will fill
+ * in ssup_reverse as well as the comparator function pointer.
+ */
+void
+PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
+{
+ Oid opfamily;
+ Oid opcintype;
+ int16 strategy;
+
+ 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);
+
+ FinishSortSupportFunction(opfamily, opcintype, ssup);
+}
+
+/*
+ * Fill in SortSupport given an index relation, attribute, and strategy.
+ *
+ * Caller must previously have zeroed the SortSupportData structure and then
+ * filled in ssup_cxt, ssup_attno, ssup_collation, and ssup_nulls_first. This
+ * will fill in ssup_reverse (based on the supplied strategy), as well as the
+ * comparator function pointer.
+ */
+void
+PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy,
+ SortSupport ssup)
+{
+ Oid opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1];
+ Oid opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1];
+
+ Assert(ssup->comparator == NULL);
+
+ /* Find the operator in pg_amop */
+ if (indexRel->rd_rel->relam != BTREE_AM_OID)
+ elog(ERROR, "unexpected non-btree AM: %u", indexRel->rd_rel->relam);
+ if (strategy != BTGreaterStrategyNumber &&
+ strategy != BTLessStrategyNumber)
+ elog(ERROR, "unexpected sort support strategy: %d", strategy);
+ ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
+
+ FinishSortSupportFunction(opfamily, opcintype, ssup);
+}