PostgreSQL Source Code  git master
tuplesort.h File Reference
#include "access/itup.h"
#include "executor/tuptable.h"
#include "storage/dsm.h"
#include "utils/relcache.h"
Include dependency graph for tuplesort.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SortCoordinateData
 
struct  TuplesortInstrumentation
 

Macros

#define NUM_TUPLESORTMETHODS   4
 
#define TUPLESORT_NONE   0
 
#define TUPLESORT_RANDOMACCESS   (1 << 0)
 
#define TUPLESORT_ALLOWBOUNDED   (1 << 1)
 

Typedefs

typedef struct Tuplesortstate Tuplesortstate
 
typedef struct Sharedsort Sharedsort
 
typedef struct SortCoordinateData SortCoordinateData
 
typedef struct SortCoordinateDataSortCoordinate
 
typedef struct TuplesortInstrumentation TuplesortInstrumentation
 

Enumerations

enum  TuplesortMethod {
  SORT_TYPE_STILL_IN_PROGRESS = 0 , SORT_TYPE_TOP_N_HEAPSORT = 1 << 0 , SORT_TYPE_QUICKSORT = 1 << 1 , SORT_TYPE_EXTERNAL_SORT = 1 << 2 ,
  SORT_TYPE_EXTERNAL_MERGE = 1 << 3
}
 
enum  TuplesortSpaceType { SORT_SPACE_TYPE_DISK , SORT_SPACE_TYPE_MEMORY }
 

Functions

Tuplesortstatetuplesort_begin_heap (TupleDesc tupDesc, int nkeys, AttrNumber *attNums, Oid *sortOperators, Oid *sortCollations, bool *nullsFirstFlags, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_cluster (TupleDesc tupDesc, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_index_btree (Relation heapRel, Relation indexRel, bool enforceUnique, bool uniqueNullsNotDistinct, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_index_hash (Relation heapRel, Relation indexRel, uint32 high_mask, uint32 low_mask, uint32 max_buckets, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_index_gist (Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_datum (Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, SortCoordinate coordinate, int sortopt)
 
void tuplesort_set_bound (Tuplesortstate *state, int64 bound)
 
bool tuplesort_used_bound (Tuplesortstate *state)
 
void tuplesort_puttupleslot (Tuplesortstate *state, TupleTableSlot *slot)
 
void tuplesort_putheaptuple (Tuplesortstate *state, HeapTuple tup)
 
void tuplesort_putindextuplevalues (Tuplesortstate *state, Relation rel, ItemPointer self, Datum *values, bool *isnull)
 
void tuplesort_putdatum (Tuplesortstate *state, Datum val, bool isNull)
 
void tuplesort_performsort (Tuplesortstate *state)
 
bool tuplesort_gettupleslot (Tuplesortstate *state, bool forward, bool copy, TupleTableSlot *slot, Datum *abbrev)
 
HeapTuple tuplesort_getheaptuple (Tuplesortstate *state, bool forward)
 
IndexTuple tuplesort_getindextuple (Tuplesortstate *state, bool forward)
 
bool tuplesort_getdatum (Tuplesortstate *state, bool forward, Datum *val, bool *isNull, Datum *abbrev)
 
bool tuplesort_skiptuples (Tuplesortstate *state, int64 ntuples, bool forward)
 
void tuplesort_end (Tuplesortstate *state)
 
void tuplesort_reset (Tuplesortstate *state)
 
void tuplesort_get_stats (Tuplesortstate *state, TuplesortInstrumentation *stats)
 
const char * tuplesort_method_name (TuplesortMethod m)
 
const char * tuplesort_space_type_name (TuplesortSpaceType t)
 
int tuplesort_merge_order (int64 allowedMem)
 
Size tuplesort_estimate_shared (int nworkers)
 
void tuplesort_initialize_shared (Sharedsort *shared, int nWorkers, dsm_segment *seg)
 
void tuplesort_attach_shared (Sharedsort *shared, dsm_segment *seg)
 
void tuplesort_rescan (Tuplesortstate *state)
 
void tuplesort_markpos (Tuplesortstate *state)
 
void tuplesort_restorepos (Tuplesortstate *state)
 

Macro Definition Documentation

◆ NUM_TUPLESORTMETHODS

#define NUM_TUPLESORTMETHODS   4

Definition at line 81 of file tuplesort.h.

◆ TUPLESORT_ALLOWBOUNDED

#define TUPLESORT_ALLOWBOUNDED   (1 << 1)

Definition at line 96 of file tuplesort.h.

◆ TUPLESORT_NONE

#define TUPLESORT_NONE   0

Definition at line 90 of file tuplesort.h.

◆ TUPLESORT_RANDOMACCESS

#define TUPLESORT_RANDOMACCESS   (1 << 0)

Definition at line 93 of file tuplesort.h.

Typedef Documentation

◆ Sharedsort

typedef struct Sharedsort Sharedsort

Definition at line 1 of file tuplesort.h.

◆ SortCoordinate

Definition at line 58 of file tuplesort.h.

◆ SortCoordinateData

◆ TuplesortInstrumentation

◆ Tuplesortstate

Definition at line 1 of file tuplesort.h.

Enumeration Type Documentation

◆ TuplesortMethod

Enumerator
SORT_TYPE_STILL_IN_PROGRESS 
SORT_TYPE_TOP_N_HEAPSORT 
SORT_TYPE_QUICKSORT 
SORT_TYPE_EXTERNAL_SORT 
SORT_TYPE_EXTERNAL_MERGE 

Definition at line 72 of file tuplesort.h.

73 {
75  SORT_TYPE_TOP_N_HEAPSORT = 1 << 0,
76  SORT_TYPE_QUICKSORT = 1 << 1,
77  SORT_TYPE_EXTERNAL_SORT = 1 << 2,
TuplesortMethod
Definition: tuplesort.h:73
@ SORT_TYPE_EXTERNAL_SORT
Definition: tuplesort.h:77
@ SORT_TYPE_TOP_N_HEAPSORT
Definition: tuplesort.h:75
@ SORT_TYPE_QUICKSORT
Definition: tuplesort.h:76
@ SORT_TYPE_STILL_IN_PROGRESS
Definition: tuplesort.h:74
@ SORT_TYPE_EXTERNAL_MERGE
Definition: tuplesort.h:78

◆ TuplesortSpaceType

Enumerator
SORT_SPACE_TYPE_DISK 
SORT_SPACE_TYPE_MEMORY 

Definition at line 83 of file tuplesort.h.

84 {
TuplesortSpaceType
Definition: tuplesort.h:84
@ SORT_SPACE_TYPE_DISK
Definition: tuplesort.h:85
@ SORT_SPACE_TYPE_MEMORY
Definition: tuplesort.h:86

Function Documentation

◆ tuplesort_attach_shared()

void tuplesort_attach_shared ( Sharedsort shared,
dsm_segment seg 
)

Definition at line 4721 of file tuplesort.c.

4722 {
4723  /* Attach to SharedFileSet */
4724  SharedFileSetAttach(&shared->fileset, seg);
4725 }
void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:62
SharedFileSet fileset
Definition: tuplesort.c:516

References Sharedsort::fileset, and SharedFileSetAttach().

Referenced by _bt_parallel_build_main().

◆ tuplesort_begin_cluster()

Tuplesortstate* tuplesort_begin_cluster ( TupleDesc  tupDesc,
Relation  indexRel,
int  workMem,
SortCoordinate  coordinate,
int  sortopt 
)

Definition at line 1105 of file tuplesort.c.

1109 {
1110  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
1111  sortopt);
1112  BTScanInsert indexScanKey;
1113  MemoryContext oldcontext;
1114  int i;
1115 
1116  Assert(indexRel->rd_rel->relam == BTREE_AM_OID);
1117 
1118  oldcontext = MemoryContextSwitchTo(state->maincontext);
1119 
1120 #ifdef TRACE_SORT
1121  if (trace_sort)
1122  elog(LOG,
1123  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
1125  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
1126 #endif
1127 
1128  state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
1129 
1130  TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
1131  false, /* no unique check */
1132  state->nKeys,
1133  workMem,
1134  sortopt & TUPLESORT_RANDOMACCESS,
1135  PARALLEL_SORT(state));
1136 
1137  state->comparetup = comparetup_cluster;
1138  state->copytup = copytup_cluster;
1139  state->writetup = writetup_cluster;
1140  state->readtup = readtup_cluster;
1141  state->abbrevNext = 10;
1142 
1143  state->indexInfo = BuildIndexInfo(indexRel);
1144 
1145  /*
1146  * If we don't have a simple leading attribute, we don't currently
1147  * initialize datum1, so disable optimizations that require it.
1148  */
1149  if (state->indexInfo->ii_IndexAttrNumbers[0] == 0)
1150  state->haveDatum1 = false;
1151  else
1152  state->haveDatum1 = true;
1153 
1154  state->tupDesc = tupDesc; /* assume we need not copy tupDesc */
1155 
1156  indexScanKey = _bt_mkscankey(indexRel, NULL);
1157 
1158  if (state->indexInfo->ii_Expressions != NULL)
1159  {
1160  TupleTableSlot *slot;
1161  ExprContext *econtext;
1162 
1163  /*
1164  * We will need to use FormIndexDatum to evaluate the index
1165  * expressions. To do that, we need an EState, as well as a
1166  * TupleTableSlot to put the table tuples into. The econtext's
1167  * scantuple has to point to that slot, too.
1168  */
1169  state->estate = CreateExecutorState();
1170  slot = MakeSingleTupleTableSlot(tupDesc, &TTSOpsHeapTuple);
1171  econtext = GetPerTupleExprContext(state->estate);
1172  econtext->ecxt_scantuple = slot;
1173  }
1174 
1175  /* Prepare SortSupport data for each column */
1176  state->sortKeys = (SortSupport) palloc0(state->nKeys *
1177  sizeof(SortSupportData));
1178 
1179  for (i = 0; i < state->nKeys; i++)
1180  {
1181  SortSupport sortKey = state->sortKeys + i;
1182  ScanKey scanKey = indexScanKey->scankeys + i;
1183  int16 strategy;
1184 
1185  sortKey->ssup_cxt = CurrentMemoryContext;
1186  sortKey->ssup_collation = scanKey->sk_collation;
1187  sortKey->ssup_nulls_first =
1188  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
1189  sortKey->ssup_attno = scanKey->sk_attno;
1190  /* Convey if abbreviation optimization is applicable in principle */
1191  sortKey->abbreviate = (i == 0 && state->haveDatum1);
1192 
1193  AssertState(sortKey->ssup_attno != 0);
1194 
1195  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
1197 
1198  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
1199  }
1200 
1201  pfree(indexScanKey);
1202 
1203  MemoryContextSwitchTo(oldcontext);
1204 
1205  return state;
1206 }
#define AssertState(condition)
Definition: c.h:807
signed short int16
Definition: c.h:428
#define LOG
Definition: elog.h:25
#define elog(elevel,...)
Definition: elog.h:218
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:84
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1238
EState * CreateExecutorState(void)
Definition: execUtils.c:90
#define GetPerTupleExprContext(estate)
Definition: executor.h:537
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:2418
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Definition: mcxt.c:1175
void * palloc0(Size size)
Definition: mcxt.c:1099
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:1085
#define SK_BT_DESC
Definition: nbtree.h:1084
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
Definition: nbtutils.c:90
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:495
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:508
void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, SortSupport ssup)
Definition: sortsupport.c:162
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define BTLessStrategyNumber
Definition: stratnum.h:29
ScanKeyData scankeys[INDEX_MAX_KEYS]
Definition: nbtree.h:793
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:232
Form_pg_class rd_rel
Definition: rel.h:109
int sk_flags
Definition: skey.h:66
Oid sk_collation
Definition: skey.h:70
AttrNumber sk_attno
Definition: skey.h:67
AttrNumber ssup_attno
Definition: sortsupport.h:81
bool ssup_nulls_first
Definition: sortsupport.h:75
MemoryContext ssup_cxt
Definition: sortsupport.h:66
Definition: regguts.h:318
static void copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4196
#define PARALLEL_SORT(state)
Definition: tuplesort.c:129
#define CLUSTER_SORT
Definition: tuplesort.c:126
static Tuplesortstate * tuplesort_begin_common(int workMem, SortCoordinate coordinate, int sortopt)
Definition: tuplesort.c:845
bool trace_sort
Definition: tuplesort.c:144
static void readtup_cluster(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Definition: tuplesort.c:4290
static int comparetup_cluster(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4084
static void writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
Definition: tuplesort.c:4269
#define TUPLESORT_RANDOMACCESS
Definition: tuplesort.h:93

References _bt_mkscankey(), SortSupportData::abbreviate, Assert(), AssertState, BTGreaterStrategyNumber, BTLessStrategyNumber, BuildIndexInfo(), CLUSTER_SORT, comparetup_cluster(), copytup_cluster(), CreateExecutorState(), CurrentMemoryContext, ExprContext::ecxt_scantuple, elog, GetPerTupleExprContext, i, IndexRelationGetNumberOfKeyAttributes, LOG, MakeSingleTupleTableSlot(), MemoryContextSwitchTo(), palloc0(), PARALLEL_SORT, pfree(), PrepareSortSupportFromIndexRel(), RelationData::rd_rel, readtup_cluster(), RelationGetNumberOfAttributes, BTScanInsertData::scankeys, ScanKeyData::sk_attno, SK_BT_DESC, SK_BT_NULLS_FIRST, ScanKeyData::sk_collation, ScanKeyData::sk_flags, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, TTSOpsHeapTuple, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, and writetup_cluster().

Referenced by heapam_relation_copy_for_cluster().

◆ tuplesort_begin_datum()

Tuplesortstate* tuplesort_begin_datum ( Oid  datumType,
Oid  sortOperator,
Oid  sortCollation,
bool  nullsFirstFlag,
int  workMem,
SortCoordinate  coordinate,
int  sortopt 
)

Definition at line 1396 of file tuplesort.c.

1399 {
1400  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
1401  sortopt);
1402  MemoryContext oldcontext;
1403  int16 typlen;
1404  bool typbyval;
1405 
1406  oldcontext = MemoryContextSwitchTo(state->maincontext);
1407 
1408 #ifdef TRACE_SORT
1409  if (trace_sort)
1410  elog(LOG,
1411  "begin datum sort: workMem = %d, randomAccess = %c",
1412  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
1413 #endif
1414 
1415  state->nKeys = 1; /* always a one-column sort */
1416 
1417  TRACE_POSTGRESQL_SORT_START(DATUM_SORT,
1418  false, /* no unique check */
1419  1,
1420  workMem,
1421  sortopt & TUPLESORT_RANDOMACCESS,
1422  PARALLEL_SORT(state));
1423 
1424  state->comparetup = comparetup_datum;
1425  state->copytup = copytup_datum;
1426  state->writetup = writetup_datum;
1427  state->readtup = readtup_datum;
1428  state->abbrevNext = 10;
1429  state->haveDatum1 = true;
1430 
1431  state->datumType = datumType;
1432 
1433  /* lookup necessary attributes of the datum type */
1434  get_typlenbyval(datumType, &typlen, &typbyval);
1435  state->datumTypeLen = typlen;
1436  state->tuples = !typbyval;
1437 
1438  /* Prepare SortSupport data */
1439  state->sortKeys = (SortSupport) palloc0(sizeof(SortSupportData));
1440 
1441  state->sortKeys->ssup_cxt = CurrentMemoryContext;
1442  state->sortKeys->ssup_collation = sortCollation;
1443  state->sortKeys->ssup_nulls_first = nullsFirstFlag;
1444 
1445  /*
1446  * Abbreviation is possible here only for by-reference types. In theory,
1447  * a pass-by-value datatype could have an abbreviated form that is cheaper
1448  * to compare. In a tuple sort, we could support that, because we can
1449  * always extract the original datum from the tuple as needed. Here, we
1450  * can't, because a datum sort only stores a single copy of the datum; the
1451  * "tuple" field of each SortTuple is NULL.
1452  */
1453  state->sortKeys->abbreviate = !typbyval;
1454 
1455  PrepareSortSupportFromOrderingOp(sortOperator, state->sortKeys);
1456 
1457  /*
1458  * The "onlyKey" optimization cannot be used with abbreviated keys, since
1459  * tie-breaker comparisons may be required. Typically, the optimization
1460  * is only of value to pass-by-value types anyway, whereas abbreviated
1461  * keys are typically only of value to pass-by-reference types.
1462  */
1463  if (!state->sortKeys->abbrev_converter)
1464  state->onlyKey = state->sortKeys;
1465 
1466  MemoryContextSwitchTo(oldcontext);
1467 
1468  return state;
1469 }
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2208
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:135
static int comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4565
static void readtup_datum(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Definition: tuplesort.c:4632
static void writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
Definition: tuplesort.c:4593
#define DATUM_SORT
Definition: tuplesort.c:125
static void copytup_datum(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4586

References comparetup_datum(), copytup_datum(), CurrentMemoryContext, DATUM_SORT, elog, get_typlenbyval(), LOG, MemoryContextSwitchTo(), palloc0(), PARALLEL_SORT, PrepareSortSupportFromOrderingOp(), readtup_datum(), trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, and writetup_datum().

Referenced by ExecSort(), initialize_aggregate(), ordered_set_startup(), and validate_index().

◆ tuplesort_begin_heap()

Tuplesortstate* tuplesort_begin_heap ( TupleDesc  tupDesc,
int  nkeys,
AttrNumber attNums,
Oid sortOperators,
Oid sortCollations,
bool nullsFirstFlags,
int  workMem,
SortCoordinate  coordinate,
int  sortopt 
)

Definition at line 1030 of file tuplesort.c.

1035 {
1036  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
1037  sortopt);
1038  MemoryContext oldcontext;
1039  int i;
1040 
1041  oldcontext = MemoryContextSwitchTo(state->maincontext);
1042 
1043  AssertArg(nkeys > 0);
1044 
1045 #ifdef TRACE_SORT
1046  if (trace_sort)
1047  elog(LOG,
1048  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
1049  nkeys, workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
1050 #endif
1051 
1052  state->nKeys = nkeys;
1053 
1054  TRACE_POSTGRESQL_SORT_START(HEAP_SORT,
1055  false, /* no unique check */
1056  nkeys,
1057  workMem,
1058  sortopt & TUPLESORT_RANDOMACCESS,
1059  PARALLEL_SORT(state));
1060 
1061  state->comparetup = comparetup_heap;
1062  state->copytup = copytup_heap;
1063  state->writetup = writetup_heap;
1064  state->readtup = readtup_heap;
1065  state->haveDatum1 = true;
1066 
1067  state->tupDesc = tupDesc; /* assume we need not copy tupDesc */
1068  state->abbrevNext = 10;
1069 
1070  /* Prepare SortSupport data for each column */
1071  state->sortKeys = (SortSupport) palloc0(nkeys * sizeof(SortSupportData));
1072 
1073  for (i = 0; i < nkeys; i++)
1074  {
1075  SortSupport sortKey = state->sortKeys + i;
1076 
1077  AssertArg(attNums[i] != 0);
1078  AssertArg(sortOperators[i] != 0);
1079 
1080  sortKey->ssup_cxt = CurrentMemoryContext;
1081  sortKey->ssup_collation = sortCollations[i];
1082  sortKey->ssup_nulls_first = nullsFirstFlags[i];
1083  sortKey->ssup_attno = attNums[i];
1084  /* Convey if abbreviation optimization is applicable in principle */
1085  sortKey->abbreviate = (i == 0 && state->haveDatum1);
1086 
1087  PrepareSortSupportFromOrderingOp(sortOperators[i], sortKey);
1088  }
1089 
1090  /*
1091  * The "onlyKey" optimization cannot be used with abbreviated keys, since
1092  * tie-breaker comparisons may be required. Typically, the optimization
1093  * is only of value to pass-by-value types anyway, whereas abbreviated
1094  * keys are typically only of value to pass-by-reference types.
1095  */
1096  if (nkeys == 1 && !state->sortKeys->abbrev_converter)
1097  state->onlyKey = state->sortKeys;
1098 
1099  MemoryContextSwitchTo(oldcontext);
1100 
1101  return state;
1102 }
#define AssertArg(condition)
Definition: c.h:806
static void copytup_heap(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:3950
static void readtup_heap(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Definition: tuplesort.c:4053
static int comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:3888
static void writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
Definition: tuplesort.c:4028
#define HEAP_SORT
Definition: tuplesort.c:123

References SortSupportData::abbreviate, AssertArg, comparetup_heap(), copytup_heap(), CurrentMemoryContext, elog, HEAP_SORT, i, LOG, MemoryContextSwitchTo(), palloc0(), PARALLEL_SORT, PrepareSortSupportFromOrderingOp(), readtup_heap(), SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, and writetup_heap().

Referenced by ExecIncrementalSort(), ExecSort(), initialize_aggregate(), initialize_phase(), ordered_set_startup(), and switchToPresortedPrefixMode().

◆ tuplesort_begin_index_btree()

Tuplesortstate* tuplesort_begin_index_btree ( Relation  heapRel,
Relation  indexRel,
bool  enforceUnique,
bool  uniqueNullsNotDistinct,
int  workMem,
SortCoordinate  coordinate,
int  sortopt 
)

Definition at line 1209 of file tuplesort.c.

1216 {
1217  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
1218  sortopt);
1219  BTScanInsert indexScanKey;
1220  MemoryContext oldcontext;
1221  int i;
1222 
1223  oldcontext = MemoryContextSwitchTo(state->maincontext);
1224 
1225 #ifdef TRACE_SORT
1226  if (trace_sort)
1227  elog(LOG,
1228  "begin index sort: unique = %c, workMem = %d, randomAccess = %c",
1229  enforceUnique ? 't' : 'f',
1230  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
1231 #endif
1232 
1233  state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
1234 
1235  TRACE_POSTGRESQL_SORT_START(INDEX_SORT,
1236  enforceUnique,
1237  state->nKeys,
1238  workMem,
1239  sortopt & TUPLESORT_RANDOMACCESS,
1240  PARALLEL_SORT(state));
1241 
1242  state->comparetup = comparetup_index_btree;
1243  state->copytup = copytup_index;
1244  state->writetup = writetup_index;
1245  state->readtup = readtup_index;
1246  state->abbrevNext = 10;
1247  state->haveDatum1 = true;
1248 
1249  state->heapRel = heapRel;
1250  state->indexRel = indexRel;
1251  state->enforceUnique = enforceUnique;
1252  state->uniqueNullsNotDistinct = uniqueNullsNotDistinct;
1253 
1254  indexScanKey = _bt_mkscankey(indexRel, NULL);
1255 
1256  /* Prepare SortSupport data for each column */
1257  state->sortKeys = (SortSupport) palloc0(state->nKeys *
1258  sizeof(SortSupportData));
1259 
1260  for (i = 0; i < state->nKeys; i++)
1261  {
1262  SortSupport sortKey = state->sortKeys + i;
1263  ScanKey scanKey = indexScanKey->scankeys + i;
1264  int16 strategy;
1265 
1266  sortKey->ssup_cxt = CurrentMemoryContext;
1267  sortKey->ssup_collation = scanKey->sk_collation;
1268  sortKey->ssup_nulls_first =
1269  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
1270  sortKey->ssup_attno = scanKey->sk_attno;
1271  /* Convey if abbreviation optimization is applicable in principle */
1272  sortKey->abbreviate = (i == 0 && state->haveDatum1);
1273 
1274  AssertState(sortKey->ssup_attno != 0);
1275 
1276  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
1278 
1279  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
1280  }
1281 
1282  pfree(indexScanKey);
1283 
1284  MemoryContextSwitchTo(oldcontext);
1285 
1286  return state;
1287 }
static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4326
static void readtup_index(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Definition: tuplesort.c:4542
static void copytup_index(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4515
#define INDEX_SORT
Definition: tuplesort.c:124
static void writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
Definition: tuplesort.c:4522

References _bt_mkscankey(), SortSupportData::abbreviate, AssertState, BTGreaterStrategyNumber, BTLessStrategyNumber, comparetup_index_btree(), copytup_index(), CurrentMemoryContext, elog, i, INDEX_SORT, IndexRelationGetNumberOfKeyAttributes, LOG, MemoryContextSwitchTo(), palloc0(), PARALLEL_SORT, pfree(), PrepareSortSupportFromIndexRel(), readtup_index(), BTScanInsertData::scankeys, ScanKeyData::sk_attno, SK_BT_DESC, SK_BT_NULLS_FIRST, ScanKeyData::sk_collation, ScanKeyData::sk_flags, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, and writetup_index().

Referenced by _bt_parallel_scan_and_sort(), and _bt_spools_heapscan().

◆ tuplesort_begin_index_gist()

Tuplesortstate* tuplesort_begin_index_gist ( Relation  heapRel,
Relation  indexRel,
int  workMem,
SortCoordinate  coordinate,
int  sortopt 
)

Definition at line 1338 of file tuplesort.c.

1343 {
1344  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
1345  sortopt);
1346  MemoryContext oldcontext;
1347  int i;
1348 
1349  oldcontext = MemoryContextSwitchTo(state->sortcontext);
1350 
1351 #ifdef TRACE_SORT
1352  if (trace_sort)
1353  elog(LOG,
1354  "begin index sort: workMem = %d, randomAccess = %c",
1355  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
1356 #endif
1357 
1358  state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
1359 
1360  state->comparetup = comparetup_index_btree;
1361  state->copytup = copytup_index;
1362  state->writetup = writetup_index;
1363  state->readtup = readtup_index;
1364  state->haveDatum1 = true;
1365 
1366  state->heapRel = heapRel;
1367  state->indexRel = indexRel;
1368 
1369  /* Prepare SortSupport data for each column */
1370  state->sortKeys = (SortSupport) palloc0(state->nKeys *
1371  sizeof(SortSupportData));
1372 
1373  for (i = 0; i < state->nKeys; i++)
1374  {
1375  SortSupport sortKey = state->sortKeys + i;
1376 
1377  sortKey->ssup_cxt = CurrentMemoryContext;
1378  sortKey->ssup_collation = indexRel->rd_indcollation[i];
1379  sortKey->ssup_nulls_first = false;
1380  sortKey->ssup_attno = i + 1;
1381  /* Convey if abbreviation optimization is applicable in principle */
1382  sortKey->abbreviate = (i == 0 && state->haveDatum1);
1383 
1384  AssertState(sortKey->ssup_attno != 0);
1385 
1386  /* Look for a sort support function */
1387  PrepareSortSupportFromGistIndexRel(indexRel, sortKey);
1388  }
1389 
1390  MemoryContextSwitchTo(oldcontext);
1391 
1392  return state;
1393 }
void PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup)
Definition: sortsupport.c:189
Oid * rd_indcollation
Definition: rel.h:213

References SortSupportData::abbreviate, AssertState, comparetup_index_btree(), copytup_index(), CurrentMemoryContext, elog, i, IndexRelationGetNumberOfKeyAttributes, LOG, MemoryContextSwitchTo(), palloc0(), PrepareSortSupportFromGistIndexRel(), RelationData::rd_indcollation, readtup_index(), SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, and writetup_index().

Referenced by gistbuild().

◆ tuplesort_begin_index_hash()

Tuplesortstate* tuplesort_begin_index_hash ( Relation  heapRel,
Relation  indexRel,
uint32  high_mask,
uint32  low_mask,
uint32  max_buckets,
int  workMem,
SortCoordinate  coordinate,
int  sortopt 
)

Definition at line 1290 of file tuplesort.c.

1298 {
1299  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
1300  sortopt);
1301  MemoryContext oldcontext;
1302 
1303  oldcontext = MemoryContextSwitchTo(state->maincontext);
1304 
1305 #ifdef TRACE_SORT
1306  if (trace_sort)
1307  elog(LOG,
1308  "begin index sort: high_mask = 0x%x, low_mask = 0x%x, "
1309  "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
1310  high_mask,
1311  low_mask,
1312  max_buckets,
1313  workMem,
1314  sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
1315 #endif
1316 
1317  state->nKeys = 1; /* Only one sort column, the hash code */
1318 
1319  state->comparetup = comparetup_index_hash;
1320  state->copytup = copytup_index;
1321  state->writetup = writetup_index;
1322  state->readtup = readtup_index;
1323  state->haveDatum1 = true;
1324 
1325  state->heapRel = heapRel;
1326  state->indexRel = indexRel;
1327 
1328  state->high_mask = high_mask;
1329  state->low_mask = low_mask;
1330  state->max_buckets = max_buckets;
1331 
1332  MemoryContextSwitchTo(oldcontext);
1333 
1334  return state;
1335 }
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4460

References comparetup_index_hash(), copytup_index(), elog, LOG, MemoryContextSwitchTo(), readtup_index(), trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, and writetup_index().

Referenced by _h_spoolinit().

◆ tuplesort_end()

void tuplesort_end ( Tuplesortstate state)

Definition at line 1620 of file tuplesort.c.

1621 {
1623 
1624  /*
1625  * Free the main memory context, including the Tuplesortstate struct
1626  * itself.
1627  */
1628  MemoryContextDelete(state->maincontext);
1629 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
static void tuplesort_free(Tuplesortstate *state)
Definition: tuplesort.c:1543

References MemoryContextDelete(), and tuplesort_free().

Referenced by _bt_parallel_scan_and_sort(), _bt_spooldestroy(), _h_spooldestroy(), ExecEndAgg(), ExecEndIncrementalSort(), ExecEndSort(), ExecReScanAgg(), ExecReScanSort(), gistbuild(), heapam_relation_copy_for_cluster(), initialize_aggregate(), initialize_phase(), ordered_set_shutdown(), process_ordered_aggregate_multi(), process_ordered_aggregate_single(), and validate_index().

◆ tuplesort_estimate_shared()

Size tuplesort_estimate_shared ( int  nworkers)

Definition at line 4677 of file tuplesort.c.

4678 {
4679  Size tapesSize;
4680 
4681  Assert(nWorkers > 0);
4682 
4683  /* Make sure that BufFile shared state is MAXALIGN'd */
4684  tapesSize = mul_size(sizeof(TapeShare), nWorkers);
4685  tapesSize = MAXALIGN(add_size(tapesSize, offsetof(Sharedsort, tapes)));
4686 
4687  return tapesSize;
4688 }
#define MAXALIGN(LEN)
Definition: c.h:757
#define offsetof(type, field)
Definition: c.h:727
size_t Size
Definition: c.h:540
Size add_size(Size s1, Size s2)
Definition: shmem.c:502
Size mul_size(Size s1, Size s2)
Definition: shmem.c:519

References add_size(), Assert(), MAXALIGN, mul_size(), and offsetof.

Referenced by _bt_begin_parallel().

◆ tuplesort_get_stats()

void tuplesort_get_stats ( Tuplesortstate state,
TuplesortInstrumentation stats 
)

Definition at line 3476 of file tuplesort.c.

3478 {
3479  /*
3480  * Note: it might seem we should provide both memory and disk usage for a
3481  * disk-based sort. However, the current code doesn't track memory space
3482  * accurately once we have begun to return tuples to the caller (since we
3483  * don't account for pfree's the caller is expected to do), so we cannot
3484  * rely on availMem in a disk sort. This does not seem worth the overhead
3485  * to fix. Is it worth creating an API for the memory context code to
3486  * tell us how much is actually used in sortcontext?
3487  */
3489 
3490  if (state->isMaxSpaceDisk)
3492  else
3494  stats->spaceUsed = (state->maxSpace + 1023) / 1024;
3495 
3496  switch (state->maxSpaceStatus)
3497  {
3498  case TSS_SORTEDINMEM:
3499  if (state->boundUsed)
3501  else
3503  break;
3504  case TSS_SORTEDONTAPE:
3506  break;
3507  case TSS_FINALMERGE:
3509  break;
3510  default:
3512  break;
3513  }
3514 }
TuplesortMethod sortMethod
Definition: tuplesort.h:100
TuplesortSpaceType spaceType
Definition: tuplesort.h:101
@ TSS_SORTEDONTAPE
Definition: tuplesort.c:218
@ TSS_SORTEDINMEM
Definition: tuplesort.c:217
@ TSS_FINALMERGE
Definition: tuplesort.c:219
static void tuplesort_updatemax(Tuplesortstate *state)
Definition: tuplesort.c:1637

References SORT_SPACE_TYPE_DISK, SORT_SPACE_TYPE_MEMORY, SORT_TYPE_EXTERNAL_MERGE, SORT_TYPE_EXTERNAL_SORT, SORT_TYPE_QUICKSORT, SORT_TYPE_STILL_IN_PROGRESS, SORT_TYPE_TOP_N_HEAPSORT, TuplesortInstrumentation::sortMethod, TuplesortInstrumentation::spaceType, TuplesortInstrumentation::spaceUsed, TSS_FINALMERGE, TSS_SORTEDINMEM, TSS_SORTEDONTAPE, and tuplesort_updatemax().

Referenced by ExecSort(), instrumentSortedGroup(), and show_sort_info().

◆ tuplesort_getdatum()

bool tuplesort_getdatum ( Tuplesortstate state,
bool  forward,
Datum val,
bool isNull,
Datum abbrev 
)

Definition at line 2647 of file tuplesort.c.

2649 {
2650  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2651  SortTuple stup;
2652 
2653  if (!tuplesort_gettuple_common(state, forward, &stup))
2654  {
2655  MemoryContextSwitchTo(oldcontext);
2656  return false;
2657  }
2658 
2659  /* Ensure we copy into caller's memory context */
2660  MemoryContextSwitchTo(oldcontext);
2661 
2662  /* Record abbreviated key for caller */
2663  if (state->sortKeys->abbrev_converter && abbrev)
2664  *abbrev = stup.datum1;
2665 
2666  if (stup.isnull1 || !state->tuples)
2667  {
2668  *val = stup.datum1;
2669  *isNull = stup.isnull1;
2670  }
2671  else
2672  {
2673  /* use stup.tuple because stup.datum1 may be an abbreviation */
2674  *val = datumCopy(PointerGetDatum(stup.tuple), false, state->datumTypeLen);
2675  *isNull = false;
2676  }
2677 
2678  return true;
2679 }
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
long val
Definition: informix.c:664
#define PointerGetDatum(X)
Definition: postgres.h:600
bool isnull1
Definition: tuplesort.c:185
void * tuple
Definition: tuplesort.c:183
Datum datum1
Definition: tuplesort.c:184
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:2307

References SortTuple::datum1, datumCopy(), SortTuple::isnull1, MemoryContextSwitchTo(), PointerGetDatum, SortTuple::tuple, tuplesort_gettuple_common(), and val.

Referenced by ExecSort(), heapam_index_validate_scan(), mode_final(), percentile_cont_final_common(), percentile_cont_multi_final_common(), percentile_disc_final(), percentile_disc_multi_final(), and process_ordered_aggregate_single().

◆ tuplesort_getheaptuple()

HeapTuple tuplesort_getheaptuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 2598 of file tuplesort.c.

2599 {
2600  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2601  SortTuple stup;
2602 
2603  if (!tuplesort_gettuple_common(state, forward, &stup))
2604  stup.tuple = NULL;
2605 
2606  MemoryContextSwitchTo(oldcontext);
2607 
2608  return stup.tuple;
2609 }

References MemoryContextSwitchTo(), SortTuple::tuple, and tuplesort_gettuple_common().

Referenced by heapam_relation_copy_for_cluster().

◆ tuplesort_getindextuple()

IndexTuple tuplesort_getindextuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 2618 of file tuplesort.c.

2619 {
2620  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2621  SortTuple stup;
2622 
2623  if (!tuplesort_gettuple_common(state, forward, &stup))
2624  stup.tuple = NULL;
2625 
2626  MemoryContextSwitchTo(oldcontext);
2627 
2628  return (IndexTuple) stup.tuple;
2629 }

References MemoryContextSwitchTo(), SortTuple::tuple, and tuplesort_gettuple_common().

Referenced by _bt_load(), _h_indexbuild(), and gist_indexsortbuild().

◆ tuplesort_gettupleslot()

bool tuplesort_gettupleslot ( Tuplesortstate state,
bool  forward,
bool  copy,
TupleTableSlot slot,
Datum abbrev 
)

Definition at line 2561 of file tuplesort.c.

2563 {
2564  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2565  SortTuple stup;
2566 
2567  if (!tuplesort_gettuple_common(state, forward, &stup))
2568  stup.tuple = NULL;
2569 
2570  MemoryContextSwitchTo(oldcontext);
2571 
2572  if (stup.tuple)
2573  {
2574  /* Record abbreviated key for caller */
2575  if (state->sortKeys->abbrev_converter && abbrev)
2576  *abbrev = stup.datum1;
2577 
2578  if (copy)
2580 
2581  ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, copy);
2582  return true;
2583  }
2584  else
2585  {
2586  ExecClearTuple(slot);
2587  return false;
2588  }
2589 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1446
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1439
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425

References SortTuple::datum1, ExecClearTuple(), ExecStoreMinimalTuple(), heap_copy_minimal_tuple(), MemoryContextSwitchTo(), SortTuple::tuple, and tuplesort_gettuple_common().

Referenced by ExecIncrementalSort(), ExecSort(), fetch_input_tuple(), hypothetical_dense_rank_final(), hypothetical_rank_common(), process_ordered_aggregate_multi(), and switchToPresortedPrefixMode().

◆ tuplesort_initialize_shared()

void tuplesort_initialize_shared ( Sharedsort shared,
int  nWorkers,
dsm_segment seg 
)

Definition at line 4698 of file tuplesort.c.

4699 {
4700  int i;
4701 
4702  Assert(nWorkers > 0);
4703 
4704  SpinLockInit(&shared->mutex);
4705  shared->currentWorker = 0;
4706  shared->workersFinished = 0;
4707  SharedFileSetInit(&shared->fileset, seg);
4708  shared->nTapes = nWorkers;
4709  for (i = 0; i < nWorkers; i++)
4710  {
4711  shared->tapes[i].firstblocknumber = 0L;
4712  }
4713 }
void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:44
#define SpinLockInit(lock)
Definition: spin.h:60
TapeShare tapes[FLEXIBLE_ARRAY_MEMBER]
Definition: tuplesort.c:525
int workersFinished
Definition: tuplesort.c:513
int nTapes
Definition: tuplesort.c:519
slock_t mutex
Definition: tuplesort.c:502
int currentWorker
Definition: tuplesort.c:512
long firstblocknumber
Definition: logtape.h:54

References Assert(), Sharedsort::currentWorker, Sharedsort::fileset, TapeShare::firstblocknumber, i, Sharedsort::mutex, Sharedsort::nTapes, SharedFileSetInit(), SpinLockInit, Sharedsort::tapes, and Sharedsort::workersFinished.

Referenced by _bt_begin_parallel().

◆ tuplesort_markpos()

void tuplesort_markpos ( Tuplesortstate state)

Definition at line 3412 of file tuplesort.c.

3413 {
3414  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3415 
3416  Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
3417 
3418  switch (state->status)
3419  {
3420  case TSS_SORTEDINMEM:
3421  state->markpos_offset = state->current;
3422  state->markpos_eof = state->eof_reached;
3423  break;
3424  case TSS_SORTEDONTAPE:
3425  LogicalTapeTell(state->result_tape,
3426  &state->markpos_block,
3427  &state->markpos_offset);
3428  state->markpos_eof = state->eof_reached;
3429  break;
3430  default:
3431  elog(ERROR, "invalid tuplesort state");
3432  break;
3433  }
3434 
3435  MemoryContextSwitchTo(oldcontext);
3436 }
#define ERROR
Definition: elog.h:33
void LogicalTapeTell(LogicalTape *lt, long *blocknum, int *offset)
Definition: logtape.c:1163

References Assert(), elog, ERROR, LogicalTapeTell(), MemoryContextSwitchTo(), TSS_SORTEDINMEM, TSS_SORTEDONTAPE, and TUPLESORT_RANDOMACCESS.

Referenced by ExecSortMarkPos().

◆ tuplesort_merge_order()

int tuplesort_merge_order ( int64  allowedMem)

Definition at line 2755 of file tuplesort.c.

2756 {
2757  int mOrder;
2758 
2759  /*----------
2760  * In the merge phase, we need buffer space for each input and output tape.
2761  * Each pass in the balanced merge algorithm reads from M input tapes, and
2762  * writes to N output tapes. Each tape consumes TAPE_BUFFER_OVERHEAD bytes
2763  * of memory. In addition to that, we want MERGE_BUFFER_SIZE workspace per
2764  * input tape.
2765  *
2766  * totalMem = M * (TAPE_BUFFER_OVERHEAD + MERGE_BUFFER_SIZE) +
2767  * N * TAPE_BUFFER_OVERHEAD
2768  *
2769  * Except for the last and next-to-last merge passes, where there can be
2770  * fewer tapes left to process, M = N. We choose M so that we have the
2771  * desired amount of memory available for the input buffers
2772  * (TAPE_BUFFER_OVERHEAD + MERGE_BUFFER_SIZE), given the total memory
2773  * available for the tape buffers (allowedMem).
2774  *
2775  * Note: you might be thinking we need to account for the memtuples[]
2776  * array in this calculation, but we effectively treat that as part of the
2777  * MERGE_BUFFER_SIZE workspace.
2778  *----------
2779  */
2780  mOrder = allowedMem /
2782 
2783  /*
2784  * Even in minimum memory, use at least a MINORDER merge. On the other
2785  * hand, even when we have lots of memory, do not use more than a MAXORDER
2786  * merge. Tapes are pretty cheap, but they're not entirely free. Each
2787  * additional tape reduces the amount of memory available to build runs,
2788  * which in turn can cause the same sort to need more runs, which makes
2789  * merging slower even if it can still be done in a single pass. Also,
2790  * high order merges are quite slow due to CPU cache effects; it can be
2791  * faster to pay the I/O cost of a multi-pass merge than to perform a
2792  * single merge pass across many hundreds of tapes.
2793  */
2794  mOrder = Max(mOrder, MINORDER);
2795  mOrder = Min(mOrder, MAXORDER);
2796 
2797  return mOrder;
2798 }
#define Min(x, y)
Definition: c.h:986
#define Max(x, y)
Definition: c.h:980
#define TAPE_BUFFER_OVERHEAD
Definition: tuplesort.c:236
#define MAXORDER
Definition: tuplesort.c:235
#define MERGE_BUFFER_SIZE
Definition: tuplesort.c:237
#define MINORDER
Definition: tuplesort.c:234

References Max, MAXORDER, MERGE_BUFFER_SIZE, Min, MINORDER, and TAPE_BUFFER_OVERHEAD.

Referenced by cost_tuplesort(), and inittapes().

◆ tuplesort_method_name()

const char* tuplesort_method_name ( TuplesortMethod  m)

Definition at line 3520 of file tuplesort.c.

3521 {
3522  switch (m)
3523  {
3525  return "still in progress";
3527  return "top-N heapsort";
3528  case SORT_TYPE_QUICKSORT:
3529  return "quicksort";
3531  return "external sort";
3533  return "external merge";
3534  }
3535 
3536  return "unknown";
3537 }

References SORT_TYPE_EXTERNAL_MERGE, SORT_TYPE_EXTERNAL_SORT, SORT_TYPE_QUICKSORT, SORT_TYPE_STILL_IN_PROGRESS, and SORT_TYPE_TOP_N_HEAPSORT.

Referenced by show_incremental_sort_group_info(), and show_sort_info().

◆ tuplesort_performsort()

void tuplesort_performsort ( Tuplesortstate state)

Definition at line 2196 of file tuplesort.c.

2197 {
2198  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2199 
2200 #ifdef TRACE_SORT
2201  if (trace_sort)
2202  elog(LOG, "performsort of worker %d starting: %s",
2203  state->worker, pg_rusage_show(&state->ru_start));
2204 #endif
2205 
2206  switch (state->status)
2207  {
2208  case TSS_INITIAL:
2209 
2210  /*
2211  * We were able to accumulate all the tuples within the allowed
2212  * amount of memory, or leader to take over worker tapes
2213  */
2214  if (SERIAL(state))
2215  {
2216  /* Just qsort 'em and we're done */
2218  state->status = TSS_SORTEDINMEM;
2219  }
2220  else if (WORKER(state))
2221  {
2222  /*
2223  * Parallel workers must still dump out tuples to tape. No
2224  * merge is required to produce single output run, though.
2225  */
2226  inittapes(state, false);
2227  dumptuples(state, true);
2229  state->status = TSS_SORTEDONTAPE;
2230  }
2231  else
2232  {
2233  /*
2234  * Leader will take over worker tapes and merge worker runs.
2235  * Note that mergeruns sets the correct state->status.
2236  */
2238  mergeruns(state);
2239  }
2240  state->current = 0;
2241  state->eof_reached = false;
2242  state->markpos_block = 0L;
2243  state->markpos_offset = 0;
2244  state->markpos_eof = false;
2245  break;
2246 
2247  case TSS_BOUNDED:
2248 
2249  /*
2250  * We were able to accumulate all the tuples required for output
2251  * in memory, using a heap to eliminate excess tuples. Now we
2252  * have to transform the heap to a properly-sorted array.
2253  */
2255  state->current = 0;
2256  state->eof_reached = false;
2257  state->markpos_offset = 0;
2258  state->markpos_eof = false;
2259  state->status = TSS_SORTEDINMEM;
2260  break;
2261 
2262  case TSS_BUILDRUNS:
2263 
2264  /*
2265  * Finish tape-based sort. First, flush all tuples remaining in
2266  * memory out to tape; then merge until we have a single remaining
2267  * run (or, if !randomAccess and !WORKER(), one run per tape).
2268  * Note that mergeruns sets the correct state->status.
2269  */
2270  dumptuples(state, true);
2271  mergeruns(state);
2272  state->eof_reached = false;
2273  state->markpos_block = 0L;
2274  state->markpos_offset = 0;
2275  state->markpos_eof = false;
2276  break;
2277 
2278  default:
2279  elog(ERROR, "invalid tuplesort state");
2280  break;
2281  }
2282 
2283 #ifdef TRACE_SORT
2284  if (trace_sort)
2285  {
2286  if (state->status == TSS_FINALMERGE)
2287  elog(LOG, "performsort of worker %d done (except %d-way final merge): %s",
2288  state->worker, state->nInputTapes,
2289  pg_rusage_show(&state->ru_start));
2290  else
2291  elog(LOG, "performsort of worker %d done: %s",
2292  state->worker, pg_rusage_show(&state->ru_start));
2293  }
2294 #endif
2295 
2296  MemoryContextSwitchTo(oldcontext);
2297 }
const char * pg_rusage_show(const PGRUsage *ru0)
Definition: pg_rusage.c:40
#define SERIAL(state)
Definition: tuplesort.c:558
static void sort_bounded_heap(Tuplesortstate *state)
Definition: tuplesort.c:3613
@ TSS_INITIAL
Definition: tuplesort.c:214
@ TSS_BUILDRUNS
Definition: tuplesort.c:216
@ TSS_BOUNDED
Definition: tuplesort.c:215
static void leader_takeover_tapes(Tuplesortstate *state)
Definition: tuplesort.c:4829
static void tuplesort_sort_memtuples(Tuplesortstate *state)
Definition: tuplesort.c:3653
static void inittapes(Tuplesortstate *state, bool mergeruns)
Definition: tuplesort.c:2842
#define WORKER(state)
Definition: tuplesort.c:559
static void worker_nomergeruns(Tuplesortstate *state)
Definition: tuplesort.c:4807
static void mergeruns(Tuplesortstate *state)
Definition: tuplesort.c:2996
static void dumptuples(Tuplesortstate *state, bool alltuples)
Definition: tuplesort.c:3288

References dumptuples(), elog, ERROR, inittapes(), leader_takeover_tapes(), LOG, MemoryContextSwitchTo(), mergeruns(), pg_rusage_show(), SERIAL, sort_bounded_heap(), trace_sort, TSS_BOUNDED, TSS_BUILDRUNS, TSS_FINALMERGE, TSS_INITIAL, TSS_SORTEDINMEM, TSS_SORTEDONTAPE, tuplesort_sort_memtuples(), WORKER, and worker_nomergeruns().

Referenced by _bt_leafbuild(), _bt_parallel_scan_and_sort(), _h_indexbuild(), ExecIncrementalSort(), ExecSort(), gistbuild(), heapam_relation_copy_for_cluster(), hypothetical_dense_rank_final(), hypothetical_rank_common(), initialize_phase(), mode_final(), percentile_cont_final_common(), percentile_cont_multi_final_common(), percentile_disc_final(), percentile_disc_multi_final(), process_ordered_aggregate_multi(), process_ordered_aggregate_single(), switchToPresortedPrefixMode(), and validate_index().

◆ tuplesort_putdatum()

void tuplesort_putdatum ( Tuplesortstate state,
Datum  val,
bool  isNull 
)

Definition at line 1961 of file tuplesort.c.

1962 {
1963  MemoryContext oldcontext = MemoryContextSwitchTo(state->tuplecontext);
1964  SortTuple stup;
1965 
1966  /*
1967  * Pass-by-value types or null values are just stored directly in
1968  * stup.datum1 (and stup.tuple is not used and set to NULL).
1969  *
1970  * Non-null pass-by-reference values need to be copied into memory we
1971  * control, and possibly abbreviated. The copied value is pointed to by
1972  * stup.tuple and is treated as the canonical copy (e.g. to return via
1973  * tuplesort_getdatum or when writing to tape); stup.datum1 gets the
1974  * abbreviated value if abbreviation is happening, otherwise it's
1975  * identical to stup.tuple.
1976  */
1977 
1978  if (isNull || !state->tuples)
1979  {
1980  /*
1981  * Set datum1 to zeroed representation for NULLs (to be consistent,
1982  * and to support cheap inequality tests for NULL abbreviated keys).
1983  */
1984  stup.datum1 = !isNull ? val : (Datum) 0;
1985  stup.isnull1 = isNull;
1986  stup.tuple = NULL; /* no separate storage */
1987  MemoryContextSwitchTo(state->sortcontext);
1988  }
1989  else
1990  {
1991  Datum original = datumCopy(val, false, state->datumTypeLen);
1992 
1993  stup.isnull1 = false;
1994  stup.tuple = DatumGetPointer(original);
1996  MemoryContextSwitchTo(state->sortcontext);
1997 
1998  if (!state->sortKeys->abbrev_converter)
1999  {
2000  stup.datum1 = original;
2001  }
2002  else if (!consider_abort_common(state))
2003  {
2004  /* Store abbreviated key representation */
2005  stup.datum1 = state->sortKeys->abbrev_converter(original,
2006  state->sortKeys);
2007  }
2008  else
2009  {
2010  /* Abort abbreviation */
2011  int i;
2012 
2013  stup.datum1 = original;
2014 
2015  /*
2016  * Set state to be consistent with never trying abbreviation.
2017  *
2018  * Alter datum1 representation in already-copied tuples, so as to
2019  * ensure a consistent representation (current tuple was just
2020  * handled). It does not matter if some dumped tuples are already
2021  * sorted on tape, since serialized tuples lack abbreviated keys
2022  * (TSS_BUILDRUNS state prevents control reaching here in any
2023  * case).
2024  */
2025  for (i = 0; i < state->memtupcount; i++)
2026  {
2027  SortTuple *mtup = &state->memtuples[i];
2028 
2029  mtup->datum1 = PointerGetDatum(mtup->tuple);
2030  }
2031  }
2032  }
2033 
2034  puttuple_common(state, &stup);
2035 
2036  MemoryContextSwitchTo(oldcontext);
2037 }
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:434
uintptr_t Datum
Definition: postgres.h:411
#define DatumGetPointer(X)
Definition: postgres.h:593
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple)
Definition: tuplesort.c:2043
#define USEMEM(state, amt)
Definition: tuplesort.c:556
static bool consider_abort_common(Tuplesortstate *state)
Definition: tuplesort.c:2152

References consider_abort_common(), SortTuple::datum1, datumCopy(), DatumGetPointer, GetMemoryChunkSpace(), i, SortTuple::isnull1, MemoryContextSwitchTo(), PointerGetDatum, puttuple_common(), SortTuple::tuple, USEMEM, and val.

Referenced by ExecEvalAggOrderedTransDatum(), ExecSort(), ordered_set_transition(), and validate_index_callback().

◆ tuplesort_putheaptuple()

void tuplesort_putheaptuple ( Tuplesortstate state,
HeapTuple  tup 
)

Definition at line 1862 of file tuplesort.c.

1863 {
1864  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1865  SortTuple stup;
1866 
1867  /*
1868  * Copy the given tuple into memory we control, and decrease availMem.
1869  * Then call the common code.
1870  */
1871  COPYTUP(state, &stup, (void *) tup);
1872 
1873  puttuple_common(state, &stup);
1874 
1875  MemoryContextSwitchTo(oldcontext);
1876 }
#define COPYTUP(state, stup, tup)
Definition: tuplesort.c:552

References COPYTUP, MemoryContextSwitchTo(), and puttuple_common().

Referenced by heapam_relation_copy_for_cluster().

◆ tuplesort_putindextuplevalues()

void tuplesort_putindextuplevalues ( Tuplesortstate state,
Relation  rel,
ItemPointer  self,
Datum values,
bool isnull 
)

Definition at line 1883 of file tuplesort.c.

1886 {
1887  MemoryContext oldcontext = MemoryContextSwitchTo(state->tuplecontext);
1888  SortTuple stup;
1889  Datum original;
1890  IndexTuple tuple;
1891 
1892  stup.tuple = index_form_tuple(RelationGetDescr(rel), values, isnull);
1893  tuple = ((IndexTuple) stup.tuple);
1894  tuple->t_tid = *self;
1896  /* set up first-column key value */
1897  original = index_getattr(tuple,
1898  1,
1899  RelationGetDescr(state->indexRel),
1900  &stup.isnull1);
1901 
1902  MemoryContextSwitchTo(state->sortcontext);
1903 
1904  if (!state->sortKeys || !state->sortKeys->abbrev_converter || stup.isnull1)
1905  {
1906  /*
1907  * Store ordinary Datum representation, or NULL value. If there is a
1908  * converter it won't expect NULL values, and cost model is not
1909  * required to account for NULL, so in that case we avoid calling
1910  * converter and just set datum1 to zeroed representation (to be
1911  * consistent, and to support cheap inequality tests for NULL
1912  * abbreviated keys).
1913  */
1914  stup.datum1 = original;
1915  }
1916  else if (!consider_abort_common(state))
1917  {
1918  /* Store abbreviated key representation */
1919  stup.datum1 = state->sortKeys->abbrev_converter(original,
1920  state->sortKeys);
1921  }
1922  else
1923  {
1924  /* Abort abbreviation */
1925  int i;
1926 
1927  stup.datum1 = original;
1928 
1929  /*
1930  * Set state to be consistent with never trying abbreviation.
1931  *
1932  * Alter datum1 representation in already-copied tuples, so as to
1933  * ensure a consistent representation (current tuple was just
1934  * handled). It does not matter if some dumped tuples are already
1935  * sorted on tape, since serialized tuples lack abbreviated keys
1936  * (TSS_BUILDRUNS state prevents control reaching here in any case).
1937  */
1938  for (i = 0; i < state->memtupcount; i++)
1939  {
1940  SortTuple *mtup = &state->memtuples[i];
1941 
1942  tuple = mtup->tuple;
1943  mtup->datum1 = index_getattr(tuple,
1944  1,
1945  RelationGetDescr(state->indexRel),
1946  &mtup->isnull1);
1947  }
1948  }
1949 
1950  puttuple_common(state, &stup);
1951 
1952  MemoryContextSwitchTo(oldcontext);
1953 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
IndexTuple index_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: indextuple.c:47
#define index_getattr(tup, attnum, tupleDesc, isnull)
Definition: itup.h:99
IndexTupleData * IndexTuple
Definition: itup.h:53
#define RelationGetDescr(relation)
Definition: rel.h:515
ItemPointerData t_tid
Definition: itup.h:37

References consider_abort_common(), SortTuple::datum1, GetMemoryChunkSpace(), i, index_form_tuple(), index_getattr, SortTuple::isnull1, MemoryContextSwitchTo(), puttuple_common(), RelationGetDescr, IndexTupleData::t_tid, SortTuple::tuple, USEMEM, and values.

Referenced by _bt_spool(), _h_spool(), and gistSortedBuildCallback().

◆ tuplesort_puttupleslot()

void tuplesort_puttupleslot ( Tuplesortstate state,
TupleTableSlot slot 
)

Definition at line 1840 of file tuplesort.c.

1841 {
1842  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1843  SortTuple stup;
1844 
1845  /*
1846  * Copy the given tuple into memory we control, and decrease availMem.
1847  * Then call the common code.
1848  */
1849  COPYTUP(state, &stup, (void *) slot);
1850 
1851  puttuple_common(state, &stup);
1852 
1853  MemoryContextSwitchTo(oldcontext);
1854 }

References COPYTUP, MemoryContextSwitchTo(), and puttuple_common().

Referenced by ExecEvalAggOrderedTransTuple(), ExecIncrementalSort(), ExecSort(), fetch_input_tuple(), hypothetical_dense_rank_final(), hypothetical_rank_common(), ordered_set_transition_multi(), and switchToPresortedPrefixMode().

◆ tuplesort_rescan()

void tuplesort_rescan ( Tuplesortstate state)

Definition at line 3379 of file tuplesort.c.

3380 {
3381  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3382 
3383  Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
3384 
3385  switch (state->status)
3386  {
3387  case TSS_SORTEDINMEM:
3388  state->current = 0;
3389  state->eof_reached = false;
3390  state->markpos_offset = 0;
3391  state->markpos_eof = false;
3392  break;
3393  case TSS_SORTEDONTAPE:
3394  LogicalTapeRewindForRead(state->result_tape, 0);
3395  state->eof_reached = false;
3396  state->markpos_block = 0L;
3397  state->markpos_offset = 0;
3398  state->markpos_eof = false;
3399  break;
3400  default:
3401  elog(ERROR, "invalid tuplesort state");
3402  break;
3403  }
3404 
3405  MemoryContextSwitchTo(oldcontext);
3406 }
void LogicalTapeRewindForRead(LogicalTape *lt, size_t buffer_size)
Definition: logtape.c:847

References Assert(), elog, ERROR, LogicalTapeRewindForRead(), MemoryContextSwitchTo(), TSS_SORTEDINMEM, TSS_SORTEDONTAPE, and TUPLESORT_RANDOMACCESS.

Referenced by ExecReScanSort(), mode_final(), percentile_cont_final_common(), percentile_cont_multi_final_common(), percentile_disc_final(), and percentile_disc_multi_final().

◆ tuplesort_reset()

void tuplesort_reset ( Tuplesortstate state)

Definition at line 1688 of file tuplesort.c.

1689 {
1692 
1693  /*
1694  * After we've freed up per-batch memory, re-setup all of the state common
1695  * to both the first batch and any subsequent batch.
1696  */
1698 
1699  state->lastReturnedTuple = NULL;
1700  state->slabMemoryBegin = NULL;
1701  state->slabMemoryEnd = NULL;
1702  state->slabFreeHead = NULL;
1703 }
static void tuplesort_begin_batch(Tuplesortstate *state)
Definition: tuplesort.c:956

References tuplesort_begin_batch(), tuplesort_free(), and tuplesort_updatemax().

Referenced by ExecIncrementalSort(), ExecReScanIncrementalSort(), and switchToPresortedPrefixMode().

◆ tuplesort_restorepos()

void tuplesort_restorepos ( Tuplesortstate state)

Definition at line 3443 of file tuplesort.c.

3444 {
3445  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3446 
3447  Assert(state->sortopt & TUPLESORT_RANDOMACCESS);
3448 
3449  switch (state->status)
3450  {
3451  case TSS_SORTEDINMEM:
3452  state->current = state->markpos_offset;
3453  state->eof_reached = state->markpos_eof;
3454  break;
3455  case TSS_SORTEDONTAPE:
3456  LogicalTapeSeek(state->result_tape,
3457  state->markpos_block,
3458  state->markpos_offset);
3459  state->eof_reached = state->markpos_eof;
3460  break;
3461  default:
3462  elog(ERROR, "invalid tuplesort state");
3463  break;
3464  }
3465 
3466  MemoryContextSwitchTo(oldcontext);
3467 }
void LogicalTapeSeek(LogicalTape *lt, long blocknum, int offset)
Definition: logtape.c:1134

References Assert(), elog, ERROR, LogicalTapeSeek(), MemoryContextSwitchTo(), TSS_SORTEDINMEM, TSS_SORTEDONTAPE, and TUPLESORT_RANDOMACCESS.

Referenced by ExecSortRestrPos().

◆ tuplesort_set_bound()

void tuplesort_set_bound ( Tuplesortstate state,
int64  bound 
)

Definition at line 1484 of file tuplesort.c.

1485 {
1486  /* Assert we're called before loading any tuples */
1487  Assert(state->status == TSS_INITIAL && state->memtupcount == 0);
1488  /* Assert we allow bounded sorts */
1489  Assert(state->sortopt & TUPLESORT_ALLOWBOUNDED);
1490  /* Can't set the bound twice, either */
1491  Assert(!state->bounded);
1492  /* Also, this shouldn't be called in a parallel worker */
1493  Assert(!WORKER(state));
1494 
1495  /* Parallel leader allows but ignores hint */
1496  if (LEADER(state))
1497  return;
1498 
1499 #ifdef DEBUG_BOUNDED_SORT
1500  /* Honor GUC setting that disables the feature (for easy testing) */
1501  if (!optimize_bounded_sort)
1502  return;
1503 #endif
1504 
1505  /* We want to be able to compute bound * 2, so limit the setting */
1506  if (bound > (int64) (INT_MAX / 2))
1507  return;
1508 
1509  state->bounded = true;
1510  state->bound = (int) bound;
1511 
1512  /*
1513  * Bounded sorts are not an effective target for abbreviated key
1514  * optimization. Disable by setting state to be consistent with no
1515  * abbreviation support.
1516  */
1517  state->sortKeys->abbrev_converter = NULL;
1518  if (state->sortKeys->abbrev_full_comparator)
1519  state->sortKeys->comparator = state->sortKeys->abbrev_full_comparator;
1520 
1521  /* Not strictly necessary, but be tidy */
1522  state->sortKeys->abbrev_abort = NULL;
1523  state->sortKeys->abbrev_full_comparator = NULL;
1524 }
#define LEADER(state)
Definition: tuplesort.c:560
#define TUPLESORT_ALLOWBOUNDED
Definition: tuplesort.h:96

References Assert(), LEADER, TSS_INITIAL, TUPLESORT_ALLOWBOUNDED, and WORKER.

Referenced by ExecIncrementalSort(), ExecSort(), and switchToPresortedPrefixMode().

◆ tuplesort_skiptuples()

bool tuplesort_skiptuples ( Tuplesortstate state,
int64  ntuples,
bool  forward 
)

Definition at line 2687 of file tuplesort.c.

2688 {
2689  MemoryContext oldcontext;
2690 
2691  /*
2692  * We don't actually support backwards skip yet, because no callers need
2693  * it. The API is designed to allow for that later, though.
2694  */
2695  Assert(forward);
2696  Assert(ntuples >= 0);
2697  Assert(!WORKER(state));
2698 
2699  switch (state->status)
2700  {
2701  case TSS_SORTEDINMEM:
2702  if (state->memtupcount - state->current >= ntuples)
2703  {
2704  state->current += ntuples;
2705  return true;
2706  }
2707  state->current = state->memtupcount;
2708  state->eof_reached = true;
2709 
2710  /*
2711  * Complain if caller tries to retrieve more tuples than
2712  * originally asked for in a bounded sort. This is because
2713  * returning EOF here might be the wrong thing.
2714  */
2715  if (state->bounded && state->current >= state->bound)
2716  elog(ERROR, "retrieved too many tuples in a bounded sort");
2717 
2718  return false;
2719 
2720  case TSS_SORTEDONTAPE:
2721  case TSS_FINALMERGE:
2722 
2723  /*
2724  * We could probably optimize these cases better, but for now it's
2725  * not worth the trouble.
2726  */
2727  oldcontext = MemoryContextSwitchTo(state->sortcontext);
2728  while (ntuples-- > 0)
2729  {
2730  SortTuple stup;
2731 
2732  if (!tuplesort_gettuple_common(state, forward, &stup))
2733  {
2734  MemoryContextSwitchTo(oldcontext);
2735  return false;
2736  }
2738  }
2739  MemoryContextSwitchTo(oldcontext);
2740  return true;
2741 
2742  default:
2743  elog(ERROR, "invalid tuplesort state");
2744  return false; /* keep compiler quiet */
2745  }
2746 }
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121

References Assert(), CHECK_FOR_INTERRUPTS, elog, ERROR, MemoryContextSwitchTo(), TSS_FINALMERGE, TSS_SORTEDINMEM, TSS_SORTEDONTAPE, tuplesort_gettuple_common(), and WORKER.

Referenced by percentile_cont_final_common(), percentile_cont_multi_final_common(), percentile_disc_final(), and percentile_disc_multi_final().

◆ tuplesort_space_type_name()

const char* tuplesort_space_type_name ( TuplesortSpaceType  t)

Definition at line 3543 of file tuplesort.c.

3544 {
3546  return t == SORT_SPACE_TYPE_DISK ? "Disk" : "Memory";
3547 }

References Assert(), SORT_SPACE_TYPE_DISK, and SORT_SPACE_TYPE_MEMORY.

Referenced by show_incremental_sort_group_info(), and show_sort_info().

◆ tuplesort_used_bound()

bool tuplesort_used_bound ( Tuplesortstate state)

Definition at line 1532 of file tuplesort.c.

1533 {
1534  return state->boundUsed;
1535 }

Referenced by ExecIncrementalSort().