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.c111
1 files changed, 60 insertions, 51 deletions
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 10676299dc8..a8a5cc52047 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -246,7 +246,7 @@ struct Tuplesortstate
{
TupSortStatus status; /* enumerated value as shown above */
int nKeys; /* number of columns in sort key */
- bool randomAccess; /* did caller request random access? */
+ int sortopt; /* Bitmask of flags used to setup sort */
bool bounded; /* did caller specify a maximum number of
* tuples to return? */
bool boundUsed; /* true if we made use of a bounded heap */
@@ -564,12 +564,12 @@ struct Sharedsort
* may or may not match the in-memory representation of the tuple ---
* any conversion needed is the job of the writetup and readtup routines.
*
- * If state->randomAccess is true, then the stored representation of the
- * tuple must be followed by another "unsigned int" that is a copy of the
- * length --- so the total tape space used is actually sizeof(unsigned int)
- * more than the stored length value. This allows read-backwards. When
- * randomAccess is not true, the write/read routines may omit the extra
- * length word.
+ * If state->sortopt contains TUPLESORT_RANDOMACCESS, then the stored
+ * representation of the tuple must be followed by another "unsigned int" that
+ * is a copy of the length --- so the total tape space used is actually
+ * sizeof(unsigned int) more than the stored length value. This allows
+ * read-backwards. When the random access flag was not specified, the
+ * write/read routines may omit the extra length word.
*
* writetup is expected to write both length words as well as the tuple
* data. When readtup is called, the tape is positioned just after the
@@ -614,7 +614,7 @@ struct Sharedsort
static Tuplesortstate *tuplesort_begin_common(int workMem,
SortCoordinate coordinate,
- bool randomAccess);
+ int sortopt);
static void tuplesort_begin_batch(Tuplesortstate *state);
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple);
static bool consider_abort_common(Tuplesortstate *state);
@@ -806,21 +806,20 @@ qsort_tuple_int32_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state)
* Each variant of tuplesort_begin has a workMem parameter specifying the
* maximum number of kilobytes of RAM to use before spilling data to disk.
* (The normal value of this parameter is work_mem, but some callers use
- * other values.) Each variant also has a randomAccess parameter specifying
- * whether the caller needs non-sequential access to the sort result.
+ * other values.) Each variant also has a sortopt which is a bitmask of
+ * sort options. See TUPLESORT_* definitions in tuplesort.h
*/
static Tuplesortstate *
-tuplesort_begin_common(int workMem, SortCoordinate coordinate,
- bool randomAccess)
+tuplesort_begin_common(int workMem, SortCoordinate coordinate, int sortopt)
{
Tuplesortstate *state;
MemoryContext maincontext;
MemoryContext sortcontext;
MemoryContext oldcontext;
- /* See leader_takeover_tapes() remarks on randomAccess support */
- if (coordinate && randomAccess)
+ /* See leader_takeover_tapes() remarks on random access support */
+ if (coordinate && (sortopt & TUPLESORT_RANDOMACCESS))
elog(ERROR, "random access disallowed under parallel sort");
/*
@@ -857,7 +856,7 @@ tuplesort_begin_common(int workMem, SortCoordinate coordinate,
pg_rusage_init(&state->ru_start);
#endif
- state->randomAccess = randomAccess;
+ state->sortopt = sortopt;
state->tuples = true;
/*
@@ -991,10 +990,10 @@ tuplesort_begin_heap(TupleDesc tupDesc,
int nkeys, AttrNumber *attNums,
Oid *sortOperators, Oid *sortCollations,
bool *nullsFirstFlags,
- int workMem, SortCoordinate coordinate, bool randomAccess)
+ int workMem, SortCoordinate coordinate, int sortopt)
{
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
- randomAccess);
+ sortopt);
MemoryContext oldcontext;
int i;
@@ -1006,7 +1005,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
if (trace_sort)
elog(LOG,
"begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
- nkeys, workMem, randomAccess ? 't' : 'f');
+ nkeys, workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
#endif
state->nKeys = nkeys;
@@ -1015,7 +1014,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
false, /* no unique check */
nkeys,
workMem,
- randomAccess,
+ sortopt & TUPLESORT_RANDOMACCESS,
PARALLEL_SORT(state));
state->comparetup = comparetup_heap;
@@ -1065,10 +1064,10 @@ Tuplesortstate *
tuplesort_begin_cluster(TupleDesc tupDesc,
Relation indexRel,
int workMem,
- SortCoordinate coordinate, bool randomAccess)
+ SortCoordinate coordinate, int sortopt)
{
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
- randomAccess);
+ sortopt);
BTScanInsert indexScanKey;
MemoryContext oldcontext;
int i;
@@ -1082,7 +1081,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
elog(LOG,
"begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
RelationGetNumberOfAttributes(indexRel),
- workMem, randomAccess ? 't' : 'f');
+ workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
#endif
state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
@@ -1091,7 +1090,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
false, /* no unique check */
state->nKeys,
workMem,
- randomAccess,
+ sortopt & TUPLESORT_RANDOMACCESS,
PARALLEL_SORT(state));
state->comparetup = comparetup_cluster;
@@ -1172,10 +1171,10 @@ tuplesort_begin_index_btree(Relation heapRel,
bool uniqueNullsNotDistinct,
int workMem,
SortCoordinate coordinate,
- bool randomAccess)
+ int sortopt)
{
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
- randomAccess);
+ sortopt);
BTScanInsert indexScanKey;
MemoryContext oldcontext;
int i;
@@ -1187,7 +1186,7 @@ tuplesort_begin_index_btree(Relation heapRel,
elog(LOG,
"begin index sort: unique = %c, workMem = %d, randomAccess = %c",
enforceUnique ? 't' : 'f',
- workMem, randomAccess ? 't' : 'f');
+ workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
#endif
state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
@@ -1196,7 +1195,7 @@ tuplesort_begin_index_btree(Relation heapRel,
enforceUnique,
state->nKeys,
workMem,
- randomAccess,
+ sortopt & TUPLESORT_RANDOMACCESS,
PARALLEL_SORT(state));
state->comparetup = comparetup_index_btree;
@@ -1254,10 +1253,10 @@ tuplesort_begin_index_hash(Relation heapRel,
uint32 max_buckets,
int workMem,
SortCoordinate coordinate,
- bool randomAccess)
+ int sortopt)
{
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
- randomAccess);
+ sortopt);
MemoryContext oldcontext;
oldcontext = MemoryContextSwitchTo(state->maincontext);
@@ -1270,7 +1269,8 @@ tuplesort_begin_index_hash(Relation heapRel,
high_mask,
low_mask,
max_buckets,
- workMem, randomAccess ? 't' : 'f');
+ workMem,
+ sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
#endif
state->nKeys = 1; /* Only one sort column, the hash code */
@@ -1298,10 +1298,10 @@ tuplesort_begin_index_gist(Relation heapRel,
Relation indexRel,
int workMem,
SortCoordinate coordinate,
- bool randomAccess)
+ int sortopt)
{
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
- randomAccess);
+ sortopt);
MemoryContext oldcontext;
int i;
@@ -1311,7 +1311,7 @@ tuplesort_begin_index_gist(Relation heapRel,
if (trace_sort)
elog(LOG,
"begin index sort: workMem = %d, randomAccess = %c",
- workMem, randomAccess ? 't' : 'f');
+ workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
#endif
state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
@@ -1354,10 +1354,10 @@ tuplesort_begin_index_gist(Relation heapRel,
Tuplesortstate *
tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
bool nullsFirstFlag, int workMem,
- SortCoordinate coordinate, bool randomAccess)
+ SortCoordinate coordinate, int sortopt)
{
Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
- randomAccess);
+ sortopt);
MemoryContext oldcontext;
int16 typlen;
bool typbyval;
@@ -1368,7 +1368,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
if (trace_sort)
elog(LOG,
"begin datum sort: workMem = %d, randomAccess = %c",
- workMem, randomAccess ? 't' : 'f');
+ workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
#endif
state->nKeys = 1; /* always a one-column sort */
@@ -1377,7 +1377,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
false, /* no unique check */
1,
workMem,
- randomAccess,
+ sortopt & TUPLESORT_RANDOMACCESS,
PARALLEL_SORT(state));
state->comparetup = comparetup_datum;
@@ -2272,7 +2272,7 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward,
switch (state->status)
{
case TSS_SORTEDINMEM:
- Assert(forward || state->randomAccess);
+ Assert(forward || state->sortopt & TUPLESORT_RANDOMACCESS);
Assert(!state->slabAllocatorUsed);
if (forward)
{
@@ -2316,7 +2316,7 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward,
break;
case TSS_SORTEDONTAPE:
- Assert(forward || state->randomAccess);
+ Assert(forward || state->sortopt & TUPLESORT_RANDOMACCESS);
Assert(state->slabAllocatorUsed);
/*
@@ -3091,7 +3091,8 @@ mergeruns(Tuplesortstate *state)
* sorted tape, we can stop at this point and do the final merge
* on-the-fly.
*/
- if (!state->randomAccess && state->nInputRuns <= state->nInputTapes
+ if ((state->sortopt & TUPLESORT_RANDOMACCESS) == 0
+ && state->nInputRuns <= state->nInputTapes
&& !WORKER(state))
{
/* Tell logtape.c we won't be writing anymore */
@@ -3337,7 +3338,7 @@ tuplesort_rescan(Tuplesortstate *state)
{
MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
- Assert(state->randomAccess);
+ Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
switch (state->status)
{
@@ -3370,7 +3371,7 @@ tuplesort_markpos(Tuplesortstate *state)
{
MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
- Assert(state->randomAccess);
+ Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
switch (state->status)
{
@@ -3401,7 +3402,7 @@ tuplesort_restorepos(Tuplesortstate *state)
{
MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
- Assert(state->randomAccess);
+ Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
switch (state->status)
{
@@ -3998,7 +3999,8 @@ writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
LogicalTapeWrite(tape, (void *) tupbody, tupbodylen);
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
if (!state->slabAllocatorUsed)
@@ -4021,7 +4023,8 @@ readtup_heap(Tuplesortstate *state, SortTuple *stup,
/* read in the tuple proper */
tuple->t_len = tuplen;
LogicalTapeReadExact(tape, tupbody, tupbodylen);
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
stup->tuple = (void *) tuple;
/* set up first-column key value */
@@ -4233,7 +4236,8 @@ writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
LogicalTapeWrite(tape, &tuple->t_self, sizeof(ItemPointerData));
LogicalTapeWrite(tape, tuple->t_data, tuple->t_len);
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
if (!state->slabAllocatorUsed)
@@ -4259,7 +4263,8 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup,
tuple->t_tableOid = InvalidOid;
/* Read in the tuple body */
LogicalTapeReadExact(tape, tuple->t_data, tuple->t_len);
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
stup->tuple = (void *) tuple;
/* set up first-column key value, if it's a simple column */
@@ -4483,7 +4488,8 @@ writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
tuplen = IndexTupleSize(tuple) + sizeof(tuplen);
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
LogicalTapeWrite(tape, (void *) tuple, IndexTupleSize(tuple));
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
if (!state->slabAllocatorUsed)
@@ -4501,7 +4507,8 @@ readtup_index(Tuplesortstate *state, SortTuple *stup,
IndexTuple tuple = (IndexTuple) readtup_alloc(state, tuplen);
LogicalTapeReadExact(tape, tuple, tuplen);
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
stup->tuple = (void *) tuple;
/* set up first-column key value */
@@ -4571,7 +4578,8 @@ writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
LogicalTapeWrite(tape, (void *) &writtenlen, sizeof(writtenlen));
LogicalTapeWrite(tape, waddr, tuplen);
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeWrite(tape, (void *) &writtenlen, sizeof(writtenlen));
if (!state->slabAllocatorUsed && stup->tuple)
@@ -4611,7 +4619,8 @@ readtup_datum(Tuplesortstate *state, SortTuple *stup,
stup->tuple = raddr;
}
- if (state->randomAccess) /* need trailing length word? */
+ if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
+ * word? */
LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
}