PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tuplesort.h File Reference
#include "access/itup.h"
#include "executor/tuptable.h"
#include "fmgr.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.

Typedefs

typedef struct Tuplesortstate Tuplesortstate
 

Functions

Tuplesortstatetuplesort_begin_heap (TupleDesc tupDesc, int nkeys, AttrNumber *attNums, Oid *sortOperators, Oid *sortCollations, bool *nullsFirstFlags, int workMem, bool randomAccess)
 
Tuplesortstatetuplesort_begin_cluster (TupleDesc tupDesc, Relation indexRel, int workMem, bool randomAccess)
 
Tuplesortstatetuplesort_begin_index_btree (Relation heapRel, Relation indexRel, bool enforceUnique, int workMem, bool randomAccess)
 
Tuplesortstatetuplesort_begin_index_hash (Relation heapRel, Relation indexRel, uint32 high_mask, uint32 low_mask, uint32 max_buckets, int workMem, bool randomAccess)
 
Tuplesortstatetuplesort_begin_datum (Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, bool randomAccess)
 
void tuplesort_set_bound (Tuplesortstate *state, int64 bound)
 
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_get_stats (Tuplesortstate *state, const char **sortMethod, const char **spaceType, long *spaceUsed)
 
int tuplesort_merge_order (int64 allowedMem)
 
void tuplesort_rescan (Tuplesortstate *state)
 
void tuplesort_markpos (Tuplesortstate *state)
 
void tuplesort_restorepos (Tuplesortstate *state)
 

Typedef Documentation

Definition at line 32 of file tuplesort.h.

Function Documentation

Tuplesortstate* tuplesort_begin_cluster ( TupleDesc  tupDesc,
Relation  indexRel,
int  workMem,
bool  randomAccess 
)

Definition at line 828 of file tuplesort.c.

References _bt_freeskey(), _bt_mkscankey_nodata(), SortSupportData::abbreviate, Tuplesortstate::abbrevNext, Assert, AssertState, BTGreaterStrategyNumber, BTLessStrategyNumber, BTREE_AM_OID, BuildIndexInfo(), CLUSTER_SORT, Tuplesortstate::comparetup, comparetup_cluster(), Tuplesortstate::copytup, copytup_cluster(), CreateExecutorState(), CurrentMemoryContext, ExprContext::ecxt_scantuple, elog, Tuplesortstate::estate, GetPerTupleExprContext, i, IndexInfo::ii_Expressions, Tuplesortstate::indexInfo, LOG, MakeSingleTupleTableSlot(), MemoryContextSwitchTo(), Tuplesortstate::nKeys, NULL, palloc0(), PrepareSortSupportFromIndexRel(), RelationData::rd_rel, Tuplesortstate::readtup, readtup_cluster(), RelationGetNumberOfAttributes, ScanKeyData::sk_attno, SK_BT_DESC, SK_BT_NULLS_FIRST, ScanKeyData::sk_collation, ScanKeyData::sk_flags, Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, Tuplesortstate::tupDesc, tuplesort_begin_common(), Tuplesortstate::writetup, and writetup_cluster().

Referenced by copy_heap_data().

831 {
832  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
833  ScanKey indexScanKey;
834  MemoryContext oldcontext;
835  int i;
836 
837  Assert(indexRel->rd_rel->relam == BTREE_AM_OID);
838 
839  oldcontext = MemoryContextSwitchTo(state->sortcontext);
840 
841 #ifdef TRACE_SORT
842  if (trace_sort)
843  elog(LOG,
844  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
846  workMem, randomAccess ? 't' : 'f');
847 #endif
848 
849  state->nKeys = RelationGetNumberOfAttributes(indexRel);
850 
851  TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
852  false, /* no unique check */
853  state->nKeys,
854  workMem,
855  randomAccess);
856 
858  state->copytup = copytup_cluster;
859  state->writetup = writetup_cluster;
860  state->readtup = readtup_cluster;
861  state->abbrevNext = 10;
862 
863  state->indexInfo = BuildIndexInfo(indexRel);
864 
865  state->tupDesc = tupDesc; /* assume we need not copy tupDesc */
866 
867  indexScanKey = _bt_mkscankey_nodata(indexRel);
868 
869  if (state->indexInfo->ii_Expressions != NULL)
870  {
871  TupleTableSlot *slot;
872  ExprContext *econtext;
873 
874  /*
875  * We will need to use FormIndexDatum to evaluate the index
876  * expressions. To do that, we need an EState, as well as a
877  * TupleTableSlot to put the table tuples into. The econtext's
878  * scantuple has to point to that slot, too.
879  */
880  state->estate = CreateExecutorState();
881  slot = MakeSingleTupleTableSlot(tupDesc);
882  econtext = GetPerTupleExprContext(state->estate);
883  econtext->ecxt_scantuple = slot;
884  }
885 
886  /* Prepare SortSupport data for each column */
887  state->sortKeys = (SortSupport) palloc0(state->nKeys *
888  sizeof(SortSupportData));
889 
890  for (i = 0; i < state->nKeys; i++)
891  {
892  SortSupport sortKey = state->sortKeys + i;
893  ScanKey scanKey = indexScanKey + i;
894  int16 strategy;
895 
896  sortKey->ssup_cxt = CurrentMemoryContext;
897  sortKey->ssup_collation = scanKey->sk_collation;
898  sortKey->ssup_nulls_first =
899  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
900  sortKey->ssup_attno = scanKey->sk_attno;
901  /* Convey if abbreviation optimization is applicable in principle */
902  sortKey->abbreviate = (i == 0);
903 
904  AssertState(sortKey->ssup_attno != 0);
905 
906  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
908 
909  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
910  }
911 
912  _bt_freeskey(indexScanKey);
913 
914  MemoryContextSwitchTo(oldcontext);
915 
916  return state;
917 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
signed short int16
Definition: c.h:255
bool ssup_nulls_first
Definition: sortsupport.h:75
ScanKey _bt_mkscankey_nodata(Relation rel)
Definition: nbtutils.c:115
static void writetup_cluster(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:3982
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define AssertState(condition)
Definition: c.h:678
int64 abbrevNext
Definition: tuplesort.c:456
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
EState * estate
Definition: tuplesort.c:464
SortSupport sortKeys
Definition: tuplesort.c:442
void _bt_freeskey(ScanKey skey)
Definition: nbtutils.c:155
#define BTREE_AM_OID
Definition: pg_am.h:70
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:298
#define CLUSTER_SORT
Definition: tuplesort.c:151
static int comparetup_cluster(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:3798
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:1640
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:316
#define LOG
Definition: elog.h:26
Form_pg_class rd_rel
Definition: rel.h:114
static void copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:3909
bool trace_sort
Definition: tuplesort.c:155
#define GetPerTupleExprContext(estate)
Definition: executor.h:456
static void readtup_cluster(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:4006
MemoryContext sortcontext
Definition: tuplesort.c:285
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:324
IndexInfo * indexInfo
Definition: tuplesort.c:463
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, SortSupport ssup)
Definition: sortsupport.c:160
EState * CreateExecutorState(void)
Definition: execUtils.c:80
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:428
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:306
void * palloc0(Size size)
Definition: mcxt.c:878
AttrNumber ssup_attno
Definition: sortsupport.h:81
int sk_flags
Definition: skey.h:66
#define NULL
Definition: c.h:229
List * ii_Expressions
Definition: execnodes.h:136
#define Assert(condition)
Definition: c.h:675
#define SK_BT_DESC
Definition: nbtree.h:427
Definition: regguts.h:298
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:197
Oid sk_collation
Definition: skey.h:70
int i
#define elog
Definition: elog.h:219
static Tuplesortstate * tuplesort_begin_common(int workMem, bool randomAccess)
Definition: tuplesort.c:670
#define BTLessStrategyNumber
Definition: stratnum.h:29
AttrNumber sk_attno
Definition: skey.h:67
TupleDesc tupDesc
Definition: tuplesort.c:441
Tuplesortstate* tuplesort_begin_datum ( Oid  datumType,
Oid  sortOperator,
Oid  sortCollation,
bool  nullsFirstFlag,
int  workMem,
bool  randomAccess 
)

Definition at line 1038 of file tuplesort.c.

References SortSupportData::abbrev_converter, SortSupportData::abbreviate, Tuplesortstate::abbrevNext, Tuplesortstate::comparetup, comparetup_datum(), Tuplesortstate::copytup, copytup_datum(), CurrentMemoryContext, DATUM_SORT, Tuplesortstate::datumType, Tuplesortstate::datumTypeLen, elog, get_typlenbyval(), LOG, MemoryContextSwitchTo(), Tuplesortstate::nKeys, Tuplesortstate::onlyKey, palloc0(), PrepareSortSupportFromOrderingOp(), Tuplesortstate::readtup, readtup_datum(), Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, Tuplesortstate::tuples, tuplesort_begin_common(), Tuplesortstate::writetup, and writetup_datum().

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

1041 {
1042  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
1043  MemoryContext oldcontext;
1044  int16 typlen;
1045  bool typbyval;
1046 
1047  oldcontext = MemoryContextSwitchTo(state->sortcontext);
1048 
1049 #ifdef TRACE_SORT
1050  if (trace_sort)
1051  elog(LOG,
1052  "begin datum sort: workMem = %d, randomAccess = %c",
1053  workMem, randomAccess ? 't' : 'f');
1054 #endif
1055 
1056  state->nKeys = 1; /* always a one-column sort */
1057 
1058  TRACE_POSTGRESQL_SORT_START(DATUM_SORT,
1059  false, /* no unique check */
1060  1,
1061  workMem,
1062  randomAccess);
1063 
1064  state->comparetup = comparetup_datum;
1065  state->copytup = copytup_datum;
1066  state->writetup = writetup_datum;
1067  state->readtup = readtup_datum;
1068  state->abbrevNext = 10;
1069 
1070  state->datumType = datumType;
1071 
1072  /* lookup necessary attributes of the datum type */
1073  get_typlenbyval(datumType, &typlen, &typbyval);
1074  state->datumTypeLen = typlen;
1075  state->tuples = !typbyval;
1076 
1077  /* Prepare SortSupport data */
1078  state->sortKeys = (SortSupport) palloc0(sizeof(SortSupportData));
1079 
1081  state->sortKeys->ssup_collation = sortCollation;
1082  state->sortKeys->ssup_nulls_first = nullsFirstFlag;
1083 
1084  /*
1085  * Abbreviation is possible here only for by-reference types. In theory,
1086  * a pass-by-value datatype could have an abbreviated form that is cheaper
1087  * to compare. In a tuple sort, we could support that, because we can
1088  * always extract the original datum from the tuple is needed. Here, we
1089  * can't, because a datum sort only stores a single copy of the datum; the
1090  * "tuple" field of each sortTuple is NULL.
1091  */
1092  state->sortKeys->abbreviate = !typbyval;
1093 
1094  PrepareSortSupportFromOrderingOp(sortOperator, state->sortKeys);
1095 
1096  /*
1097  * The "onlyKey" optimization cannot be used with abbreviated keys, since
1098  * tie-breaker comparisons may be required. Typically, the optimization
1099  * is only of value to pass-by-value types anyway, whereas abbreviated
1100  * keys are typically only of value to pass-by-reference types.
1101  */
1102  if (!state->sortKeys->abbrev_converter)
1103  state->onlyKey = state->sortKeys;
1104 
1105  MemoryContextSwitchTo(oldcontext);
1106 
1107  return state;
1108 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
signed short int16
Definition: c.h:255
bool ssup_nulls_first
Definition: sortsupport.h:75
int64 abbrevNext
Definition: tuplesort.c:456
SortSupport sortKeys
Definition: tuplesort.c:442
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:133
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:298
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:316
#define LOG
Definition: elog.h:26
bool trace_sort
Definition: tuplesort.c:155
#define DATUM_SORT
Definition: tuplesort.c:150
MemoryContext sortcontext
Definition: tuplesort.c:285
MemoryContext ssup_cxt
Definition: sortsupport.h:66
static int comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4337
static void copytup_datum(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4358
static void readtup_datum(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:4406
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:324
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
static void writetup_datum(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:4365
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:306
void * palloc0(Size size)
Definition: mcxt.c:878
Definition: regguts.h:298
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2001
SortSupport onlyKey
Definition: tuplesort.c:448
#define elog
Definition: elog.h:219
static Tuplesortstate * tuplesort_begin_common(int workMem, bool randomAccess)
Definition: tuplesort.c:670
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
Tuplesortstate* tuplesort_begin_heap ( TupleDesc  tupDesc,
int  nkeys,
AttrNumber attNums,
Oid sortOperators,
Oid sortCollations,
bool nullsFirstFlags,
int  workMem,
bool  randomAccess 
)

Definition at line 756 of file tuplesort.c.

References SortSupportData::abbrev_converter, SortSupportData::abbreviate, Tuplesortstate::abbrevNext, AssertArg, Tuplesortstate::comparetup, comparetup_heap(), Tuplesortstate::copytup, copytup_heap(), CurrentMemoryContext, elog, HEAP_SORT, i, LOG, MemoryContextSwitchTo(), Tuplesortstate::nKeys, Tuplesortstate::onlyKey, palloc0(), PrepareSortSupportFromOrderingOp(), Tuplesortstate::readtup, readtup_heap(), Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, Tuplesortstate::tupDesc, tuplesort_begin_common(), Tuplesortstate::writetup, and writetup_heap().

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

761 {
762  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
763  MemoryContext oldcontext;
764  int i;
765 
766  oldcontext = MemoryContextSwitchTo(state->sortcontext);
767 
768  AssertArg(nkeys > 0);
769 
770 #ifdef TRACE_SORT
771  if (trace_sort)
772  elog(LOG,
773  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
774  nkeys, workMem, randomAccess ? 't' : 'f');
775 #endif
776 
777  state->nKeys = nkeys;
778 
779  TRACE_POSTGRESQL_SORT_START(HEAP_SORT,
780  false, /* no unique check */
781  nkeys,
782  workMem,
783  randomAccess);
784 
785  state->comparetup = comparetup_heap;
786  state->copytup = copytup_heap;
787  state->writetup = writetup_heap;
788  state->readtup = readtup_heap;
789 
790  state->tupDesc = tupDesc; /* assume we need not copy tupDesc */
791  state->abbrevNext = 10;
792 
793  /* Prepare SortSupport data for each column */
794  state->sortKeys = (SortSupport) palloc0(nkeys * sizeof(SortSupportData));
795 
796  for (i = 0; i < nkeys; i++)
797  {
798  SortSupport sortKey = state->sortKeys + i;
799 
800  AssertArg(attNums[i] != 0);
801  AssertArg(sortOperators[i] != 0);
802 
803  sortKey->ssup_cxt = CurrentMemoryContext;
804  sortKey->ssup_collation = sortCollations[i];
805  sortKey->ssup_nulls_first = nullsFirstFlags[i];
806  sortKey->ssup_attno = attNums[i];
807  /* Convey if abbreviation optimization is applicable in principle */
808  sortKey->abbreviate = (i == 0);
809 
810  PrepareSortSupportFromOrderingOp(sortOperators[i], sortKey);
811  }
812 
813  /*
814  * The "onlyKey" optimization cannot be used with abbreviated keys, since
815  * tie-breaker comparisons may be required. Typically, the optimization
816  * is only of value to pass-by-value types anyway, whereas abbreviated
817  * keys are typically only of value to pass-by-reference types.
818  */
819  if (nkeys == 1 && !state->sortKeys->abbrev_converter)
820  state->onlyKey = state->sortKeys;
821 
822  MemoryContextSwitchTo(oldcontext);
823 
824  return state;
825 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
bool ssup_nulls_first
Definition: sortsupport.h:75
static int comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:3599
int64 abbrevNext
Definition: tuplesort.c:456
SortSupport sortKeys
Definition: tuplesort.c:442
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:133
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:298
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:316
#define LOG
Definition: elog.h:26
#define HEAP_SORT
Definition: tuplesort.c:148
bool trace_sort
Definition: tuplesort.c:155
MemoryContext sortcontext
Definition: tuplesort.c:285
static void writetup_heap(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:3739
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:324
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define AssertArg(condition)
Definition: c.h:677
static void copytup_heap(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:3661
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:306
void * palloc0(Size size)
Definition: mcxt.c:878
AttrNumber ssup_attno
Definition: sortsupport.h:81
Definition: regguts.h:298
static void readtup_heap(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:3766
int i
SortSupport onlyKey
Definition: tuplesort.c:448
#define elog
Definition: elog.h:219
static Tuplesortstate * tuplesort_begin_common(int workMem, bool randomAccess)
Definition: tuplesort.c:670
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
TupleDesc tupDesc
Definition: tuplesort.c:441
Tuplesortstate* tuplesort_begin_index_btree ( Relation  heapRel,
Relation  indexRel,
bool  enforceUnique,
int  workMem,
bool  randomAccess 
)

Definition at line 920 of file tuplesort.c.

References _bt_freeskey(), _bt_mkscankey_nodata(), SortSupportData::abbreviate, Tuplesortstate::abbrevNext, AssertState, BTGreaterStrategyNumber, BTLessStrategyNumber, Tuplesortstate::comparetup, comparetup_index_btree(), Tuplesortstate::copytup, copytup_index(), CurrentMemoryContext, elog, Tuplesortstate::enforceUnique, Tuplesortstate::heapRel, i, INDEX_SORT, Tuplesortstate::indexRel, LOG, MemoryContextSwitchTo(), Tuplesortstate::nKeys, palloc0(), PrepareSortSupportFromIndexRel(), Tuplesortstate::readtup, readtup_index(), RelationGetNumberOfAttributes, ScanKeyData::sk_attno, SK_BT_DESC, SK_BT_NULLS_FIRST, ScanKeyData::sk_collation, ScanKeyData::sk_flags, Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, tuplesort_begin_common(), Tuplesortstate::writetup, and writetup_index().

Referenced by _bt_spoolinit().

924 {
925  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
926  ScanKey indexScanKey;
927  MemoryContext oldcontext;
928  int i;
929 
930  oldcontext = MemoryContextSwitchTo(state->sortcontext);
931 
932 #ifdef TRACE_SORT
933  if (trace_sort)
934  elog(LOG,
935  "begin index sort: unique = %c, workMem = %d, randomAccess = %c",
936  enforceUnique ? 't' : 'f',
937  workMem, randomAccess ? 't' : 'f');
938 #endif
939 
940  state->nKeys = RelationGetNumberOfAttributes(indexRel);
941 
942  TRACE_POSTGRESQL_SORT_START(INDEX_SORT,
943  enforceUnique,
944  state->nKeys,
945  workMem,
946  randomAccess);
947 
949  state->copytup = copytup_index;
950  state->writetup = writetup_index;
951  state->readtup = readtup_index;
952  state->abbrevNext = 10;
953 
954  state->heapRel = heapRel;
955  state->indexRel = indexRel;
956  state->enforceUnique = enforceUnique;
957 
958  indexScanKey = _bt_mkscankey_nodata(indexRel);
959  state->nKeys = RelationGetNumberOfAttributes(indexRel);
960 
961  /* Prepare SortSupport data for each column */
962  state->sortKeys = (SortSupport) palloc0(state->nKeys *
963  sizeof(SortSupportData));
964 
965  for (i = 0; i < state->nKeys; i++)
966  {
967  SortSupport sortKey = state->sortKeys + i;
968  ScanKey scanKey = indexScanKey + i;
969  int16 strategy;
970 
971  sortKey->ssup_cxt = CurrentMemoryContext;
972  sortKey->ssup_collation = scanKey->sk_collation;
973  sortKey->ssup_nulls_first =
974  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
975  sortKey->ssup_attno = scanKey->sk_attno;
976  /* Convey if abbreviation optimization is applicable in principle */
977  sortKey->abbreviate = (i == 0);
978 
979  AssertState(sortKey->ssup_attno != 0);
980 
981  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
983 
984  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
985  }
986 
987  _bt_freeskey(indexScanKey);
988 
989  MemoryContextSwitchTo(oldcontext);
990 
991  return state;
992 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
signed short int16
Definition: c.h:255
bool ssup_nulls_first
Definition: sortsupport.h:75
ScanKey _bt_mkscankey_nodata(Relation rel)
Definition: nbtutils.c:115
Relation heapRel
Definition: tuplesort.c:470
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define AssertState(condition)
Definition: c.h:678
int64 abbrevNext
Definition: tuplesort.c:456
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
static void copytup_index(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4225
SortSupport sortKeys
Definition: tuplesort.c:442
void _bt_freeskey(ScanKey skey)
Definition: nbtutils.c:155
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:298
#define INDEX_SORT
Definition: tuplesort.c:149
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:316
#define LOG
Definition: elog.h:26
static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4044
bool trace_sort
Definition: tuplesort.c:155
MemoryContext sortcontext
Definition: tuplesort.c:285
static void writetup_index(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:4291
MemoryContext ssup_cxt
Definition: sortsupport.h:66
static void readtup_index(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:4313
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:324
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, SortSupport ssup)
Definition: sortsupport.c:160
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:428
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:306
void * palloc0(Size size)
Definition: mcxt.c:878
Relation indexRel
Definition: tuplesort.c:471
AttrNumber ssup_attno
Definition: sortsupport.h:81
int sk_flags
Definition: skey.h:66
#define SK_BT_DESC
Definition: nbtree.h:427
Definition: regguts.h:298
bool enforceUnique
Definition: tuplesort.c:474
Oid sk_collation
Definition: skey.h:70
int i
#define elog
Definition: elog.h:219
static Tuplesortstate * tuplesort_begin_common(int workMem, bool randomAccess)
Definition: tuplesort.c:670
#define BTLessStrategyNumber
Definition: stratnum.h:29
AttrNumber sk_attno
Definition: skey.h:67
Tuplesortstate* tuplesort_begin_index_hash ( Relation  heapRel,
Relation  indexRel,
uint32  high_mask,
uint32  low_mask,
uint32  max_buckets,
int  workMem,
bool  randomAccess 
)

Definition at line 995 of file tuplesort.c.

References Tuplesortstate::comparetup, comparetup_index_hash(), Tuplesortstate::copytup, copytup_index(), elog, Tuplesortstate::heapRel, Tuplesortstate::high_mask, Tuplesortstate::indexRel, LOG, Tuplesortstate::low_mask, Tuplesortstate::max_buckets, MemoryContextSwitchTo(), Tuplesortstate::nKeys, Tuplesortstate::readtup, readtup_index(), Tuplesortstate::sortcontext, trace_sort, tuplesort_begin_common(), Tuplesortstate::writetup, and writetup_index().

Referenced by _h_spoolinit().

1001 {
1002  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
1003  MemoryContext oldcontext;
1004 
1005  oldcontext = MemoryContextSwitchTo(state->sortcontext);
1006 
1007 #ifdef TRACE_SORT
1008  if (trace_sort)
1009  elog(LOG,
1010  "begin index sort: high_mask = 0x%x, low_mask = 0x%x, "
1011  "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
1012  high_mask,
1013  low_mask,
1014  max_buckets,
1015  workMem, randomAccess ? 't' : 'f');
1016 #endif
1017 
1018  state->nKeys = 1; /* Only one sort column, the hash code */
1019 
1021  state->copytup = copytup_index;
1022  state->writetup = writetup_index;
1023  state->readtup = readtup_index;
1024 
1025  state->heapRel = heapRel;
1026  state->indexRel = indexRel;
1027 
1028  state->high_mask = high_mask;
1029  state->low_mask = low_mask;
1030  state->max_buckets = max_buckets;
1031 
1032  MemoryContextSwitchTo(oldcontext);
1033 
1034  return state;
1035 }
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4173
Relation heapRel
Definition: tuplesort.c:470
static void copytup_index(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4225
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:298
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:316
#define LOG
Definition: elog.h:26
bool trace_sort
Definition: tuplesort.c:155
MemoryContext sortcontext
Definition: tuplesort.c:285
static void writetup_index(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:4291
uint32 high_mask
Definition: tuplesort.c:477
static void readtup_index(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:4313
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:324
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:306
Relation indexRel
Definition: tuplesort.c:471
Definition: regguts.h:298
uint32 max_buckets
Definition: tuplesort.c:479
uint32 low_mask
Definition: tuplesort.c:478
#define elog
Definition: elog.h:219
static Tuplesortstate * tuplesort_begin_common(int workMem, bool randomAccess)
Definition: tuplesort.c:670
void tuplesort_end ( Tuplesortstate state)

Definition at line 1167 of file tuplesort.c.

References Tuplesortstate::allowedMem, Tuplesortstate::availMem, ExprContext::ecxt_scantuple, elog, Tuplesortstate::estate, ExecDropSingleTupleTableSlot(), FreeExecutorState(), GetPerTupleExprContext, LOG, LogicalTapeSetBlocks(), LogicalTapeSetClose(), MemoryContextDelete(), MemoryContextSwitchTo(), NULL, pg_rusage_show(), Tuplesortstate::ru_start, Tuplesortstate::sortcontext, Tuplesortstate::tapeset, and trace_sort.

Referenced by _bt_spooldestroy(), _h_spooldestroy(), copy_heap_data(), ExecEndAgg(), ExecEndSort(), ExecReScanAgg(), ExecReScanSort(), hypothetical_dense_rank_final(), hypothetical_rank_common(), initialize_aggregate(), initialize_phase(), ordered_set_shutdown(), process_ordered_aggregate_multi(), process_ordered_aggregate_single(), and validate_index().

1168 {
1169  /* context swap probably not needed, but let's be safe */
1170  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1171 
1172 #ifdef TRACE_SORT
1173  long spaceUsed;
1174 
1175  if (state->tapeset)
1176  spaceUsed = LogicalTapeSetBlocks(state->tapeset);
1177  else
1178  spaceUsed = (state->allowedMem - state->availMem + 1023) / 1024;
1179 #endif
1180 
1181  /*
1182  * Delete temporary "tape" files, if any.
1183  *
1184  * Note: want to include this in reported total cost of sort, hence need
1185  * for two #ifdef TRACE_SORT sections.
1186  */
1187  if (state->tapeset)
1188  LogicalTapeSetClose(state->tapeset);
1189 
1190 #ifdef TRACE_SORT
1191  if (trace_sort)
1192  {
1193  if (state->tapeset)
1194  elog(LOG, "external sort ended, %ld disk blocks used: %s",
1195  spaceUsed, pg_rusage_show(&state->ru_start));
1196  else
1197  elog(LOG, "internal sort ended, %ld KB used: %s",
1198  spaceUsed, pg_rusage_show(&state->ru_start));
1199  }
1200 
1201  TRACE_POSTGRESQL_SORT_DONE(state->tapeset != NULL, spaceUsed);
1202 #else
1203 
1204  /*
1205  * If you disabled TRACE_SORT, you can still probe sort__done, but you
1206  * ain't getting space-used stats.
1207  */
1208  TRACE_POSTGRESQL_SORT_DONE(state->tapeset != NULL, 0L);
1209 #endif
1210 
1211  /* Free any execution state created for CLUSTER case */
1212  if (state->estate != NULL)
1213  {
1214  ExprContext *econtext = GetPerTupleExprContext(state->estate);
1215 
1217  FreeExecutorState(state->estate);
1218  }
1219 
1220  MemoryContextSwitchTo(oldcontext);
1221 
1222  /*
1223  * Free the per-sort memory context, thereby releasing all working memory,
1224  * including the Tuplesortstate struct itself.
1225  */
1227 }
int64 availMem
Definition: tuplesort.c:281
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
PGRUsage ru_start
Definition: tuplesort.c:493
EState * estate
Definition: tuplesort.c:464
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define LOG
Definition: elog.h:26
bool trace_sort
Definition: tuplesort.c:155
void FreeExecutorState(EState *estate)
Definition: execUtils.c:178
#define GetPerTupleExprContext(estate)
Definition: executor.h:456
MemoryContext sortcontext
Definition: tuplesort.c:285
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:216
const char * pg_rusage_show(const PGRUsage *ru0)
Definition: pg_rusage.c:40
LogicalTapeSet * tapeset
Definition: tuplesort.c:287
int64 allowedMem
Definition: tuplesort.c:282
#define NULL
Definition: c.h:229
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:197
void LogicalTapeSetClose(LogicalTapeSet *lts)
Definition: logtape.c:427
#define elog
Definition: elog.h:219
long LogicalTapeSetBlocks(LogicalTapeSet *lts)
Definition: logtape.c:889
void tuplesort_get_stats ( Tuplesortstate state,
const char **  sortMethod,
const char **  spaceType,
long *  spaceUsed 
)

Definition at line 3233 of file tuplesort.c.

References Tuplesortstate::allowedMem, Tuplesortstate::availMem, Tuplesortstate::boundUsed, LogicalTapeSetBlocks(), Tuplesortstate::status, Tuplesortstate::tapeset, TSS_FINALMERGE, TSS_SORTEDINMEM, and TSS_SORTEDONTAPE.

Referenced by show_sort_info().

3237 {
3238  /*
3239  * Note: it might seem we should provide both memory and disk usage for a
3240  * disk-based sort. However, the current code doesn't track memory space
3241  * accurately once we have begun to return tuples to the caller (since we
3242  * don't account for pfree's the caller is expected to do), so we cannot
3243  * rely on availMem in a disk sort. This does not seem worth the overhead
3244  * to fix. Is it worth creating an API for the memory context code to
3245  * tell us how much is actually used in sortcontext?
3246  */
3247  if (state->tapeset)
3248  {
3249  *spaceType = "Disk";
3250  *spaceUsed = LogicalTapeSetBlocks(state->tapeset) * (BLCKSZ / 1024);
3251  }
3252  else
3253  {
3254  *spaceType = "Memory";
3255  *spaceUsed = (state->allowedMem - state->availMem + 1023) / 1024;
3256  }
3257 
3258  switch (state->status)
3259  {
3260  case TSS_SORTEDINMEM:
3261  if (state->boundUsed)
3262  *sortMethod = "top-N heapsort";
3263  else
3264  *sortMethod = "quicksort";
3265  break;
3266  case TSS_SORTEDONTAPE:
3267  *sortMethod = "external sort";
3268  break;
3269  case TSS_FINALMERGE:
3270  *sortMethod = "external merge";
3271  break;
3272  default:
3273  *sortMethod = "still in progress";
3274  break;
3275  }
3276 }
int64 availMem
Definition: tuplesort.c:281
TupSortStatus status
Definition: tuplesort.c:273
LogicalTapeSet * tapeset
Definition: tuplesort.c:287
int64 allowedMem
Definition: tuplesort.c:282
long LogicalTapeSetBlocks(LogicalTapeSet *lts)
Definition: logtape.c:889
bool tuplesort_getdatum ( Tuplesortstate state,
bool  forward,
Datum val,
bool isNull,
Datum abbrev 
)

Definition at line 2199 of file tuplesort.c.

References SortSupportData::abbrev_converter, SortTuple::datum1, datumCopy(), Tuplesortstate::datumTypeLen, SortTuple::isnull1, MemoryContextSwitchTo(), PointerGetDatum, Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, SortTuple::tuple, Tuplesortstate::tuples, and tuplesort_gettuple_common().

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

2201 {
2202  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2203  SortTuple stup;
2204 
2205  if (!tuplesort_gettuple_common(state, forward, &stup))
2206  {
2207  MemoryContextSwitchTo(oldcontext);
2208  return false;
2209  }
2210 
2211  /* Record abbreviated key for caller */
2212  if (state->sortKeys->abbrev_converter && abbrev)
2213  *abbrev = stup.datum1;
2214 
2215  if (stup.isnull1 || !state->tuples)
2216  {
2217  *val = stup.datum1;
2218  *isNull = stup.isnull1;
2219  }
2220  else
2221  {
2222  /* use stup.tuple because stup.datum1 may be an abbreviation */
2223  *val = datumCopy(PointerGetDatum(stup.tuple), false, state->datumTypeLen);
2224  *isNull = false;
2225  }
2226 
2227  MemoryContextSwitchTo(oldcontext);
2228 
2229  return true;
2230 }
#define PointerGetDatum(X)
Definition: postgres.h:562
SortSupport sortKeys
Definition: tuplesort.c:442
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum datum1
Definition: tuplesort.c:202
bool isnull1
Definition: tuplesort.c:203
void * tuple
Definition: tuplesort.c:201
MemoryContext sortcontext
Definition: tuplesort.c:285
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1859
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:128
long val
Definition: informix.c:689
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
HeapTuple tuplesort_getheaptuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 2150 of file tuplesort.c.

References MemoryContextSwitchTo(), NULL, Tuplesortstate::sortcontext, SortTuple::tuple, and tuplesort_gettuple_common().

Referenced by copy_heap_data().

2151 {
2152  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2153  SortTuple stup;
2154 
2155  if (!tuplesort_gettuple_common(state, forward, &stup))
2156  stup.tuple = NULL;
2157 
2158  MemoryContextSwitchTo(oldcontext);
2159 
2160  return stup.tuple;
2161 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void * tuple
Definition: tuplesort.c:201
MemoryContext sortcontext
Definition: tuplesort.c:285
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1859
#define NULL
Definition: c.h:229
IndexTuple tuplesort_getindextuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 2170 of file tuplesort.c.

References MemoryContextSwitchTo(), NULL, Tuplesortstate::sortcontext, SortTuple::tuple, and tuplesort_gettuple_common().

Referenced by _bt_load(), and _h_indexbuild().

2171 {
2172  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2173  SortTuple stup;
2174 
2175  if (!tuplesort_gettuple_common(state, forward, &stup))
2176  stup.tuple = NULL;
2177 
2178  MemoryContextSwitchTo(oldcontext);
2179 
2180  return (IndexTuple) stup.tuple;
2181 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void * tuple
Definition: tuplesort.c:201
MemoryContext sortcontext
Definition: tuplesort.c:285
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1859
#define NULL
Definition: c.h:229
bool tuplesort_gettupleslot ( Tuplesortstate state,
bool  forward,
bool  copy,
TupleTableSlot slot,
Datum abbrev 
)

Definition at line 2113 of file tuplesort.c.

References SortSupportData::abbrev_converter, SortTuple::datum1, ExecClearTuple(), ExecStoreMinimalTuple(), heap_copy_minimal_tuple(), MemoryContextSwitchTo(), NULL, Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, SortTuple::tuple, and tuplesort_gettuple_common().

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

2115 {
2116  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2117  SortTuple stup;
2118 
2119  if (!tuplesort_gettuple_common(state, forward, &stup))
2120  stup.tuple = NULL;
2121 
2122  MemoryContextSwitchTo(oldcontext);
2123 
2124  if (stup.tuple)
2125  {
2126  /* Record abbreviated key for caller */
2127  if (state->sortKeys->abbrev_converter && abbrev)
2128  *abbrev = stup.datum1;
2129 
2130  if (copy)
2132 
2133  ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, copy);
2134  return true;
2135  }
2136  else
2137  {
2138  ExecClearTuple(slot);
2139  return false;
2140  }
2141 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:384
SortSupport sortKeys
Definition: tuplesort.c:442
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum datum1
Definition: tuplesort.c:202
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1479
void * tuple
Definition: tuplesort.c:201
MemoryContext sortcontext
Definition: tuplesort.c:285
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1859
#define NULL
Definition: c.h:229
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
void tuplesort_markpos ( Tuplesortstate state)

Definition at line 3166 of file tuplesort.c.

References Assert, Tuplesortstate::current, elog, Tuplesortstate::eof_reached, ERROR, LogicalTapeTell(), Tuplesortstate::markpos_block, Tuplesortstate::markpos_eof, Tuplesortstate::markpos_offset, MemoryContextSwitchTo(), Tuplesortstate::randomAccess, Tuplesortstate::result_tape, Tuplesortstate::sortcontext, Tuplesortstate::status, Tuplesortstate::tapeset, TSS_SORTEDINMEM, and TSS_SORTEDONTAPE.

Referenced by ExecSortMarkPos().

3167 {
3168  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3169 
3170  Assert(state->randomAccess);
3171 
3172  switch (state->status)
3173  {
3174  case TSS_SORTEDINMEM:
3175  state->markpos_offset = state->current;
3176  state->markpos_eof = state->eof_reached;
3177  break;
3178  case TSS_SORTEDONTAPE:
3179  LogicalTapeTell(state->tapeset,
3180  state->result_tape,
3181  &state->markpos_block,
3182  &state->markpos_offset);
3183  state->markpos_eof = state->eof_reached;
3184  break;
3185  default:
3186  elog(ERROR, "invalid tuplesort state");
3187  break;
3188  }
3189 
3190  MemoryContextSwitchTo(oldcontext);
3191 }
TupSortStatus status
Definition: tuplesort.c:273
bool randomAccess
Definition: tuplesort.c:275
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int markpos_offset
Definition: tuplesort.c:433
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:285
LogicalTapeSet * tapeset
Definition: tuplesort.c:287
void LogicalTapeTell(LogicalTapeSet *lts, int tapenum, long *blocknum, int *offset)
Definition: logtape.c:870
#define Assert(condition)
Definition: c.h:675
long markpos_block
Definition: tuplesort.c:432
bool eof_reached
Definition: tuplesort.c:429
bool markpos_eof
Definition: tuplesort.c:434
#define elog
Definition: elog.h:219
int tuplesort_merge_order ( int64  allowedMem)

Definition at line 2305 of file tuplesort.c.

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

Referenced by cost_sort(), and inittapes().

2306 {
2307  int mOrder;
2308 
2309  /*
2310  * We need one tape for each merge input, plus another one for the output,
2311  * and each of these tapes needs buffer space. In addition we want
2312  * MERGE_BUFFER_SIZE workspace per input tape (but the output tape doesn't
2313  * count).
2314  *
2315  * Note: you might be thinking we need to account for the memtuples[]
2316  * array in this calculation, but we effectively treat that as part of the
2317  * MERGE_BUFFER_SIZE workspace.
2318  */
2319  mOrder = (allowedMem - TAPE_BUFFER_OVERHEAD) /
2321 
2322  /*
2323  * Even in minimum memory, use at least a MINORDER merge. On the other
2324  * hand, even when we have lots of memory, do not use more than a MAXORDER
2325  * merge. Tapes are pretty cheap, but they're not entirely free. Each
2326  * additional tape reduces the amount of memory available to build runs,
2327  * which in turn can cause the same sort to need more runs, which makes
2328  * merging slower even if it can still be done in a single pass. Also,
2329  * high order merges are quite slow due to CPU cache effects; it can be
2330  * faster to pay the I/O cost of a polyphase merge than to perform a
2331  * single merge pass across many hundreds of tapes.
2332  */
2333  mOrder = Max(mOrder, MINORDER);
2334  mOrder = Min(mOrder, MAXORDER);
2335 
2336  return mOrder;
2337 }
#define Min(x, y)
Definition: c.h:806
#define TAPE_BUFFER_OVERHEAD
Definition: tuplesort.c:253
#define MERGE_BUFFER_SIZE
Definition: tuplesort.c:254
#define MINORDER
Definition: tuplesort.c:251
#define Max(x, y)
Definition: c.h:800
#define MAXORDER
Definition: tuplesort.c:252
void tuplesort_performsort ( Tuplesortstate state)

Definition at line 1773 of file tuplesort.c.

References Tuplesortstate::activeTapes, Tuplesortstate::current, dumptuples(), elog, Tuplesortstate::eof_reached, ERROR, LOG, Tuplesortstate::markpos_block, Tuplesortstate::markpos_eof, Tuplesortstate::markpos_offset, MemoryContextSwitchTo(), mergeruns(), pg_rusage_show(), Tuplesortstate::ru_start, sort_bounded_heap(), Tuplesortstate::sortcontext, Tuplesortstate::status, trace_sort, TSS_BOUNDED, TSS_BUILDRUNS, TSS_FINALMERGE, TSS_INITIAL, TSS_SORTEDINMEM, and tuplesort_sort_memtuples().

Referenced by _bt_leafbuild(), _h_indexbuild(), copy_heap_data(), ExecSort(), 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(), and validate_index().

1774 {
1775  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1776 
1777 #ifdef TRACE_SORT
1778  if (trace_sort)
1779  elog(LOG, "performsort starting: %s",
1780  pg_rusage_show(&state->ru_start));
1781 #endif
1782 
1783  switch (state->status)
1784  {
1785  case TSS_INITIAL:
1786 
1787  /*
1788  * We were able to accumulate all the tuples within the allowed
1789  * amount of memory. Just qsort 'em and we're done.
1790  */
1791  tuplesort_sort_memtuples(state);
1792  state->current = 0;
1793  state->eof_reached = false;
1794  state->markpos_offset = 0;
1795  state->markpos_eof = false;
1796  state->status = TSS_SORTEDINMEM;
1797  break;
1798 
1799  case TSS_BOUNDED:
1800 
1801  /*
1802  * We were able to accumulate all the tuples required for output
1803  * in memory, using a heap to eliminate excess tuples. Now we
1804  * have to transform the heap to a properly-sorted array.
1805  */
1806  sort_bounded_heap(state);
1807  state->current = 0;
1808  state->eof_reached = false;
1809  state->markpos_offset = 0;
1810  state->markpos_eof = false;
1811  state->status = TSS_SORTEDINMEM;
1812  break;
1813 
1814  case TSS_BUILDRUNS:
1815 
1816  /*
1817  * Finish tape-based sort. First, flush all tuples remaining in
1818  * memory out to tape; then merge until we have a single remaining
1819  * run (or, if !randomAccess, one run per tape). Note that
1820  * mergeruns sets the correct state->status.
1821  */
1822  dumptuples(state, true);
1823  mergeruns(state);
1824  state->eof_reached = false;
1825  state->markpos_block = 0L;
1826  state->markpos_offset = 0;
1827  state->markpos_eof = false;
1828  break;
1829 
1830  default:
1831  elog(ERROR, "invalid tuplesort state");
1832  break;
1833  }
1834 
1835 #ifdef TRACE_SORT
1836  if (trace_sort)
1837  {
1838  if (state->status == TSS_FINALMERGE)
1839  elog(LOG, "performsort done (except %d-way final merge): %s",
1840  state->activeTapes,
1841  pg_rusage_show(&state->ru_start));
1842  else
1843  elog(LOG, "performsort done: %s",
1844  pg_rusage_show(&state->ru_start));
1845  }
1846 #endif
1847 
1848  MemoryContextSwitchTo(oldcontext);
1849 }
static void dumptuples(Tuplesortstate *state, bool alltuples)
Definition: tuplesort.c:2946
TupSortStatus status
Definition: tuplesort.c:273
PGRUsage ru_start
Definition: tuplesort.c:493
static void sort_bounded_heap(Tuplesortstate *state)
Definition: tuplesort.c:3359
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define LOG
Definition: elog.h:26
int markpos_offset
Definition: tuplesort.c:433
bool trace_sort
Definition: tuplesort.c:155
static void mergeruns(Tuplesortstate *state)
Definition: tuplesort.c:2549
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:285
const char * pg_rusage_show(const PGRUsage *ru0)
Definition: pg_rusage.c:40
long markpos_block
Definition: tuplesort.c:432
bool eof_reached
Definition: tuplesort.c:429
static void tuplesort_sort_memtuples(Tuplesortstate *state)
Definition: tuplesort.c:3401
bool markpos_eof
Definition: tuplesort.c:434
#define elog
Definition: elog.h:219
void tuplesort_putdatum ( Tuplesortstate state,
Datum  val,
bool  isNull 
)

Definition at line 1485 of file tuplesort.c.

References SortSupportData::abbrev_converter, consider_abort_common(), SortTuple::datum1, datumCopy(), DatumGetPointer, Tuplesortstate::datumTypeLen, GetMemoryChunkSpace(), i, SortTuple::isnull1, MemoryContextSwitchTo(), Tuplesortstate::memtupcount, Tuplesortstate::memtuples, NULL, PointerGetDatum, puttuple_common(), Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, SortTuple::tuple, Tuplesortstate::tuplecontext, Tuplesortstate::tuples, and USEMEM.

Referenced by advance_aggregates(), ordered_set_transition(), and validate_index_callback().

1486 {
1487  MemoryContext oldcontext = MemoryContextSwitchTo(state->tuplecontext);
1488  SortTuple stup;
1489 
1490  /*
1491  * Pass-by-value types or null values are just stored directly in
1492  * stup.datum1 (and stup.tuple is not used and set to NULL).
1493  *
1494  * Non-null pass-by-reference values need to be copied into memory we
1495  * control, and possibly abbreviated. The copied value is pointed to by
1496  * stup.tuple and is treated as the canonical copy (e.g. to return via
1497  * tuplesort_getdatum or when writing to tape); stup.datum1 gets the
1498  * abbreviated value if abbreviation is happening, otherwise it's
1499  * identical to stup.tuple.
1500  */
1501 
1502  if (isNull || !state->tuples)
1503  {
1504  /*
1505  * Set datum1 to zeroed representation for NULLs (to be consistent,
1506  * and to support cheap inequality tests for NULL abbreviated keys).
1507  */
1508  stup.datum1 = !isNull ? val : (Datum) 0;
1509  stup.isnull1 = isNull;
1510  stup.tuple = NULL; /* no separate storage */
1512  }
1513  else
1514  {
1515  Datum original = datumCopy(val, false, state->datumTypeLen);
1516 
1517  stup.isnull1 = false;
1518  stup.tuple = DatumGetPointer(original);
1519  USEMEM(state, GetMemoryChunkSpace(stup.tuple));
1521 
1522  if (!state->sortKeys->abbrev_converter)
1523  {
1524  stup.datum1 = original;
1525  }
1526  else if (!consider_abort_common(state))
1527  {
1528  /* Store abbreviated key representation */
1529  stup.datum1 = state->sortKeys->abbrev_converter(original,
1530  state->sortKeys);
1531  }
1532  else
1533  {
1534  /* Abort abbreviation */
1535  int i;
1536 
1537  stup.datum1 = original;
1538 
1539  /*
1540  * Set state to be consistent with never trying abbreviation.
1541  *
1542  * Alter datum1 representation in already-copied tuples, so as to
1543  * ensure a consistent representation (current tuple was just
1544  * handled). It does not matter if some dumped tuples are already
1545  * sorted on tape, since serialized tuples lack abbreviated keys
1546  * (TSS_BUILDRUNS state prevents control reaching here in any
1547  * case).
1548  */
1549  for (i = 0; i < state->memtupcount; i++)
1550  {
1551  SortTuple *mtup = &state->memtuples[i];
1552 
1553  mtup->datum1 = PointerGetDatum(mtup->tuple);
1554  }
1555  }
1556  }
1557 
1558  puttuple_common(state, &stup);
1559 
1560  MemoryContextSwitchTo(oldcontext);
1561 }
#define PointerGetDatum(X)
Definition: postgres.h:562
SortSupport sortKeys
Definition: tuplesort.c:442
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum datum1
Definition: tuplesort.c:202
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:390
bool isnull1
Definition: tuplesort.c:203
void * tuple
Definition: tuplesort.c:201
static bool consider_abort_common(Tuplesortstate *state)
Definition: tuplesort.c:1729
MemoryContext sortcontext
Definition: tuplesort.c:285
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:128
uintptr_t Datum
Definition: postgres.h:372
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple)
Definition: tuplesort.c:1567
#define NULL
Definition: c.h:229
#define DatumGetPointer(X)
Definition: postgres.h:555
MemoryContext tuplecontext
Definition: tuplesort.c:286
#define USEMEM(state, amt)
Definition: tuplesort.c:525
int i
long val
Definition: informix.c:689
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
SortTuple * memtuples
Definition: tuplesort.c:334
void tuplesort_putheaptuple ( Tuplesortstate state,
HeapTuple  tup 
)

Definition at line 1386 of file tuplesort.c.

References COPYTUP, MemoryContextSwitchTo(), puttuple_common(), and Tuplesortstate::sortcontext.

Referenced by copy_heap_data().

1387 {
1388  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1389  SortTuple stup;
1390 
1391  /*
1392  * Copy the given tuple into memory we control, and decrease availMem.
1393  * Then call the common code.
1394  */
1395  COPYTUP(state, &stup, (void *) tup);
1396 
1397  puttuple_common(state, &stup);
1398 
1399  MemoryContextSwitchTo(oldcontext);
1400 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext sortcontext
Definition: tuplesort.c:285
#define COPYTUP(state, stup, tup)
Definition: tuplesort.c:521
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple)
Definition: tuplesort.c:1567
void tuplesort_putindextuplevalues ( Tuplesortstate state,
Relation  rel,
ItemPointer  self,
Datum values,
bool isnull 
)

Definition at line 1407 of file tuplesort.c.

References SortSupportData::abbrev_converter, consider_abort_common(), SortTuple::datum1, GetMemoryChunkSpace(), i, index_form_tuple(), index_getattr, Tuplesortstate::indexRel, SortTuple::isnull1, MemoryContextSwitchTo(), Tuplesortstate::memtupcount, Tuplesortstate::memtuples, puttuple_common(), RelationGetDescr, Tuplesortstate::sortcontext, Tuplesortstate::sortKeys, IndexTupleData::t_tid, SortTuple::tuple, Tuplesortstate::tuplecontext, and USEMEM.

Referenced by _bt_spool(), and _h_spool().

1410 {
1411  MemoryContext oldcontext = MemoryContextSwitchTo(state->tuplecontext);
1412  SortTuple stup;
1413  Datum original;
1414  IndexTuple tuple;
1415 
1416  stup.tuple = index_form_tuple(RelationGetDescr(rel), values, isnull);
1417  tuple = ((IndexTuple) stup.tuple);
1418  tuple->t_tid = *self;
1419  USEMEM(state, GetMemoryChunkSpace(stup.tuple));
1420  /* set up first-column key value */
1421  original = index_getattr(tuple,
1422  1,
1423  RelationGetDescr(state->indexRel),
1424  &stup.isnull1);
1425 
1427 
1428  if (!state->sortKeys || !state->sortKeys->abbrev_converter || stup.isnull1)
1429  {
1430  /*
1431  * Store ordinary Datum representation, or NULL value. If there is a
1432  * converter it won't expect NULL values, and cost model is not
1433  * required to account for NULL, so in that case we avoid calling
1434  * converter and just set datum1 to zeroed representation (to be
1435  * consistent, and to support cheap inequality tests for NULL
1436  * abbreviated keys).
1437  */
1438  stup.datum1 = original;
1439  }
1440  else if (!consider_abort_common(state))
1441  {
1442  /* Store abbreviated key representation */
1443  stup.datum1 = state->sortKeys->abbrev_converter(original,
1444  state->sortKeys);
1445  }
1446  else
1447  {
1448  /* Abort abbreviation */
1449  int i;
1450 
1451  stup.datum1 = original;
1452 
1453  /*
1454  * Set state to be consistent with never trying abbreviation.
1455  *
1456  * Alter datum1 representation in already-copied tuples, so as to
1457  * ensure a consistent representation (current tuple was just
1458  * handled). It does not matter if some dumped tuples are already
1459  * sorted on tape, since serialized tuples lack abbreviated keys
1460  * (TSS_BUILDRUNS state prevents control reaching here in any case).
1461  */
1462  for (i = 0; i < state->memtupcount; i++)
1463  {
1464  SortTuple *mtup = &state->memtuples[i];
1465 
1466  tuple = mtup->tuple;
1467  mtup->datum1 = index_getattr(tuple,
1468  1,
1469  RelationGetDescr(state->indexRel),
1470  &mtup->isnull1);
1471  }
1472  }
1473 
1474  puttuple_common(state, &stup);
1475 
1476  MemoryContextSwitchTo(oldcontext);
1477 }
#define RelationGetDescr(relation)
Definition: rel.h:428
SortSupport sortKeys
Definition: tuplesort.c:442
ItemPointerData t_tid
Definition: itup.h:37
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum datum1
Definition: tuplesort.c:202
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:390
bool isnull1
Definition: tuplesort.c:203
IndexTuple index_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: indextuple.c:37
void * tuple
Definition: tuplesort.c:201
static bool consider_abort_common(Tuplesortstate *state)
Definition: tuplesort.c:1729
MemoryContext sortcontext
Definition: tuplesort.c:285
IndexTupleData * IndexTuple
Definition: itup.h:53
Relation indexRel
Definition: tuplesort.c:471
uintptr_t Datum
Definition: postgres.h:372
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple)
Definition: tuplesort.c:1567
#define index_getattr(tup, attnum, tupleDesc, isnull)
Definition: itup.h:100
static Datum values[MAXATTR]
Definition: bootstrap.c:163
MemoryContext tuplecontext
Definition: tuplesort.c:286
#define USEMEM(state, amt)
Definition: tuplesort.c:525
int i
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
SortTuple * memtuples
Definition: tuplesort.c:334
void tuplesort_puttupleslot ( Tuplesortstate state,
TupleTableSlot slot 
)

Definition at line 1364 of file tuplesort.c.

References COPYTUP, MemoryContextSwitchTo(), puttuple_common(), and Tuplesortstate::sortcontext.

Referenced by advance_aggregates(), ExecSort(), fetch_input_tuple(), hypothetical_dense_rank_final(), hypothetical_rank_common(), and ordered_set_transition_multi().

1365 {
1366  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1367  SortTuple stup;
1368 
1369  /*
1370  * Copy the given tuple into memory we control, and decrease availMem.
1371  * Then call the common code.
1372  */
1373  COPYTUP(state, &stup, (void *) slot);
1374 
1375  puttuple_common(state, &stup);
1376 
1377  MemoryContextSwitchTo(oldcontext);
1378 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext sortcontext
Definition: tuplesort.c:285
#define COPYTUP(state, stup, tup)
Definition: tuplesort.c:521
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple)
Definition: tuplesort.c:1567
void tuplesort_rescan ( Tuplesortstate state)

Definition at line 3131 of file tuplesort.c.

References Assert, Tuplesortstate::current, elog, Tuplesortstate::eof_reached, ERROR, LogicalTapeRewindForRead(), Tuplesortstate::markpos_block, Tuplesortstate::markpos_eof, Tuplesortstate::markpos_offset, MemoryContextSwitchTo(), Tuplesortstate::randomAccess, Tuplesortstate::result_tape, Tuplesortstate::sortcontext, Tuplesortstate::status, Tuplesortstate::tapeset, TSS_SORTEDINMEM, and TSS_SORTEDONTAPE.

Referenced by ExecReScanSort().

3132 {
3133  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3134 
3135  Assert(state->randomAccess);
3136 
3137  switch (state->status)
3138  {
3139  case TSS_SORTEDINMEM:
3140  state->current = 0;
3141  state->eof_reached = false;
3142  state->markpos_offset = 0;
3143  state->markpos_eof = false;
3144  break;
3145  case TSS_SORTEDONTAPE:
3147  state->result_tape,
3148  0);
3149  state->eof_reached = false;
3150  state->markpos_block = 0L;
3151  state->markpos_offset = 0;
3152  state->markpos_eof = false;
3153  break;
3154  default:
3155  elog(ERROR, "invalid tuplesort state");
3156  break;
3157  }
3158 
3159  MemoryContextSwitchTo(oldcontext);
3160 }
TupSortStatus status
Definition: tuplesort.c:273
bool randomAccess
Definition: tuplesort.c:275
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int markpos_offset
Definition: tuplesort.c:433
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:285
LogicalTapeSet * tapeset
Definition: tuplesort.c:287
#define Assert(condition)
Definition: c.h:675
long markpos_block
Definition: tuplesort.c:432
bool eof_reached
Definition: tuplesort.c:429
void LogicalTapeRewindForRead(LogicalTapeSet *lts, int tapenum, size_t buffer_size)
Definition: logtape.c:551
bool markpos_eof
Definition: tuplesort.c:434
#define elog
Definition: elog.h:219
void tuplesort_restorepos ( Tuplesortstate state)

Definition at line 3198 of file tuplesort.c.

References Assert, Tuplesortstate::current, elog, Tuplesortstate::eof_reached, ERROR, LogicalTapeSeek(), Tuplesortstate::markpos_block, Tuplesortstate::markpos_eof, Tuplesortstate::markpos_offset, MemoryContextSwitchTo(), Tuplesortstate::randomAccess, Tuplesortstate::result_tape, Tuplesortstate::sortcontext, Tuplesortstate::status, Tuplesortstate::tapeset, TSS_SORTEDINMEM, and TSS_SORTEDONTAPE.

Referenced by ExecSortRestrPos().

3199 {
3200  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3201 
3202  Assert(state->randomAccess);
3203 
3204  switch (state->status)
3205  {
3206  case TSS_SORTEDINMEM:
3207  state->current = state->markpos_offset;
3208  state->eof_reached = state->markpos_eof;
3209  break;
3210  case TSS_SORTEDONTAPE:
3211  LogicalTapeSeek(state->tapeset,
3212  state->result_tape,
3213  state->markpos_block,
3214  state->markpos_offset);
3215  state->eof_reached = state->markpos_eof;
3216  break;
3217  default:
3218  elog(ERROR, "invalid tuplesort state");
3219  break;
3220  }
3221 
3222  MemoryContextSwitchTo(oldcontext);
3223 }
TupSortStatus status
Definition: tuplesort.c:273
bool randomAccess
Definition: tuplesort.c:275
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int markpos_offset
Definition: tuplesort.c:433
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:285
LogicalTapeSet * tapeset
Definition: tuplesort.c:287
#define Assert(condition)
Definition: c.h:675
long markpos_block
Definition: tuplesort.c:432
bool eof_reached
Definition: tuplesort.c:429
bool markpos_eof
Definition: tuplesort.c:434
void LogicalTapeSeek(LogicalTapeSet *lts, int tapenum, long blocknum, int offset)
Definition: logtape.c:839
#define elog
Definition: elog.h:219
void tuplesort_set_bound ( Tuplesortstate state,
int64  bound 
)

Definition at line 1123 of file tuplesort.c.

References SortSupportData::abbrev_abort, SortSupportData::abbrev_converter, SortSupportData::abbrev_full_comparator, Assert, Tuplesortstate::bound, Tuplesortstate::bounded, SortSupportData::comparator, Tuplesortstate::memtupcount, NULL, Tuplesortstate::sortKeys, Tuplesortstate::status, and TSS_INITIAL.

Referenced by ExecSort().

1124 {
1125  /* Assert we're called before loading any tuples */
1126  Assert(state->status == TSS_INITIAL);
1127  Assert(state->memtupcount == 0);
1128  Assert(!state->bounded);
1129 
1130 #ifdef DEBUG_BOUNDED_SORT
1131  /* Honor GUC setting that disables the feature (for easy testing) */
1132  if (!optimize_bounded_sort)
1133  return;
1134 #endif
1135 
1136  /* We want to be able to compute bound * 2, so limit the setting */
1137  if (bound > (int64) (INT_MAX / 2))
1138  return;
1139 
1140  state->bounded = true;
1141  state->bound = (int) bound;
1142 
1143  /*
1144  * Bounded sorts are not an effective target for abbreviated key
1145  * optimization. Disable by setting state to be consistent with no
1146  * abbreviation support.
1147  */
1148  state->sortKeys->abbrev_converter = NULL;
1149  if (state->sortKeys->abbrev_full_comparator)
1151 
1152  /* Not strictly necessary, but be tidy */
1153  state->sortKeys->abbrev_abort = NULL;
1155 }
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:107
TupSortStatus status
Definition: tuplesort.c:273
SortSupport sortKeys
Definition: tuplesort.c:442
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:192
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool(* abbrev_abort)(int memtupcount, SortSupport ssup)
Definition: sortsupport.h:183
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
bool tuplesort_skiptuples ( Tuplesortstate state,
int64  ntuples,
bool  forward 
)

Definition at line 2238 of file tuplesort.c.

References Assert, Tuplesortstate::bound, Tuplesortstate::bounded, CHECK_FOR_INTERRUPTS, Tuplesortstate::current, elog, Tuplesortstate::eof_reached, ERROR, MemoryContextSwitchTo(), Tuplesortstate::memtupcount, Tuplesortstate::sortcontext, Tuplesortstate::status, TSS_FINALMERGE, TSS_SORTEDINMEM, TSS_SORTEDONTAPE, and tuplesort_gettuple_common().

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

2239 {
2240  MemoryContext oldcontext;
2241 
2242  /*
2243  * We don't actually support backwards skip yet, because no callers need
2244  * it. The API is designed to allow for that later, though.
2245  */
2246  Assert(forward);
2247  Assert(ntuples >= 0);
2248 
2249  switch (state->status)
2250  {
2251  case TSS_SORTEDINMEM:
2252  if (state->memtupcount - state->current >= ntuples)
2253  {
2254  state->current += ntuples;
2255  return true;
2256  }
2257  state->current = state->memtupcount;
2258  state->eof_reached = true;
2259 
2260  /*
2261  * Complain if caller tries to retrieve more tuples than
2262  * originally asked for in a bounded sort. This is because
2263  * returning EOF here might be the wrong thing.
2264  */
2265  if (state->bounded && state->current >= state->bound)
2266  elog(ERROR, "retrieved too many tuples in a bounded sort");
2267 
2268  return false;
2269 
2270  case TSS_SORTEDONTAPE:
2271  case TSS_FINALMERGE:
2272 
2273  /*
2274  * We could probably optimize these cases better, but for now it's
2275  * not worth the trouble.
2276  */
2277  oldcontext = MemoryContextSwitchTo(state->sortcontext);
2278  while (ntuples-- > 0)
2279  {
2280  SortTuple stup;
2281 
2282  if (!tuplesort_gettuple_common(state, forward, &stup))
2283  {
2284  MemoryContextSwitchTo(oldcontext);
2285  return false;
2286  }
2288  }
2289  MemoryContextSwitchTo(oldcontext);
2290  return true;
2291 
2292  default:
2293  elog(ERROR, "invalid tuplesort state");
2294  return false; /* keep compiler quiet */
2295  }
2296 }
TupSortStatus status
Definition: tuplesort.c:273
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:285
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1859
#define Assert(condition)
Definition: c.h:675
bool eof_reached
Definition: tuplesort.c:429
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
#define elog
Definition: elog.h:219