diff options
Diffstat (limited to 'src/backend/utils/sort/tuplesort.c')
-rw-r--r-- | src/backend/utils/sort/tuplesort.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 1452e8c7cfc..10b19c0b21f 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -195,6 +195,9 @@ typedef enum #define TAPE_BUFFER_OVERHEAD (BLCKSZ * 3) #define MERGE_BUFFER_SIZE (BLCKSZ * 32) +typedef int (*SortTupleComparator) (const SortTuple *a, const SortTuple *b, + Tuplesortstate *state); + /* * Private state of a Tuplesort operation. */ @@ -223,8 +226,7 @@ struct Tuplesortstate * <0, 0, >0 according as a<b, a=b, a>b. The API must match * qsort_arg_comparator. */ - int (*comparetup) (const SortTuple *a, const SortTuple *b, - Tuplesortstate *state); + SortTupleComparator comparetup; /* * Function to copy a supplied input tuple into palloc'd space and set up @@ -363,12 +365,14 @@ struct Tuplesortstate /* These are specific to the index_hash subcase: */ uint32 hash_mask; /* mask for sortable part of hash code */ + /* This is initialized when, and only when, there's just one key. */ + SortSupport onlyKey; + /* * These variables are specific to the Datum case; they are set by * tuplesort_begin_datum and used only by the DatumTuple routines. */ Oid datumType; - SortSupport datumKey; /* we need typelen and byval in order to know how to copy the Datums. */ int datumTypeLen; bool datumTypeByVal; @@ -492,6 +496,11 @@ static void readtup_datum(Tuplesortstate *state, SortTuple *stup, static void reversedirection_datum(Tuplesortstate *state); static void free_sort_tuple(Tuplesortstate *state, SortTuple *stup); +/* + * Special version of qsort, just for SortTuple objects. + */ +#include "qsort_tuple.c" + /* * tuplesort_begin_xxx @@ -631,6 +640,9 @@ tuplesort_begin_heap(TupleDesc tupDesc, PrepareSortSupportFromOrderingOp(sortOperators[i], sortKey); } + if (nkeys == 1) + state->onlyKey = state->sortKeys; + MemoryContextSwitchTo(oldcontext); return state; @@ -809,13 +821,13 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, state->datumType = datumType; /* Prepare SortSupport data */ - state->datumKey = (SortSupport) palloc0(sizeof(SortSupportData)); + state->onlyKey = (SortSupport) palloc0(sizeof(SortSupportData)); - state->datumKey->ssup_cxt = CurrentMemoryContext; - state->datumKey->ssup_collation = sortCollation; - state->datumKey->ssup_nulls_first = nullsFirstFlag; + state->onlyKey->ssup_cxt = CurrentMemoryContext; + state->onlyKey->ssup_collation = sortCollation; + state->onlyKey->ssup_nulls_first = nullsFirstFlag; - PrepareSortSupportFromOrderingOp(sortOperator, state->datumKey); + PrepareSortSupportFromOrderingOp(sortOperator, state->onlyKey); /* lookup necessary attributes of the datum type */ get_typlenbyval(datumType, &typlen, &typbyval); @@ -1222,11 +1234,16 @@ tuplesort_performsort(Tuplesortstate *state) * amount of memory. Just qsort 'em and we're done. */ if (state->memtupcount > 1) - qsort_arg((void *) state->memtuples, - state->memtupcount, - sizeof(SortTuple), - (qsort_arg_comparator) state->comparetup, - (void *) state); + { + if (state->onlyKey != NULL) + qsort_ssup(state->memtuples, state->memtupcount, + state->onlyKey); + else + qsort_tuple(state->memtuples, + state->memtupcount, + state->comparetup, + state); + } state->current = 0; state->eof_reached = false; state->markpos_offset = 0; @@ -2660,9 +2677,6 @@ comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) int nkey; int32 compare; - /* Allow interrupting long sorts */ - CHECK_FOR_INTERRUPTS(); - /* Compare the leading sort key */ compare = ApplySortComparator(a->datum1, a->isnull1, b->datum1, b->isnull1, @@ -2804,9 +2818,6 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b, int nkey; int32 compare; - /* Allow interrupting long sorts */ - CHECK_FOR_INTERRUPTS(); - /* Compare the leading sort key, if it's simple */ if (state->indexInfo->ii_KeyAttrNumbers[0] != 0) { @@ -2995,9 +3006,6 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b, int nkey; int32 compare; - /* Allow interrupting long sorts */ - CHECK_FOR_INTERRUPTS(); - /* Compare the leading sort key */ compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags, scanKey->sk_collation, @@ -3102,9 +3110,6 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b, IndexTuple tuple1; IndexTuple tuple2; - /* Allow interrupting long sorts */ - CHECK_FOR_INTERRUPTS(); - /* * Fetch hash keys and mask off bits we don't want to sort by. We know * that the first column of the index tuple is the hash key. @@ -3231,12 +3236,9 @@ reversedirection_index_hash(Tuplesortstate *state) static int comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) { - /* Allow interrupting long sorts */ - CHECK_FOR_INTERRUPTS(); - - return ApplySortComparator(a->datum1, a->isnull1, - b->datum1, b->isnull1, - state->datumKey); + /* Not currently needed */ + elog(ERROR, "comparetup_datum() should not be called"); + return 0; } static void @@ -3328,8 +3330,8 @@ readtup_datum(Tuplesortstate *state, SortTuple *stup, static void reversedirection_datum(Tuplesortstate *state) { - state->datumKey->ssup_reverse = !state->datumKey->ssup_reverse; - state->datumKey->ssup_nulls_first = !state->datumKey->ssup_nulls_first; + state->onlyKey->ssup_reverse = !state->onlyKey->ssup_reverse; + state->onlyKey->ssup_nulls_first = !state->onlyKey->ssup_nulls_first; } /* |