diff options
Diffstat (limited to 'src/backend/utils/sort/sortsupport.c')
-rw-r--r-- | src/backend/utils/sort/sortsupport.c | 79 |
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); +} |