aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/sort/tuplesort.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/sort/tuplesort.c')
-rw-r--r--src/backend/utils/sort/tuplesort.c68
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;
}
/*