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 hash_mask, 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, 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 825 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().

828 {
829  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
830  ScanKey indexScanKey;
831  MemoryContext oldcontext;
832  int i;
833 
834  Assert(indexRel->rd_rel->relam == BTREE_AM_OID);
835 
836  oldcontext = MemoryContextSwitchTo(state->sortcontext);
837 
838 #ifdef TRACE_SORT
839  if (trace_sort)
840  elog(LOG,
841  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
843  workMem, randomAccess ? 't' : 'f');
844 #endif
845 
846  state->nKeys = RelationGetNumberOfAttributes(indexRel);
847 
848  TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
849  false, /* no unique check */
850  state->nKeys,
851  workMem,
852  randomAccess);
853 
855  state->copytup = copytup_cluster;
856  state->writetup = writetup_cluster;
857  state->readtup = readtup_cluster;
858  state->abbrevNext = 10;
859 
860  state->indexInfo = BuildIndexInfo(indexRel);
861 
862  state->tupDesc = tupDesc; /* assume we need not copy tupDesc */
863 
864  indexScanKey = _bt_mkscankey_nodata(indexRel);
865 
866  if (state->indexInfo->ii_Expressions != NULL)
867  {
868  TupleTableSlot *slot;
869  ExprContext *econtext;
870 
871  /*
872  * We will need to use FormIndexDatum to evaluate the index
873  * expressions. To do that, we need an EState, as well as a
874  * TupleTableSlot to put the table tuples into. The econtext's
875  * scantuple has to point to that slot, too.
876  */
877  state->estate = CreateExecutorState();
878  slot = MakeSingleTupleTableSlot(tupDesc);
879  econtext = GetPerTupleExprContext(state->estate);
880  econtext->ecxt_scantuple = slot;
881  }
882 
883  /* Prepare SortSupport data for each column */
884  state->sortKeys = (SortSupport) palloc0(state->nKeys *
885  sizeof(SortSupportData));
886 
887  for (i = 0; i < state->nKeys; i++)
888  {
889  SortSupport sortKey = state->sortKeys + i;
890  ScanKey scanKey = indexScanKey + i;
891  int16 strategy;
892 
893  sortKey->ssup_cxt = CurrentMemoryContext;
894  sortKey->ssup_collation = scanKey->sk_collation;
895  sortKey->ssup_nulls_first =
896  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
897  sortKey->ssup_attno = scanKey->sk_attno;
898  /* Convey if abbreviation optimization is applicable in principle */
899  sortKey->abbreviate = (i == 0);
900 
901  AssertState(sortKey->ssup_attno != 0);
902 
903  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
905 
906  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
907  }
908 
909  _bt_freeskey(indexScanKey);
910 
911  MemoryContextSwitchTo(oldcontext);
912 
913  return state;
914 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
signed short int16
Definition: c.h:252
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:3966
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define AssertState(condition)
Definition: c.h:673
int64 abbrevNext
Definition: tuplesort.c:455
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:419
EState * estate
Definition: tuplesort.c:463
SortSupport sortKeys
Definition: tuplesort.c:441
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:297
#define CLUSTER_SORT
Definition: tuplesort.c:150
static int comparetup_cluster(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:3782
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:1639
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:315
#define LOG
Definition: elog.h:26
Form_pg_class rd_rel
Definition: rel.h:113
static void copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:3893
bool trace_sort
Definition: tuplesort.c:154
#define GetPerTupleExprContext(estate)
Definition: executor.h:338
static void readtup_cluster(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:3990
MemoryContext sortcontext
Definition: tuplesort.c:284
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:323
IndexInfo * indexInfo
Definition: tuplesort.c:462
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:72
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:428
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:305
void * palloc0(Size size)
Definition: mcxt.c:920
AttrNumber ssup_attno
Definition: sortsupport.h:81
int sk_flags
Definition: skey.h:66
#define NULL
Definition: c.h:226
List * ii_Expressions
Definition: execnodes.h:67
#define Assert(condition)
Definition: c.h:670
#define SK_BT_DESC
Definition: nbtree.h:427
Definition: regguts.h:298
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
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:667
#define BTLessStrategyNumber
Definition: stratnum.h:29
AttrNumber sk_attno
Definition: skey.h:67
TupleDesc tupDesc
Definition: tuplesort.c:440
Tuplesortstate* tuplesort_begin_datum ( Oid  datumType,
Oid  sortOperator,
Oid  sortCollation,
bool  nullsFirstFlag,
int  workMem,
bool  randomAccess 
)

Definition at line 1028 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().

1031 {
1032  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
1033  MemoryContext oldcontext;
1034  int16 typlen;
1035  bool typbyval;
1036 
1037  oldcontext = MemoryContextSwitchTo(state->sortcontext);
1038 
1039 #ifdef TRACE_SORT
1040  if (trace_sort)
1041  elog(LOG,
1042  "begin datum sort: workMem = %d, randomAccess = %c",
1043  workMem, randomAccess ? 't' : 'f');
1044 #endif
1045 
1046  state->nKeys = 1; /* always a one-column sort */
1047 
1048  TRACE_POSTGRESQL_SORT_START(DATUM_SORT,
1049  false, /* no unique check */
1050  1,
1051  workMem,
1052  randomAccess);
1053 
1054  state->comparetup = comparetup_datum;
1055  state->copytup = copytup_datum;
1056  state->writetup = writetup_datum;
1057  state->readtup = readtup_datum;
1058  state->abbrevNext = 10;
1059 
1060  state->datumType = datumType;
1061 
1062  /* lookup necessary attributes of the datum type */
1063  get_typlenbyval(datumType, &typlen, &typbyval);
1064  state->datumTypeLen = typlen;
1065  state->tuples = !typbyval;
1066 
1067  /* Prepare SortSupport data */
1068  state->sortKeys = (SortSupport) palloc0(sizeof(SortSupportData));
1069 
1071  state->sortKeys->ssup_collation = sortCollation;
1072  state->sortKeys->ssup_nulls_first = nullsFirstFlag;
1073 
1074  /*
1075  * Abbreviation is possible here only for by-reference types. In theory,
1076  * a pass-by-value datatype could have an abbreviated form that is cheaper
1077  * to compare. In a tuple sort, we could support that, because we can
1078  * always extract the original datum from the tuple is needed. Here, we
1079  * can't, because a datum sort only stores a single copy of the datum; the
1080  * "tuple" field of each sortTuple is NULL.
1081  */
1082  state->sortKeys->abbreviate = !typbyval;
1083 
1084  PrepareSortSupportFromOrderingOp(sortOperator, state->sortKeys);
1085 
1086  /*
1087  * The "onlyKey" optimization cannot be used with abbreviated keys, since
1088  * tie-breaker comparisons may be required. Typically, the optimization
1089  * is only of value to pass-by-value types anyway, whereas abbreviated
1090  * keys are typically only of value to pass-by-reference types.
1091  */
1092  if (!state->sortKeys->abbrev_converter)
1093  state->onlyKey = state->sortKeys;
1094 
1095  MemoryContextSwitchTo(oldcontext);
1096 
1097  return state;
1098 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
signed short int16
Definition: c.h:252
bool ssup_nulls_first
Definition: sortsupport.h:75
int64 abbrevNext
Definition: tuplesort.c:455
SortSupport sortKeys
Definition: tuplesort.c:441
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:133
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:297
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:315
#define LOG
Definition: elog.h:26
bool trace_sort
Definition: tuplesort.c:154
#define DATUM_SORT
Definition: tuplesort.c:149
MemoryContext sortcontext
Definition: tuplesort.c:284
MemoryContext ssup_cxt
Definition: sortsupport.h:66
static int comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4318
static void copytup_datum(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4339
static void readtup_datum(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:4387
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:323
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
static void writetup_datum(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:4346
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:305
void * palloc0(Size size)
Definition: mcxt.c:920
Definition: regguts.h:298
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:1969
SortSupport onlyKey
Definition: tuplesort.c:447
#define elog
Definition: elog.h:219
static Tuplesortstate * tuplesort_begin_common(int workMem, bool randomAccess)
Definition: tuplesort.c:667
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 753 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().

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

Definition at line 917 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().

921 {
922  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
923  ScanKey indexScanKey;
924  MemoryContext oldcontext;
925  int i;
926 
927  oldcontext = MemoryContextSwitchTo(state->sortcontext);
928 
929 #ifdef TRACE_SORT
930  if (trace_sort)
931  elog(LOG,
932  "begin index sort: unique = %c, workMem = %d, randomAccess = %c",
933  enforceUnique ? 't' : 'f',
934  workMem, randomAccess ? 't' : 'f');
935 #endif
936 
937  state->nKeys = RelationGetNumberOfAttributes(indexRel);
938 
939  TRACE_POSTGRESQL_SORT_START(INDEX_SORT,
940  enforceUnique,
941  state->nKeys,
942  workMem,
943  randomAccess);
944 
946  state->copytup = copytup_index;
947  state->writetup = writetup_index;
948  state->readtup = readtup_index;
949  state->abbrevNext = 10;
950 
951  state->heapRel = heapRel;
952  state->indexRel = indexRel;
953  state->enforceUnique = enforceUnique;
954 
955  indexScanKey = _bt_mkscankey_nodata(indexRel);
956  state->nKeys = RelationGetNumberOfAttributes(indexRel);
957 
958  /* Prepare SortSupport data for each column */
959  state->sortKeys = (SortSupport) palloc0(state->nKeys *
960  sizeof(SortSupportData));
961 
962  for (i = 0; i < state->nKeys; i++)
963  {
964  SortSupport sortKey = state->sortKeys + i;
965  ScanKey scanKey = indexScanKey + i;
966  int16 strategy;
967 
968  sortKey->ssup_cxt = CurrentMemoryContext;
969  sortKey->ssup_collation = scanKey->sk_collation;
970  sortKey->ssup_nulls_first =
971  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
972  sortKey->ssup_attno = scanKey->sk_attno;
973  /* Convey if abbreviation optimization is applicable in principle */
974  sortKey->abbreviate = (i == 0);
975 
976  AssertState(sortKey->ssup_attno != 0);
977 
978  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
980 
981  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
982  }
983 
984  _bt_freeskey(indexScanKey);
985 
986  MemoryContextSwitchTo(oldcontext);
987 
988  return state;
989 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
signed short int16
Definition: c.h:252
bool ssup_nulls_first
Definition: sortsupport.h:75
ScanKey _bt_mkscankey_nodata(Relation rel)
Definition: nbtutils.c:115
Relation heapRel
Definition: tuplesort.c:469
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define AssertState(condition)
Definition: c.h:673
int64 abbrevNext
Definition: tuplesort.c:455
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:419
static void copytup_index(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4206
SortSupport sortKeys
Definition: tuplesort.c:441
void _bt_freeskey(ScanKey skey)
Definition: nbtutils.c:155
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:297
#define INDEX_SORT
Definition: tuplesort.c:148
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:315
#define LOG
Definition: elog.h:26
static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4028
bool trace_sort
Definition: tuplesort.c:154
MemoryContext sortcontext
Definition: tuplesort.c:284
static void writetup_index(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:4272
MemoryContext ssup_cxt
Definition: sortsupport.h:66
static void readtup_index(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:4294
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:323
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:305
void * palloc0(Size size)
Definition: mcxt.c:920
Relation indexRel
Definition: tuplesort.c:470
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:473
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:667
#define BTLessStrategyNumber
Definition: stratnum.h:29
AttrNumber sk_attno
Definition: skey.h:67
Tuplesortstate* tuplesort_begin_index_hash ( Relation  heapRel,
Relation  indexRel,
uint32  hash_mask,
int  workMem,
bool  randomAccess 
)

Definition at line 992 of file tuplesort.c.

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

Referenced by _h_spoolinit().

996 {
997  Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
998  MemoryContext oldcontext;
999 
1000  oldcontext = MemoryContextSwitchTo(state->sortcontext);
1001 
1002 #ifdef TRACE_SORT
1003  if (trace_sort)
1004  elog(LOG,
1005  "begin index sort: hash_mask = 0x%x, workMem = %d, randomAccess = %c",
1006  hash_mask,
1007  workMem, randomAccess ? 't' : 'f');
1008 #endif
1009 
1010  state->nKeys = 1; /* Only one sort column, the hash code */
1011 
1013  state->copytup = copytup_index;
1014  state->writetup = writetup_index;
1015  state->readtup = readtup_index;
1016 
1017  state->heapRel = heapRel;
1018  state->indexRel = indexRel;
1019 
1020  state->hash_mask = hash_mask;
1021 
1022  MemoryContextSwitchTo(oldcontext);
1023 
1024  return state;
1025 }
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Definition: tuplesort.c:4157
Relation heapRel
Definition: tuplesort.c:469
static void copytup_index(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:4206
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SortTupleComparator comparetup
Definition: tuplesort.c:297
void(* writetup)(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:315
#define LOG
Definition: elog.h:26
bool trace_sort
Definition: tuplesort.c:154
MemoryContext sortcontext
Definition: tuplesort.c:284
static void writetup_index(Tuplesortstate *state, int tapenum, SortTuple *stup)
Definition: tuplesort.c:4272
static void readtup_index(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:4294
void(* readtup)(Tuplesortstate *state, SortTuple *stup, int tapenum, unsigned int len)
Definition: tuplesort.c:323
void(* copytup)(Tuplesortstate *state, SortTuple *stup, void *tup)
Definition: tuplesort.c:305
Relation indexRel
Definition: tuplesort.c:470
Definition: regguts.h:298
uint32 hash_mask
Definition: tuplesort.c:476
#define elog
Definition: elog.h:219
static Tuplesortstate * tuplesort_begin_common(int workMem, bool randomAccess)
Definition: tuplesort.c:667
void tuplesort_end ( Tuplesortstate state)

Definition at line 1157 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().

1158 {
1159  /* context swap probably not needed, but let's be safe */
1160  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1161 
1162 #ifdef TRACE_SORT
1163  long spaceUsed;
1164 
1165  if (state->tapeset)
1166  spaceUsed = LogicalTapeSetBlocks(state->tapeset);
1167  else
1168  spaceUsed = (state->allowedMem - state->availMem + 1023) / 1024;
1169 #endif
1170 
1171  /*
1172  * Delete temporary "tape" files, if any.
1173  *
1174  * Note: want to include this in reported total cost of sort, hence need
1175  * for two #ifdef TRACE_SORT sections.
1176  */
1177  if (state->tapeset)
1178  LogicalTapeSetClose(state->tapeset);
1179 
1180 #ifdef TRACE_SORT
1181  if (trace_sort)
1182  {
1183  if (state->tapeset)
1184  elog(LOG, "external sort ended, %ld disk blocks used: %s",
1185  spaceUsed, pg_rusage_show(&state->ru_start));
1186  else
1187  elog(LOG, "internal sort ended, %ld KB used: %s",
1188  spaceUsed, pg_rusage_show(&state->ru_start));
1189  }
1190 
1191  TRACE_POSTGRESQL_SORT_DONE(state->tapeset != NULL, spaceUsed);
1192 #else
1193 
1194  /*
1195  * If you disabled TRACE_SORT, you can still probe sort__done, but you
1196  * ain't getting space-used stats.
1197  */
1198  TRACE_POSTGRESQL_SORT_DONE(state->tapeset != NULL, 0L);
1199 #endif
1200 
1201  /* Free any execution state created for CLUSTER case */
1202  if (state->estate != NULL)
1203  {
1204  ExprContext *econtext = GetPerTupleExprContext(state->estate);
1205 
1207  FreeExecutorState(state->estate);
1208  }
1209 
1210  MemoryContextSwitchTo(oldcontext);
1211 
1212  /*
1213  * Free the per-sort memory context, thereby releasing all working memory,
1214  * including the Tuplesortstate struct itself.
1215  */
1217 }
int64 availMem
Definition: tuplesort.c:280
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
PGRUsage ru_start
Definition: tuplesort.c:490
EState * estate
Definition: tuplesort.c:463
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define LOG
Definition: elog.h:26
bool trace_sort
Definition: tuplesort.c:154
void FreeExecutorState(EState *estate)
Definition: execUtils.c:167
#define GetPerTupleExprContext(estate)
Definition: executor.h:338
MemoryContext sortcontext
Definition: tuplesort.c:284
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:286
int64 allowedMem
Definition: tuplesort.c:281
#define NULL
Definition: c.h:226
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
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 3217 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().

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

Definition at line 2183 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().

2185 {
2186  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2187  SortTuple stup;
2188 
2189  if (!tuplesort_gettuple_common(state, forward, &stup))
2190  {
2191  MemoryContextSwitchTo(oldcontext);
2192  return false;
2193  }
2194 
2195  /* Record abbreviated key for caller */
2196  if (state->sortKeys->abbrev_converter && abbrev)
2197  *abbrev = stup.datum1;
2198 
2199  if (stup.isnull1 || !state->tuples)
2200  {
2201  *val = stup.datum1;
2202  *isNull = stup.isnull1;
2203  }
2204  else
2205  {
2206  /* use stup.tuple because stup.datum1 may be an abbreviation */
2207  *val = datumCopy(PointerGetDatum(stup.tuple), false, state->datumTypeLen);
2208  *isNull = false;
2209  }
2210 
2211  MemoryContextSwitchTo(oldcontext);
2212 
2213  return true;
2214 }
#define PointerGetDatum(X)
Definition: postgres.h:564
SortSupport sortKeys
Definition: tuplesort.c:441
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum datum1
Definition: tuplesort.c:201
bool isnull1
Definition: tuplesort.c:202
void * tuple
Definition: tuplesort.c:200
MemoryContext sortcontext
Definition: tuplesort.c:284
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1848
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 2134 of file tuplesort.c.

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

Referenced by copy_heap_data().

2135 {
2136  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2137  SortTuple stup;
2138 
2139  if (!tuplesort_gettuple_common(state, forward, &stup))
2140  stup.tuple = NULL;
2141 
2142  MemoryContextSwitchTo(oldcontext);
2143 
2144  return stup.tuple;
2145 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void * tuple
Definition: tuplesort.c:200
MemoryContext sortcontext
Definition: tuplesort.c:284
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1848
#define NULL
Definition: c.h:226
IndexTuple tuplesort_getindextuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 2154 of file tuplesort.c.

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

Referenced by _bt_load(), and _h_indexbuild().

2155 {
2156  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2157  SortTuple stup;
2158 
2159  if (!tuplesort_gettuple_common(state, forward, &stup))
2160  stup.tuple = NULL;
2161 
2162  MemoryContextSwitchTo(oldcontext);
2163 
2164  return (IndexTuple) stup.tuple;
2165 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void * tuple
Definition: tuplesort.c:200
MemoryContext sortcontext
Definition: tuplesort.c:284
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1848
#define NULL
Definition: c.h:226
bool tuplesort_gettupleslot ( Tuplesortstate state,
bool  forward,
TupleTableSlot slot,
Datum abbrev 
)

Definition at line 2099 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().

2101 {
2102  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
2103  SortTuple stup;
2104 
2105  if (!tuplesort_gettuple_common(state, forward, &stup))
2106  stup.tuple = NULL;
2107 
2108  MemoryContextSwitchTo(oldcontext);
2109 
2110  if (stup.tuple)
2111  {
2112  /* Record abbreviated key for caller */
2113  if (state->sortKeys->abbrev_converter && abbrev)
2114  *abbrev = stup.datum1;
2115 
2117  ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, true);
2118  return true;
2119  }
2120  else
2121  {
2122  ExecClearTuple(slot);
2123  return false;
2124  }
2125 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:384
SortSupport sortKeys
Definition: tuplesort.c:441
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum datum1
Definition: tuplesort.c:201
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1481
void * tuple
Definition: tuplesort.c:200
MemoryContext sortcontext
Definition: tuplesort.c:284
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1848
#define NULL
Definition: c.h:226
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:173
void tuplesort_markpos ( Tuplesortstate state)

Definition at line 3150 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().

3151 {
3152  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3153 
3154  Assert(state->randomAccess);
3155 
3156  switch (state->status)
3157  {
3158  case TSS_SORTEDINMEM:
3159  state->markpos_offset = state->current;
3160  state->markpos_eof = state->eof_reached;
3161  break;
3162  case TSS_SORTEDONTAPE:
3163  LogicalTapeTell(state->tapeset,
3164  state->result_tape,
3165  &state->markpos_block,
3166  &state->markpos_offset);
3167  state->markpos_eof = state->eof_reached;
3168  break;
3169  default:
3170  elog(ERROR, "invalid tuplesort state");
3171  break;
3172  }
3173 
3174  MemoryContextSwitchTo(oldcontext);
3175 }
TupSortStatus status
Definition: tuplesort.c:272
bool randomAccess
Definition: tuplesort.c:274
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int markpos_offset
Definition: tuplesort.c:432
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:284
LogicalTapeSet * tapeset
Definition: tuplesort.c:286
void LogicalTapeTell(LogicalTapeSet *lts, int tapenum, long *blocknum, int *offset)
Definition: logtape.c:870
#define Assert(condition)
Definition: c.h:670
long markpos_block
Definition: tuplesort.c:431
bool eof_reached
Definition: tuplesort.c:428
bool markpos_eof
Definition: tuplesort.c:433
#define elog
Definition: elog.h:219
int tuplesort_merge_order ( int64  allowedMem)

Definition at line 2289 of file tuplesort.c.

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

Referenced by cost_sort(), and inittapes().

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

Definition at line 1763 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().

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

Definition at line 1475 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().

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

Definition at line 1376 of file tuplesort.c.

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

Referenced by copy_heap_data().

1377 {
1378  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1379  SortTuple stup;
1380 
1381  /*
1382  * Copy the given tuple into memory we control, and decrease availMem.
1383  * Then call the common code.
1384  */
1385  COPYTUP(state, &stup, (void *) tup);
1386 
1387  puttuple_common(state, &stup);
1388 
1389  MemoryContextSwitchTo(oldcontext);
1390 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext sortcontext
Definition: tuplesort.c:284
#define COPYTUP(state, stup, tup)
Definition: tuplesort.c:518
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple)
Definition: tuplesort.c:1557
void tuplesort_putindextuplevalues ( Tuplesortstate state,
Relation  rel,
ItemPointer  self,
Datum values,
bool isnull 
)

Definition at line 1397 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().

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

Definition at line 1354 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().

1355 {
1356  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1357  SortTuple stup;
1358 
1359  /*
1360  * Copy the given tuple into memory we control, and decrease availMem.
1361  * Then call the common code.
1362  */
1363  COPYTUP(state, &stup, (void *) slot);
1364 
1365  puttuple_common(state, &stup);
1366 
1367  MemoryContextSwitchTo(oldcontext);
1368 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext sortcontext
Definition: tuplesort.c:284
#define COPYTUP(state, stup, tup)
Definition: tuplesort.c:518
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple)
Definition: tuplesort.c:1557
void tuplesort_rescan ( Tuplesortstate state)

Definition at line 3115 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().

3116 {
3117  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3118 
3119  Assert(state->randomAccess);
3120 
3121  switch (state->status)
3122  {
3123  case TSS_SORTEDINMEM:
3124  state->current = 0;
3125  state->eof_reached = false;
3126  state->markpos_offset = 0;
3127  state->markpos_eof = false;
3128  break;
3129  case TSS_SORTEDONTAPE:
3131  state->result_tape,
3132  0);
3133  state->eof_reached = false;
3134  state->markpos_block = 0L;
3135  state->markpos_offset = 0;
3136  state->markpos_eof = false;
3137  break;
3138  default:
3139  elog(ERROR, "invalid tuplesort state");
3140  break;
3141  }
3142 
3143  MemoryContextSwitchTo(oldcontext);
3144 }
TupSortStatus status
Definition: tuplesort.c:272
bool randomAccess
Definition: tuplesort.c:274
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int markpos_offset
Definition: tuplesort.c:432
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:284
LogicalTapeSet * tapeset
Definition: tuplesort.c:286
#define Assert(condition)
Definition: c.h:670
long markpos_block
Definition: tuplesort.c:431
bool eof_reached
Definition: tuplesort.c:428
void LogicalTapeRewindForRead(LogicalTapeSet *lts, int tapenum, size_t buffer_size)
Definition: logtape.c:551
bool markpos_eof
Definition: tuplesort.c:433
#define elog
Definition: elog.h:219
void tuplesort_restorepos ( Tuplesortstate state)

Definition at line 3182 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().

3183 {
3184  MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
3185 
3186  Assert(state->randomAccess);
3187 
3188  switch (state->status)
3189  {
3190  case TSS_SORTEDINMEM:
3191  state->current = state->markpos_offset;
3192  state->eof_reached = state->markpos_eof;
3193  break;
3194  case TSS_SORTEDONTAPE:
3195  LogicalTapeSeek(state->tapeset,
3196  state->result_tape,
3197  state->markpos_block,
3198  state->markpos_offset);
3199  state->eof_reached = state->markpos_eof;
3200  break;
3201  default:
3202  elog(ERROR, "invalid tuplesort state");
3203  break;
3204  }
3205 
3206  MemoryContextSwitchTo(oldcontext);
3207 }
TupSortStatus status
Definition: tuplesort.c:272
bool randomAccess
Definition: tuplesort.c:274
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int markpos_offset
Definition: tuplesort.c:432
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:284
LogicalTapeSet * tapeset
Definition: tuplesort.c:286
#define Assert(condition)
Definition: c.h:670
long markpos_block
Definition: tuplesort.c:431
bool eof_reached
Definition: tuplesort.c:428
bool markpos_eof
Definition: tuplesort.c:433
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 1113 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().

1114 {
1115  /* Assert we're called before loading any tuples */
1116  Assert(state->status == TSS_INITIAL);
1117  Assert(state->memtupcount == 0);
1118  Assert(!state->bounded);
1119 
1120 #ifdef DEBUG_BOUNDED_SORT
1121  /* Honor GUC setting that disables the feature (for easy testing) */
1122  if (!optimize_bounded_sort)
1123  return;
1124 #endif
1125 
1126  /* We want to be able to compute bound * 2, so limit the setting */
1127  if (bound > (int64) (INT_MAX / 2))
1128  return;
1129 
1130  state->bounded = true;
1131  state->bound = (int) bound;
1132 
1133  /*
1134  * Bounded sorts are not an effective target for abbreviated key
1135  * optimization. Disable by setting state to be consistent with no
1136  * abbreviation support.
1137  */
1138  state->sortKeys->abbrev_converter = NULL;
1139  if (state->sortKeys->abbrev_full_comparator)
1141 
1142  /* Not strictly necessary, but be tidy */
1143  state->sortKeys->abbrev_abort = NULL;
1145 }
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:107
TupSortStatus status
Definition: tuplesort.c:272
SortSupport sortKeys
Definition: tuplesort.c:441
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:192
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
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 2222 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().

2223 {
2224  MemoryContext oldcontext;
2225 
2226  /*
2227  * We don't actually support backwards skip yet, because no callers need
2228  * it. The API is designed to allow for that later, though.
2229  */
2230  Assert(forward);
2231  Assert(ntuples >= 0);
2232 
2233  switch (state->status)
2234  {
2235  case TSS_SORTEDINMEM:
2236  if (state->memtupcount - state->current >= ntuples)
2237  {
2238  state->current += ntuples;
2239  return true;
2240  }
2241  state->current = state->memtupcount;
2242  state->eof_reached = true;
2243 
2244  /*
2245  * Complain if caller tries to retrieve more tuples than
2246  * originally asked for in a bounded sort. This is because
2247  * returning EOF here might be the wrong thing.
2248  */
2249  if (state->bounded && state->current >= state->bound)
2250  elog(ERROR, "retrieved too many tuples in a bounded sort");
2251 
2252  return false;
2253 
2254  case TSS_SORTEDONTAPE:
2255  case TSS_FINALMERGE:
2256 
2257  /*
2258  * We could probably optimize these cases better, but for now it's
2259  * not worth the trouble.
2260  */
2261  oldcontext = MemoryContextSwitchTo(state->sortcontext);
2262  while (ntuples-- > 0)
2263  {
2264  SortTuple stup;
2265 
2266  if (!tuplesort_gettuple_common(state, forward, &stup))
2267  {
2268  MemoryContextSwitchTo(oldcontext);
2269  return false;
2270  }
2272  }
2273  MemoryContextSwitchTo(oldcontext);
2274  return true;
2275 
2276  default:
2277  elog(ERROR, "invalid tuplesort state");
2278  return false; /* keep compiler quiet */
2279  }
2280 }
TupSortStatus status
Definition: tuplesort.c:272
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ERROR
Definition: elog.h:43
MemoryContext sortcontext
Definition: tuplesort.c:284
static bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1848
#define Assert(condition)
Definition: c.h:670
bool eof_reached
Definition: tuplesort.c:428
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
#define elog
Definition: elog.h:219