{
    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 */
  * 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
 
 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);
  * 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");
 
    /*
        pg_rusage_init(&state->ru_start);
 #endif
 
-   state->randomAccess = randomAccess;
+   state->sortopt = sortopt;
    state->tuples = true;
 
    /*
                     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;
 
    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;
                                false,  /* no unique check */
                                nkeys,
                                workMem,
-                               randomAccess,
+                               sortopt & TUPLESORT_RANDOMACCESS,
                                PARALLEL_SORT(state));
 
    state->comparetup = comparetup_heap;
 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;
        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);
                                false,  /* no unique check */
                                state->nKeys,
                                workMem,
-                               randomAccess,
+                               sortopt & TUPLESORT_RANDOMACCESS,
                                PARALLEL_SORT(state));
 
    state->comparetup = comparetup_cluster;
                            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;
        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);
                                enforceUnique,
                                state->nKeys,
                                workMem,
-                               randomAccess,
+                               sortopt & TUPLESORT_RANDOMACCESS,
                                PARALLEL_SORT(state));
 
    state->comparetup = comparetup_index_btree;
                           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);
             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 */
                           Relation indexRel,
                           int workMem,
                           SortCoordinate coordinate,
-                          bool randomAccess)
+                          int sortopt)
 {
    Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
-                                                  randomAccess);
+                                                  sortopt);
    MemoryContext oldcontext;
    int         i;
 
    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);
 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;
    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 */
                                false,  /* no unique check */
                                1,
                                workMem,
-                               randomAccess,
+                               sortopt & TUPLESORT_RANDOMACCESS,
                                PARALLEL_SORT(state));
 
    state->comparetup = comparetup_datum;
    switch (state->status)
    {
        case TSS_SORTEDINMEM:
-           Assert(forward || state->randomAccess);
+           Assert(forward || state->sortopt & TUPLESORT_RANDOMACCESS);
            Assert(!state->slabAllocatorUsed);
            if (forward)
            {
            break;
 
        case TSS_SORTEDONTAPE:
-           Assert(forward || state->randomAccess);
+           Assert(forward || state->sortopt & TUPLESORT_RANDOMACCESS);
            Assert(state->slabAllocatorUsed);
 
            /*
             * 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 */
 {
    MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
 
-   Assert(state->randomAccess);
+   Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
 
    switch (state->status)
    {
 {
    MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
 
-   Assert(state->randomAccess);
+   Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
 
    switch (state->status)
    {
 {
    MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
 
-   Assert(state->randomAccess);
+   Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
 
    switch (state->status)
    {
 
    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)
    /* 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 */
    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)
    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 */
    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)
    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 */
 
    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)
        stup->tuple = raddr;
    }
 
-   if (state->randomAccess)    /* need trailing length word? */
+   if (state->sortopt & TUPLESORT_RANDOMACCESS)    /* need trailing length
+                                                    * word? */
        LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
 }