Adjust tuplesort API to have bitwise option flags
authorDavid Rowley <drowley@postgresql.org>
Mon, 4 Apr 2022 10:24:59 +0000 (22:24 +1200)
committerDavid Rowley <drowley@postgresql.org>
Mon, 4 Apr 2022 10:24:59 +0000 (22:24 +1200)
This replaces the bool flag for randomAccess.  An upcoming patch requires
adding another option, so instead of breaking the API for that, then
breaking it again one day if we add more options, let's just break it
once.  Any boolean options we add in the future will just make use of an
unused bit in the flags.

Any extensions making use of tuplesorts will need to update their code
to pass TUPLESORT_RANDOMACCESS instead of true for randomAccess.
TUPLESORT_NONE can be used for a set of empty options.

Author: David Rowley
Reviewed-by: Justin Pryzby
Discussion: https://postgr.es/m/CAApHDvoH4ASzsAOyHcxkuY01Qf%2B%2B8JJ0paw%2B03dk%2BW25tQEcNQ%40mail.gmail.com

src/backend/access/gist/gistbuild.c
src/backend/access/hash/hashsort.c
src/backend/access/heap/heapam_handler.c
src/backend/access/nbtree/nbtsort.c
src/backend/catalog/index.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeIncrementalSort.c
src/backend/executor/nodeSort.c
src/backend/utils/adt/orderedsetaggs.c
src/backend/utils/sort/tuplesort.c
src/include/utils/tuplesort.h

index e081e6571a4a2361fe2632df15b61b6bf713946e..f5a5caff8ec82db21fba970df34b85dd2bd3219c 100644 (file)
@@ -271,7 +271,7 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
                                                          index,
                                                          maintenance_work_mem,
                                                          NULL,
-                                                         false);
+                                                         TUPLESORT_NONE);
 
        /* Scan the table, adding all tuples to the tuplesort */
        reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
index 6d8512283a8bcda937704e39b258578657be6b7d..aa61e39f26acba4b9195ae1657d4ac2fd3812580 100644 (file)
@@ -86,7 +86,7 @@ _h_spoolinit(Relation heap, Relation index, uint32 num_buckets)
                                                   hspool->max_buckets,
                                                   maintenance_work_mem,
                                                   NULL,
-                                                  false);
+                                                  TUPLESORT_NONE);
 
    return hspool;
 }
index dee264e8596b11e02dda18907068ec38eb5f8ba6..3a9532cb4f7addee6212c1cf7d18ef36ad696e47 100644 (file)
@@ -726,7 +726,7 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
    if (use_sort)
        tuplesort = tuplesort_begin_cluster(oldTupDesc, OldIndex,
                                            maintenance_work_mem,
-                                           NULL, false);
+                                           NULL, TUPLESORT_NONE);
    else
        tuplesort = NULL;
 
index c074513efa156ff956c174b7ad6ffc770dca2511..9f60fa9894bc6ad6ec93ce73a33bbac73fa2aacc 100644 (file)
@@ -436,7 +436,7 @@ _bt_spools_heapscan(Relation heap, Relation index, BTBuildState *buildstate,
        tuplesort_begin_index_btree(heap, index, buildstate->isunique,
                                    buildstate->nulls_not_distinct,
                                    maintenance_work_mem, coordinate,
-                                   false);
+                                   TUPLESORT_NONE);
 
    /*
     * If building a unique index, put dead tuples in a second spool to keep
@@ -475,7 +475,7 @@ _bt_spools_heapscan(Relation heap, Relation index, BTBuildState *buildstate,
         */
        buildstate->spool2->sortstate =
            tuplesort_begin_index_btree(heap, index, false, false, work_mem,
-                                       coordinate2, false);
+                                       coordinate2, TUPLESORT_NONE);
    }
 
    /* Fill spool using either serial or parallel heap scan */
@@ -1939,7 +1939,7 @@ _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2,
                                                     btspool->isunique,
                                                     btspool->nulls_not_distinct,
                                                     sortmem, coordinate,
-                                                    false);
+                                                    TUPLESORT_NONE);
 
    /*
     * Just as with serial case, there may be a second spool.  If so, a
index dd715ca0609805c9f6bd31846c7ece6e43e8cf4e..55800c947867891f360fc665eecce160c6a77e0b 100644 (file)
@@ -3364,7 +3364,7 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
    state.tuplesort = tuplesort_begin_datum(INT8OID, Int8LessOperator,
                                            InvalidOid, false,
                                            maintenance_work_mem,
-                                           NULL, false);
+                                           NULL, TUPLESORT_NONE);
    state.htups = state.itups = state.tups_inserted = 0;
 
    /* ambulkdelete updates progress metrics */
index 08cf569d8fa7c78cdef081f533874b125c3e5591..23030a32a59b84a63479fda309e0011ac0e80cd3 100644 (file)
@@ -530,7 +530,7 @@ initialize_phase(AggState *aggstate, int newphase)
                                                  sortnode->collations,
                                                  sortnode->nullsFirst,
                                                  work_mem,
-                                                 NULL, false);
+                                                 NULL, TUPLESORT_NONE);
    }
 
    aggstate->current_phase = newphase;
@@ -607,7 +607,7 @@ initialize_aggregate(AggState *aggstate, AggStatePerTrans pertrans,
                                      pertrans->sortOperators[0],
                                      pertrans->sortCollations[0],
                                      pertrans->sortNullsFirst[0],
-                                     work_mem, NULL, false);
+                                     work_mem, NULL, TUPLESORT_NONE);
        }
        else
            pertrans->sortstates[aggstate->current_set] =
@@ -617,7 +617,7 @@ initialize_aggregate(AggState *aggstate, AggStatePerTrans pertrans,
                                     pertrans->sortOperators,
                                     pertrans->sortCollations,
                                     pertrans->sortNullsFirst,
-                                    work_mem, NULL, false);
+                                    work_mem, NULL, TUPLESORT_NONE);
    }
 
    /*
index d6fb56dec73cc9d3c52aa820f0eb79efa3b05f8f..4f50bc845dac76a57905a572b977405baa4a0e00 100644 (file)
@@ -315,7 +315,7 @@ switchToPresortedPrefixMode(PlanState *pstate)
                                                &(plannode->sort.nullsFirst[nPresortedCols]),
                                                work_mem,
                                                NULL,
-                                               false);
+                                               TUPLESORT_NONE);
        node->prefixsort_state = prefixsort_state;
    }
    else
@@ -616,7 +616,7 @@ ExecIncrementalSort(PlanState *pstate)
                                                  plannode->sort.nullsFirst,
                                                  work_mem,
                                                  NULL,
-                                                 false);
+                                                 TUPLESORT_NONE);
            node->fullsort_state = fullsort_state;
        }
        else
index 9481a622bf5c7bc76aaded04c59dacdacb9c7f56..a113d737955dd7bdfe253b7b825570f6bb672d16 100644 (file)
@@ -77,6 +77,7 @@ ExecSort(PlanState *pstate)
        Sort       *plannode = (Sort *) node->ss.ps.plan;
        PlanState  *outerNode;
        TupleDesc   tupDesc;
+       int         tuplesortopts = TUPLESORT_NONE;
 
        SO1_printf("ExecSort: %s\n",
                   "sorting subplan");
@@ -96,6 +97,9 @@ ExecSort(PlanState *pstate)
        outerNode = outerPlanState(node);
        tupDesc = ExecGetResultType(outerNode);
 
+       if (node->randomAccess)
+           tuplesortopts |= TUPLESORT_RANDOMACCESS;
+
        if (node->datumSort)
            tuplesortstate = tuplesort_begin_datum(TupleDescAttr(tupDesc, 0)->atttypid,
                                                   plannode->sortOperators[0],
@@ -103,7 +107,7 @@ ExecSort(PlanState *pstate)
                                                   plannode->nullsFirst[0],
                                                   work_mem,
                                                   NULL,
-                                                  node->randomAccess);
+                                                  tuplesortopts);
        else
            tuplesortstate = tuplesort_begin_heap(tupDesc,
                                                  plannode->numCols,
@@ -113,7 +117,7 @@ ExecSort(PlanState *pstate)
                                                  plannode->nullsFirst,
                                                  work_mem,
                                                  NULL,
-                                                 node->randomAccess);
+                                                 tuplesortopts);
        if (node->bounded)
            tuplesort_set_bound(tuplesortstate, node->bound);
        node->tuplesortstate = (void *) tuplesortstate;
index 96dae6ec4a832a82c37fa13581b7b30f3e8991ba..6d4f6b7dca2349d2126517b81140d77fcfa65284 100644 (file)
@@ -118,6 +118,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
    OSAPerQueryState *qstate;
    MemoryContext gcontext;
    MemoryContext oldcontext;
+   int         tuplesortopt;
 
    /*
     * Check we're called as aggregate (and not a window function), and get
@@ -283,6 +284,11 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
    osastate->qstate = qstate;
    osastate->gcontext = gcontext;
 
+   tuplesortopt = TUPLESORT_NONE;
+
+   if (qstate->rescan_needed)
+       tuplesortopt |= TUPLESORT_RANDOMACCESS;
+
    /*
     * Initialize tuplesort object.
     */
@@ -295,7 +301,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
                                                   qstate->sortNullsFirsts,
                                                   work_mem,
                                                   NULL,
-                                                  qstate->rescan_needed);
+                                                  tuplesortopt);
    else
        osastate->sortstate = tuplesort_begin_datum(qstate->sortColType,
                                                    qstate->sortOperator,
@@ -303,7 +309,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
                                                    qstate->sortNullsFirst,
                                                    work_mem,
                                                    NULL,
-                                                   qstate->rescan_needed);
+                                                   tuplesortopt);
 
    osastate->number_of_rows = 0;
    osastate->sort_done = false;
index 10676299dc86533b2ca825ada0b794b641809a38..a8a5cc52047dc5d6971b9ee5272513488b2e6ebf 100644 (file)
@@ -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));
 }
 
index da5ba59198967b41c41e1af2731bf5139253a454..345f4ce8024df729a2073d554753ebf99f482809 100644 (file)
@@ -86,6 +86,12 @@ typedef enum
    SORT_SPACE_TYPE_MEMORY
 } TuplesortSpaceType;
 
+/* Bitwise option flags for tuple sorts */
+#define TUPLESORT_NONE                 0
+
+/* specifies whether non-sequential access to the sort result is required */
+#define    TUPLESORT_RANDOMACCESS          (1 << 0)
+
 typedef struct TuplesortInstrumentation
 {
    TuplesortMethod sortMethod; /* sort algorithm used */
@@ -201,32 +207,33 @@ extern Tuplesortstate *tuplesort_begin_heap(TupleDesc tupDesc,
                                            Oid *sortOperators, Oid *sortCollations,
                                            bool *nullsFirstFlags,
                                            int workMem, SortCoordinate coordinate,
-                                           bool randomAccess);
+                                           int sortopt);
 extern Tuplesortstate *tuplesort_begin_cluster(TupleDesc tupDesc,
                                               Relation indexRel, int workMem,
-                                              SortCoordinate coordinate, bool randomAccess);
+                                              SortCoordinate coordinate,
+                                              int sortopt);
 extern Tuplesortstate *tuplesort_begin_index_btree(Relation heapRel,
                                                   Relation indexRel,
                                                   bool enforceUnique,
                                                   bool uniqueNullsNotDistinct,
                                                   int workMem, SortCoordinate coordinate,
-                                                  bool randomAccess);
+                                                  int sortopt);
 extern Tuplesortstate *tuplesort_begin_index_hash(Relation heapRel,
                                                  Relation indexRel,
                                                  uint32 high_mask,
                                                  uint32 low_mask,
                                                  uint32 max_buckets,
                                                  int workMem, SortCoordinate coordinate,
-                                                 bool randomAccess);
+                                                 int sortopt);
 extern Tuplesortstate *tuplesort_begin_index_gist(Relation heapRel,
                                                  Relation indexRel,
                                                  int workMem, SortCoordinate coordinate,
-                                                 bool randomAccess);
+                                                 int sortopt);
 extern Tuplesortstate *tuplesort_begin_datum(Oid datumType,
                                             Oid sortOperator, Oid sortCollation,
                                             bool nullsFirstFlag,
                                             int workMem, SortCoordinate coordinate,
-                                            bool randomAccess);
+                                            int sortopt);
 
 extern void tuplesort_set_bound(Tuplesortstate *state, int64 bound);
 extern bool tuplesort_used_bound(Tuplesortstate *state);