PostgreSQL Source Code  git master
tuplesortvariants.c File Reference
#include "postgres.h"
#include "access/hash.h"
#include "access/htup_details.h"
#include "access/nbtree.h"
#include "catalog/index.h"
#include "executor/executor.h"
#include "pg_trace.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/guc.h"
#include "utils/tuplesort.h"
Include dependency graph for tuplesortvariants.c:

Go to the source code of this file.

Data Structures

struct  TuplesortClusterArg
 
struct  TuplesortIndexArg
 
struct  TuplesortIndexBTreeArg
 
struct  TuplesortIndexHashArg
 
struct  TuplesortDatumArg
 

Macros

#define HEAP_SORT   0
 
#define INDEX_SORT   1
 
#define DATUM_SORT   2
 
#define CLUSTER_SORT   3
 

Functions

static void removeabbrev_heap (Tuplesortstate *state, SortTuple *stups, int count)
 
static void removeabbrev_cluster (Tuplesortstate *state, SortTuple *stups, int count)
 
static void removeabbrev_index (Tuplesortstate *state, SortTuple *stups, int count)
 
static void removeabbrev_datum (Tuplesortstate *state, SortTuple *stups, int count)
 
static int comparetup_heap (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static void writetup_heap (Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
 
static void readtup_heap (Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
 
static int comparetup_cluster (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static void writetup_cluster (Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
 
static void readtup_cluster (Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int tuplen)
 
static int comparetup_index_btree (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static int comparetup_index_hash (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static void writetup_index (Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
 
static void readtup_index (Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
 
static int comparetup_datum (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static void writetup_datum (Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
 
static void readtup_datum (Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
 
static void freestate_cluster (Tuplesortstate *state)
 
Tuplesortstatetuplesort_begin_heap (TupleDesc tupDesc, int nkeys, AttrNumber *attNums, Oid *sortOperators, Oid *sortCollations, bool *nullsFirstFlags, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_cluster (TupleDesc tupDesc, Relation indexRel, Relation heaprel, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_index_btree (Relation heapRel, Relation indexRel, bool enforceUnique, bool uniqueNullsNotDistinct, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_index_hash (Relation heapRel, Relation indexRel, uint32 high_mask, uint32 low_mask, uint32 max_buckets, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_index_gist (Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_datum (Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, SortCoordinate coordinate, int sortopt)
 
void tuplesort_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)
 
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, bool copy, Datum *val, bool *isNull, Datum *abbrev)
 

Macro Definition Documentation

◆ CLUSTER_SORT

#define CLUSTER_SORT   3

Definition at line 38 of file tuplesortvariants.c.

◆ DATUM_SORT

#define DATUM_SORT   2

Definition at line 37 of file tuplesortvariants.c.

◆ HEAP_SORT

#define HEAP_SORT   0

Definition at line 35 of file tuplesortvariants.c.

◆ INDEX_SORT

#define INDEX_SORT   1

Definition at line 36 of file tuplesortvariants.c.

Function Documentation

◆ comparetup_cluster()

static int comparetup_cluster ( const SortTuple a,
const SortTuple b,
Tuplesortstate state 
)
static

Definition at line 1063 of file tuplesortvariants.c.

1065 {
1068  SortSupport sortKey = base->sortKeys;
1069  HeapTuple ltup;
1070  HeapTuple rtup;
1071  TupleDesc tupDesc;
1072  int nkey;
1073  int32 compare;
1074  Datum datum1,
1075  datum2;
1076  bool isnull1,
1077  isnull2;
1078 
1079  /* Be prepared to compare additional sort keys */
1080  ltup = (HeapTuple) a->tuple;
1081  rtup = (HeapTuple) b->tuple;
1082  tupDesc = arg->tupDesc;
1083 
1084  /* Compare the leading sort key, if it's simple */
1085  if (base->haveDatum1)
1086  {
1087  compare = ApplySortComparator(a->datum1, a->isnull1,
1088  b->datum1, b->isnull1,
1089  sortKey);
1090  if (compare != 0)
1091  return compare;
1092 
1093  if (sortKey->abbrev_converter)
1094  {
1095  AttrNumber leading = arg->indexInfo->ii_IndexAttrNumbers[0];
1096 
1097  datum1 = heap_getattr(ltup, leading, tupDesc, &isnull1);
1098  datum2 = heap_getattr(rtup, leading, tupDesc, &isnull2);
1099 
1100  compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1101  datum2, isnull2,
1102  sortKey);
1103  }
1104  if (compare != 0 || base->nKeys == 1)
1105  return compare;
1106  /* Compare additional columns the hard way */
1107  sortKey++;
1108  nkey = 1;
1109  }
1110  else
1111  {
1112  /* Must compare all keys the hard way */
1113  nkey = 0;
1114  }
1115 
1116  if (arg->indexInfo->ii_Expressions == NULL)
1117  {
1118  /* If not expression index, just compare the proper heap attrs */
1119 
1120  for (; nkey < base->nKeys; nkey++, sortKey++)
1121  {
1122  AttrNumber attno = arg->indexInfo->ii_IndexAttrNumbers[nkey];
1123 
1124  datum1 = heap_getattr(ltup, attno, tupDesc, &isnull1);
1125  datum2 = heap_getattr(rtup, attno, tupDesc, &isnull2);
1126 
1127  compare = ApplySortComparator(datum1, isnull1,
1128  datum2, isnull2,
1129  sortKey);
1130  if (compare != 0)
1131  return compare;
1132  }
1133  }
1134  else
1135  {
1136  /*
1137  * In the expression index case, compute the whole index tuple and
1138  * then compare values. It would perhaps be faster to compute only as
1139  * many columns as we need to compare, but that would require
1140  * duplicating all the logic in FormIndexDatum.
1141  */
1142  Datum l_index_values[INDEX_MAX_KEYS];
1143  bool l_index_isnull[INDEX_MAX_KEYS];
1144  Datum r_index_values[INDEX_MAX_KEYS];
1145  bool r_index_isnull[INDEX_MAX_KEYS];
1146  TupleTableSlot *ecxt_scantuple;
1147 
1148  /* Reset context each time to prevent memory leakage */
1149  ResetPerTupleExprContext(arg->estate);
1150 
1151  ecxt_scantuple = GetPerTupleExprContext(arg->estate)->ecxt_scantuple;
1152 
1153  ExecStoreHeapTuple(ltup, ecxt_scantuple, false);
1154  FormIndexDatum(arg->indexInfo, ecxt_scantuple, arg->estate,
1155  l_index_values, l_index_isnull);
1156 
1157  ExecStoreHeapTuple(rtup, ecxt_scantuple, false);
1158  FormIndexDatum(arg->indexInfo, ecxt_scantuple, arg->estate,
1159  r_index_values, r_index_isnull);
1160 
1161  for (; nkey < base->nKeys; nkey++, sortKey++)
1162  {
1163  compare = ApplySortComparator(l_index_values[nkey],
1164  l_index_isnull[nkey],
1165  r_index_values[nkey],
1166  r_index_isnull[nkey],
1167  sortKey);
1168  if (compare != 0)
1169  return compare;
1170  }
1171  }
1172 
1173  return 0;
1174 }
int16 AttrNumber
Definition: attnum.h:21
signed int int32
Definition: c.h:478
TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1353
#define ResetPerTupleExprContext(estate)
Definition: executor.h:558
#define GetPerTupleExprContext(estate)
Definition: executor.h:549
static int compare(const void *arg1, const void *arg2)
Definition: geqo_pool.c:145
HeapTupleData * HeapTuple
Definition: htup.h:71
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:2721
int b
Definition: isn.c:70
int a
Definition: isn.c:69
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
void * arg
#define INDEX_MAX_KEYS
uintptr_t Datum
Definition: postgres.h:64
static int ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
Definition: sortsupport.h:341
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
Definition: sortsupport.h:200
SortSupport sortKeys
Definition: tuplesort.h:217
Definition: regguts.h:323
#define TuplesortstateGetPublic(state)
Definition: tuplesort.h:241

References a, ApplySortAbbrevFullComparator(), ApplySortComparator(), arg, TuplesortPublic::arg, b, compare(), ExecStoreHeapTuple(), FormIndexDatum(), GetPerTupleExprContext, TuplesortPublic::haveDatum1, heap_getattr(), if(), INDEX_MAX_KEYS, TuplesortPublic::nKeys, ResetPerTupleExprContext, TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_cluster().

◆ comparetup_datum()

static int comparetup_datum ( const SortTuple a,
const SortTuple b,
Tuplesortstate state 
)
static

Definition at line 1519 of file tuplesortvariants.c.

1520 {
1522  int compare;
1523 
1524  compare = ApplySortComparator(a->datum1, a->isnull1,
1525  b->datum1, b->isnull1,
1526  base->sortKeys);
1527  if (compare != 0)
1528  return compare;
1529 
1530  /* if we have abbreviations, then "tuple" has the original value */
1531 
1532  if (base->sortKeys->abbrev_converter)
1534  PointerGetDatum(b->tuple), b->isnull1,
1535  base->sortKeys);
1536 
1537  return compare;
1538 }
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:172

References a, SortSupportData::abbrev_converter, ApplySortAbbrevFullComparator(), ApplySortComparator(), b, compare(), PointerGetDatum(), TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_datum().

◆ comparetup_heap()

static int comparetup_heap ( const SortTuple a,
const SortTuple b,
Tuplesortstate state 
)
static

Definition at line 931 of file tuplesortvariants.c.

932 {
934  SortSupport sortKey = base->sortKeys;
935  HeapTupleData ltup;
936  HeapTupleData rtup;
937  TupleDesc tupDesc;
938  int nkey;
939  int32 compare;
940  AttrNumber attno;
941  Datum datum1,
942  datum2;
943  bool isnull1,
944  isnull2;
945 
946 
947  /* Compare the leading sort key */
948  compare = ApplySortComparator(a->datum1, a->isnull1,
949  b->datum1, b->isnull1,
950  sortKey);
951  if (compare != 0)
952  return compare;
953 
954  /* Compare additional sort keys */
955  ltup.t_len = ((MinimalTuple) a->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
956  ltup.t_data = (HeapTupleHeader) ((char *) a->tuple - MINIMAL_TUPLE_OFFSET);
957  rtup.t_len = ((MinimalTuple) b->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
958  rtup.t_data = (HeapTupleHeader) ((char *) b->tuple - MINIMAL_TUPLE_OFFSET);
959  tupDesc = (TupleDesc) base->arg;
960 
961  if (sortKey->abbrev_converter)
962  {
963  attno = sortKey->ssup_attno;
964 
965  datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
966  datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
967 
968  compare = ApplySortAbbrevFullComparator(datum1, isnull1,
969  datum2, isnull2,
970  sortKey);
971  if (compare != 0)
972  return compare;
973  }
974 
975  sortKey++;
976  for (nkey = 1; nkey < base->nKeys; nkey++, sortKey++)
977  {
978  attno = sortKey->ssup_attno;
979 
980  datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
981  datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
982 
983  compare = ApplySortComparator(datum1, isnull1,
984  datum2, isnull2,
985  sortKey);
986  if (compare != 0)
987  return compare;
988  }
989 
990  return 0;
991 }
MinimalTupleData * MinimalTuple
Definition: htup.h:27
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:617
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
AttrNumber ssup_attno
Definition: sortsupport.h:81
struct TupleDescData * TupleDesc
Definition: tupdesc.h:89

References a, SortSupportData::abbrev_converter, ApplySortAbbrevFullComparator(), ApplySortComparator(), TuplesortPublic::arg, b, compare(), heap_getattr(), if(), MINIMAL_TUPLE_OFFSET, TuplesortPublic::nKeys, TuplesortPublic::sortKeys, SortSupportData::ssup_attno, HeapTupleData::t_data, HeapTupleData::t_len, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_heap().

◆ comparetup_index_btree()

static int comparetup_index_btree ( const SortTuple a,
const SortTuple b,
Tuplesortstate state 
)
static

Definition at line 1264 of file tuplesortvariants.c.

1266 {
1267  /*
1268  * This is similar to comparetup_heap(), but expects index tuples. There
1269  * is also special handling for enforcing uniqueness, and special
1270  * treatment for equal keys at the end.
1271  */
1274  SortSupport sortKey = base->sortKeys;
1275  IndexTuple tuple1;
1276  IndexTuple tuple2;
1277  int keysz;
1278  TupleDesc tupDes;
1279  bool equal_hasnull = false;
1280  int nkey;
1281  int32 compare;
1282  Datum datum1,
1283  datum2;
1284  bool isnull1,
1285  isnull2;
1286 
1287 
1288  /* Compare the leading sort key */
1289  compare = ApplySortComparator(a->datum1, a->isnull1,
1290  b->datum1, b->isnull1,
1291  sortKey);
1292  if (compare != 0)
1293  return compare;
1294 
1295  /* Compare additional sort keys */
1296  tuple1 = (IndexTuple) a->tuple;
1297  tuple2 = (IndexTuple) b->tuple;
1298  keysz = base->nKeys;
1299  tupDes = RelationGetDescr(arg->index.indexRel);
1300 
1301  if (sortKey->abbrev_converter)
1302  {
1303  datum1 = index_getattr(tuple1, 1, tupDes, &isnull1);
1304  datum2 = index_getattr(tuple2, 1, tupDes, &isnull2);
1305 
1306  compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1307  datum2, isnull2,
1308  sortKey);
1309  if (compare != 0)
1310  return compare;
1311  }
1312 
1313  /* they are equal, so we only need to examine one null flag */
1314  if (a->isnull1)
1315  equal_hasnull = true;
1316 
1317  sortKey++;
1318  for (nkey = 2; nkey <= keysz; nkey++, sortKey++)
1319  {
1320  datum1 = index_getattr(tuple1, nkey, tupDes, &isnull1);
1321  datum2 = index_getattr(tuple2, nkey, tupDes, &isnull2);
1322 
1323  compare = ApplySortComparator(datum1, isnull1,
1324  datum2, isnull2,
1325  sortKey);
1326  if (compare != 0)
1327  return compare; /* done when we find unequal attributes */
1328 
1329  /* they are equal, so we only need to examine one null flag */
1330  if (isnull1)
1331  equal_hasnull = true;
1332  }
1333 
1334  /*
1335  * If btree has asked us to enforce uniqueness, complain if two equal
1336  * tuples are detected (unless there was at least one NULL field and NULLS
1337  * NOT DISTINCT was not set).
1338  *
1339  * It is sufficient to make the test here, because if two tuples are equal
1340  * they *must* get compared at some stage of the sort --- otherwise the
1341  * sort algorithm wouldn't have checked whether one must appear before the
1342  * other.
1343  */
1344  if (arg->enforceUnique && !(!arg->uniqueNullsNotDistinct && equal_hasnull))
1345  {
1347  bool isnull[INDEX_MAX_KEYS];
1348  char *key_desc;
1349 
1350  /*
1351  * Some rather brain-dead implementations of qsort (such as the one in
1352  * QNX 4) will sometimes call the comparison routine to compare a
1353  * value to itself, but we always use our own implementation, which
1354  * does not.
1355  */
1356  Assert(tuple1 != tuple2);
1357 
1358  index_deform_tuple(tuple1, tupDes, values, isnull);
1359 
1360  key_desc = BuildIndexValueDescription(arg->index.indexRel, values, isnull);
1361 
1362  ereport(ERROR,
1363  (errcode(ERRCODE_UNIQUE_VIOLATION),
1364  errmsg("could not create unique index \"%s\"",
1365  RelationGetRelationName(arg->index.indexRel)),
1366  key_desc ? errdetail("Key %s is duplicated.", key_desc) :
1367  errdetail("Duplicate keys exist."),
1368  errtableconstraint(arg->index.heapRel,
1369  RelationGetRelationName(arg->index.indexRel))));
1370  }
1371 
1372  /*
1373  * If key values are equal, we sort on ItemPointer. This is required for
1374  * btree indexes, since heap TID is treated as an implicit last key
1375  * attribute in order to ensure that all keys in the index are physically
1376  * unique.
1377  */
1378  {
1379  BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid);
1380  BlockNumber blk2 = ItemPointerGetBlockNumber(&tuple2->t_tid);
1381 
1382  if (blk1 != blk2)
1383  return (blk1 < blk2) ? -1 : 1;
1384  }
1385  {
1386  OffsetNumber pos1 = ItemPointerGetOffsetNumber(&tuple1->t_tid);
1387  OffsetNumber pos2 = ItemPointerGetOffsetNumber(&tuple2->t_tid);
1388 
1389  if (pos1 != pos2)
1390  return (pos1 < pos2) ? -1 : 1;
1391  }
1392 
1393  /* ItemPointer values should never be equal */
1394  Assert(false);
1395 
1396  return 0;
1397 }
uint32 BlockNumber
Definition: block.h:31
static Datum values[MAXATTR]
Definition: bootstrap.c:156
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
char * BuildIndexValueDescription(Relation indexRelation, Datum *values, bool *isnull)
Definition: genam.c:177
void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: indextuple.c:456
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
IndexTupleData * IndexTuple
Definition: itup.h:53
static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: itup.h:117
Assert(fmt[strlen(fmt) - 1] !='\n')
uint16 OffsetNumber
Definition: off.h:24
#define RelationGetDescr(relation)
Definition: rel.h:530
#define RelationGetRelationName(relation)
Definition: rel.h:538
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5960

References a, ApplySortAbbrevFullComparator(), ApplySortComparator(), arg, TuplesortPublic::arg, Assert(), b, BuildIndexValueDescription(), compare(), ereport, errcode(), errdetail(), errmsg(), ERROR, errtableconstraint(), index_deform_tuple(), index_getattr(), INDEX_MAX_KEYS, ItemPointerGetBlockNumber(), ItemPointerGetOffsetNumber(), TuplesortPublic::nKeys, RelationGetDescr, RelationGetRelationName, TuplesortPublic::sortKeys, TuplesortstateGetPublic, and values.

Referenced by tuplesort_begin_index_btree(), and tuplesort_begin_index_gist().

◆ comparetup_index_hash()

static int comparetup_index_hash ( const SortTuple a,
const SortTuple b,
Tuplesortstate state 
)
static

Definition at line 1400 of file tuplesortvariants.c.

1402 {
1403  Bucket bucket1;
1404  Bucket bucket2;
1405  uint32 hash1;
1406  uint32 hash2;
1407  IndexTuple tuple1;
1408  IndexTuple tuple2;
1411 
1412  /*
1413  * Fetch hash keys and mask off bits we don't want to sort by, so that the
1414  * initial sort is just on the bucket number. We know that the first
1415  * column of the index tuple is the hash key.
1416  */
1417  Assert(!a->isnull1);
1418  bucket1 = _hash_hashkey2bucket(DatumGetUInt32(a->datum1),
1419  arg->max_buckets, arg->high_mask,
1420  arg->low_mask);
1421  Assert(!b->isnull1);
1422  bucket2 = _hash_hashkey2bucket(DatumGetUInt32(b->datum1),
1423  arg->max_buckets, arg->high_mask,
1424  arg->low_mask);
1425  if (bucket1 > bucket2)
1426  return 1;
1427  else if (bucket1 < bucket2)
1428  return -1;
1429 
1430  /*
1431  * If bucket values are equal, sort by hash values. This allows us to
1432  * insert directly onto bucket/overflow pages, where the index tuples are
1433  * stored in hash order to allow fast binary search within each page.
1434  */
1435  hash1 = DatumGetUInt32(a->datum1);
1436  hash2 = DatumGetUInt32(b->datum1);
1437  if (hash1 > hash2)
1438  return 1;
1439  else if (hash1 < hash2)
1440  return -1;
1441 
1442  /*
1443  * If hash values are equal, we sort on ItemPointer. This does not affect
1444  * validity of the finished index, but it may be useful to have index
1445  * scans in physical order.
1446  */
1447  tuple1 = (IndexTuple) a->tuple;
1448  tuple2 = (IndexTuple) b->tuple;
1449 
1450  {
1451  BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid);
1452  BlockNumber blk2 = ItemPointerGetBlockNumber(&tuple2->t_tid);
1453 
1454  if (blk1 != blk2)
1455  return (blk1 < blk2) ? -1 : 1;
1456  }
1457  {
1460 
1461  if (pos1 != pos2)
1462  return (pos1 < pos2) ? -1 : 1;
1463  }
1464 
1465  /* ItemPointer values should never be equal */
1466  Assert(false);
1467 
1468  return 0;
1469 }
unsigned int uint32
Definition: c.h:490
uint32 Bucket
Definition: hash.h:35
Bucket _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket, uint32 highmask, uint32 lowmask)
Definition: hashutil.c:126
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:222
ItemPointerData t_tid
Definition: itup.h:37

References _hash_hashkey2bucket(), a, arg, TuplesortPublic::arg, Assert(), b, DatumGetUInt32(), ItemPointerGetBlockNumber(), ItemPointerGetOffsetNumber(), IndexTupleData::t_tid, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_hash().

◆ freestate_cluster()

static void freestate_cluster ( Tuplesortstate state)
static

Definition at line 1221 of file tuplesortvariants.c.

1222 {
1225 
1226  /* Free any execution state created for CLUSTER case */
1227  if (arg->estate != NULL)
1228  {
1229  ExprContext *econtext = GetPerTupleExprContext(arg->estate);
1230 
1232  FreeExecutorState(arg->estate);
1233  }
1234 }
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1255
void FreeExecutorState(EState *estate)
Definition: execUtils.c:194
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:249

References arg, TuplesortPublic::arg, ExprContext::ecxt_scantuple, ExecDropSingleTupleTableSlot(), FreeExecutorState(), GetPerTupleExprContext, if(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_cluster().

◆ readtup_cluster()

static void readtup_cluster ( Tuplesortstate state,
SortTuple stup,
LogicalTape tape,
unsigned int  tuplen 
)
static

Definition at line 1192 of file tuplesortvariants.c.

1194 {
1197  unsigned int t_len = tuplen - sizeof(ItemPointerData) - sizeof(int);
1199  t_len + HEAPTUPLESIZE);
1200 
1201  /* Reconstruct the HeapTupleData header */
1202  tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1203  tuple->t_len = t_len;
1204  LogicalTapeReadExact(tape, &tuple->t_self, sizeof(ItemPointerData));
1205  /* We don't currently bother to reconstruct t_tableOid */
1206  tuple->t_tableOid = InvalidOid;
1207  /* Read in the tuple body */
1208  LogicalTapeReadExact(tape, tuple->t_data, tuple->t_len);
1209  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1210  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1211  stup->tuple = (void *) tuple;
1212  /* set up first-column key value, if it's a simple column */
1213  if (base->haveDatum1)
1214  stup->datum1 = heap_getattr(tuple,
1215  arg->indexInfo->ii_IndexAttrNumbers[0],
1216  arg->tupDesc,
1217  &stup->isnull1);
1218 }
#define HEAPTUPLESIZE
Definition: htup.h:73
#define InvalidOid
Definition: postgres_ext.h:36
ItemPointerData t_self
Definition: htup.h:65
Oid t_tableOid
Definition: htup.h:66
bool isnull1
Definition: tuplesort.h:140
void * tuple
Definition: tuplesort.h:138
Datum datum1
Definition: tuplesort.h:139
void * tuplesort_readtup_alloc(Tuplesortstate *state, Size tuplen)
Definition: tuplesort.c:2921
#define TUPLESORT_RANDOMACCESS
Definition: tuplesort.h:95
#define LogicalTapeReadExact(tape, ptr, len)
Definition: tuplesort.h:244

References arg, TuplesortPublic::arg, SortTuple::datum1, TuplesortPublic::haveDatum1, heap_getattr(), HEAPTUPLESIZE, InvalidOid, SortTuple::isnull1, LogicalTapeReadExact, TuplesortPublic::sortopt, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, SortTuple::tuple, TUPLESORT_RANDOMACCESS, tuplesort_readtup_alloc(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_cluster().

◆ readtup_datum()

static void readtup_datum ( Tuplesortstate state,
SortTuple stup,
LogicalTape tape,
unsigned int  len 
)
static

Definition at line 1575 of file tuplesortvariants.c.

1577 {
1579  unsigned int tuplen = len - sizeof(unsigned int);
1580 
1581  if (tuplen == 0)
1582  {
1583  /* it's NULL */
1584  stup->datum1 = (Datum) 0;
1585  stup->isnull1 = true;
1586  stup->tuple = NULL;
1587  }
1588  else if (!base->tuples)
1589  {
1590  Assert(tuplen == sizeof(Datum));
1591  LogicalTapeReadExact(tape, &stup->datum1, tuplen);
1592  stup->isnull1 = false;
1593  stup->tuple = NULL;
1594  }
1595  else
1596  {
1597  void *raddr = tuplesort_readtup_alloc(state, tuplen);
1598 
1599  LogicalTapeReadExact(tape, raddr, tuplen);
1600  stup->datum1 = PointerGetDatum(raddr);
1601  stup->isnull1 = false;
1602  stup->tuple = raddr;
1603  }
1604 
1605  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1606  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1607 }
const void size_t len

References Assert(), SortTuple::datum1, SortTuple::isnull1, len, LogicalTapeReadExact, PointerGetDatum(), TuplesortPublic::sortopt, SortTuple::tuple, TuplesortPublic::tuples, TUPLESORT_RANDOMACCESS, tuplesort_readtup_alloc(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_datum().

◆ readtup_heap()

static void readtup_heap ( Tuplesortstate state,
SortTuple stup,
LogicalTape tape,
unsigned int  len 
)
static

Definition at line 1013 of file tuplesortvariants.c.

1015 {
1016  unsigned int tupbodylen = len - sizeof(int);
1017  unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
1019  char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1021  HeapTupleData htup;
1022 
1023  /* read in the tuple proper */
1024  tuple->t_len = tuplen;
1025  LogicalTapeReadExact(tape, tupbody, tupbodylen);
1026  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1027  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1028  stup->tuple = (void *) tuple;
1029  /* set up first-column key value */
1030  htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
1031  htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
1032  stup->datum1 = heap_getattr(&htup,
1033  base->sortKeys[0].ssup_attno,
1034  (TupleDesc) base->arg,
1035  &stup->isnull1);
1036 }
#define MINIMAL_TUPLE_DATA_OFFSET
Definition: htup_details.h:621

References TuplesortPublic::arg, SortTuple::datum1, heap_getattr(), SortTuple::isnull1, len, LogicalTapeReadExact, MINIMAL_TUPLE_DATA_OFFSET, MINIMAL_TUPLE_OFFSET, TuplesortPublic::sortKeys, TuplesortPublic::sortopt, SortSupportData::ssup_attno, HeapTupleData::t_data, HeapTupleData::t_len, MinimalTupleData::t_len, SortTuple::tuple, TUPLESORT_RANDOMACCESS, tuplesort_readtup_alloc(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_heap().

◆ readtup_index()

static void readtup_index ( Tuplesortstate state,
SortTuple stup,
LogicalTape tape,
unsigned int  len 
)
static

Definition at line 1486 of file tuplesortvariants.c.

1488 {
1491  unsigned int tuplen = len - sizeof(unsigned int);
1493 
1494  LogicalTapeReadExact(tape, tuple, tuplen);
1495  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1496  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1497  stup->tuple = (void *) tuple;
1498  /* set up first-column key value */
1499  stup->datum1 = index_getattr(tuple,
1500  1,
1501  RelationGetDescr(arg->indexRel),
1502  &stup->isnull1);
1503 }

References arg, TuplesortPublic::arg, SortTuple::datum1, index_getattr(), SortTuple::isnull1, len, LogicalTapeReadExact, RelationGetDescr, TuplesortPublic::sortopt, SortTuple::tuple, TUPLESORT_RANDOMACCESS, tuplesort_readtup_alloc(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_btree(), tuplesort_begin_index_gist(), and tuplesort_begin_index_hash().

◆ removeabbrev_cluster()

static void removeabbrev_cluster ( Tuplesortstate state,
SortTuple stups,
int  count 
)
static

Definition at line 1044 of file tuplesortvariants.c.

1045 {
1046  int i;
1049 
1050  for (i = 0; i < count; i++)
1051  {
1052  HeapTuple tup;
1053 
1054  tup = (HeapTuple) stups[i].tuple;
1055  stups[i].datum1 = heap_getattr(tup,
1056  arg->indexInfo->ii_IndexAttrNumbers[0],
1057  arg->tupDesc,
1058  &stups[i].isnull1);
1059  }
1060 }
int i
Definition: isn.c:73

References arg, TuplesortPublic::arg, SortTuple::datum1, heap_getattr(), i, SortTuple::isnull1, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_cluster().

◆ removeabbrev_datum()

static void removeabbrev_datum ( Tuplesortstate state,
SortTuple stups,
int  count 
)
static

Definition at line 1510 of file tuplesortvariants.c.

1511 {
1512  int i;
1513 
1514  for (i = 0; i < count; i++)
1515  stups[i].datum1 = PointerGetDatum(stups[i].tuple);
1516 }

References i, and PointerGetDatum().

Referenced by tuplesort_begin_datum().

◆ removeabbrev_heap()

static void removeabbrev_heap ( Tuplesortstate state,
SortTuple stups,
int  count 
)
static

Definition at line 910 of file tuplesortvariants.c.

911 {
912  int i;
914 
915  for (i = 0; i < count; i++)
916  {
917  HeapTupleData htup;
918 
919  htup.t_len = ((MinimalTuple) stups[i].tuple)->t_len +
921  htup.t_data = (HeapTupleHeader) ((char *) stups[i].tuple -
923  stups[i].datum1 = heap_getattr(&htup,
924  base->sortKeys[0].ssup_attno,
925  (TupleDesc) base->arg,
926  &stups[i].isnull1);
927  }
928 }

References TuplesortPublic::arg, SortTuple::datum1, heap_getattr(), i, SortTuple::isnull1, MINIMAL_TUPLE_OFFSET, TuplesortPublic::sortKeys, SortSupportData::ssup_attno, HeapTupleData::t_data, HeapTupleData::t_len, SortTuple::tuple, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_heap().

◆ removeabbrev_index()

static void removeabbrev_index ( Tuplesortstate state,
SortTuple stups,
int  count 
)
static

Definition at line 1245 of file tuplesortvariants.c.

1246 {
1249  int i;
1250 
1251  for (i = 0; i < count; i++)
1252  {
1253  IndexTuple tuple;
1254 
1255  tuple = stups[i].tuple;
1256  stups[i].datum1 = index_getattr(tuple,
1257  1,
1258  RelationGetDescr(arg->indexRel),
1259  &stups[i].isnull1);
1260  }
1261 }

References arg, TuplesortPublic::arg, SortTuple::datum1, i, index_getattr(), SortTuple::isnull1, RelationGetDescr, SortTuple::tuple, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_btree(), tuplesort_begin_index_gist(), and tuplesort_begin_index_hash().

◆ tuplesort_begin_cluster()

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

Definition at line 208 of file tuplesortvariants.c.

213 {
214  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
215  sortopt);
217  BTScanInsert indexScanKey;
218  MemoryContext oldcontext;
220  int i;
221 
222  Assert(indexRel->rd_rel->relam == BTREE_AM_OID);
223 
224  oldcontext = MemoryContextSwitchTo(base->maincontext);
226 
227 #ifdef TRACE_SORT
228  if (trace_sort)
229  elog(LOG,
230  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
232  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
233 #endif
234 
236 
237  TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
238  false, /* no unique check */
239  base->nKeys,
240  workMem,
241  sortopt & TUPLESORT_RANDOMACCESS,
242  PARALLEL_SORT(coordinate));
243 
246  base->writetup = writetup_cluster;
247  base->readtup = readtup_cluster;
249  base->arg = arg;
250 
251  arg->indexInfo = BuildIndexInfo(indexRel);
252 
253  /*
254  * If we don't have a simple leading attribute, we don't currently
255  * initialize datum1, so disable optimizations that require it.
256  */
257  if (arg->indexInfo->ii_IndexAttrNumbers[0] == 0)
258  base->haveDatum1 = false;
259  else
260  base->haveDatum1 = true;
261 
262  arg->tupDesc = tupDesc; /* assume we need not copy tupDesc */
263 
264  indexScanKey = _bt_mkscankey(indexRel, heaprel, NULL);
265 
266  if (arg->indexInfo->ii_Expressions != NULL)
267  {
268  TupleTableSlot *slot;
269  ExprContext *econtext;
270 
271  /*
272  * We will need to use FormIndexDatum to evaluate the index
273  * expressions. To do that, we need an EState, as well as a
274  * TupleTableSlot to put the table tuples into. The econtext's
275  * scantuple has to point to that slot, too.
276  */
277  arg->estate = CreateExecutorState();
278  slot = MakeSingleTupleTableSlot(tupDesc, &TTSOpsHeapTuple);
279  econtext = GetPerTupleExprContext(arg->estate);
280  econtext->ecxt_scantuple = slot;
281  }
282 
283  /* Prepare SortSupport data for each column */
284  base->sortKeys = (SortSupport) palloc0(base->nKeys *
285  sizeof(SortSupportData));
286 
287  for (i = 0; i < base->nKeys; i++)
288  {
289  SortSupport sortKey = base->sortKeys + i;
290  ScanKey scanKey = indexScanKey->scankeys + i;
291  int16 strategy;
292 
293  sortKey->ssup_cxt = CurrentMemoryContext;
294  sortKey->ssup_collation = scanKey->sk_collation;
295  sortKey->ssup_nulls_first =
296  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
297  sortKey->ssup_attno = scanKey->sk_attno;
298  /* Convey if abbreviation optimization is applicable in principle */
299  sortKey->abbreviate = (i == 0 && base->haveDatum1);
300 
301  Assert(sortKey->ssup_attno != 0);
302 
303  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
305 
306  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
307  }
308 
309  pfree(indexScanKey);
310 
311  MemoryContextSwitchTo(oldcontext);
312 
313  return state;
314 }
signed short int16
Definition: c.h:477
#define LOG
Definition: elog.h:31
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:84
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1239
EState * CreateExecutorState(void)
Definition: execUtils.c:93
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:2430
void pfree(void *pointer)
Definition: mcxt.c:1456
void * palloc0(Size size)
Definition: mcxt.c:1257
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:1087
#define SK_BT_DESC
Definition: nbtree.h:1086
BTScanInsert _bt_mkscankey(Relation rel, Relation heaprel, IndexTuple itup)
Definition: nbtutils.c:90
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:510
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:523
void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, SortSupport ssup)
Definition: sortsupport.c:162
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define BTLessStrategyNumber
Definition: stratnum.h:29
ScanKeyData scankeys[INDEX_MAX_KEYS]
Definition: nbtree.h:795
Form_pg_class rd_rel
Definition: rel.h:111
int sk_flags
Definition: skey.h:66
Oid sk_collation
Definition: skey.h:70
AttrNumber sk_attno
Definition: skey.h:67
bool ssup_nulls_first
Definition: sortsupport.h:75
MemoryContext ssup_cxt
Definition: sortsupport.h:66
MemoryContext maincontext
Definition: tuplesort.h:200
void(* writetup)(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
Definition: tuplesort.h:176
void(* removeabbrev)(Tuplesortstate *state, SortTuple *stups, int count)
Definition: tuplesort.h:169
void(* freestate)(Tuplesortstate *state)
Definition: tuplesort.h:194
void(* readtup)(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Definition: tuplesort.h:185
SortTupleComparator comparetup
Definition: tuplesort.h:163
Tuplesortstate * tuplesort_begin_common(int workMem, SortCoordinate coordinate, int sortopt)
Definition: tuplesort.c:646
bool trace_sort
Definition: tuplesort.c:127
#define PARALLEL_SORT(coordinate)
Definition: tuplesort.h:237
static void readtup_cluster(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int tuplen)
#define CLUSTER_SORT
static void freestate_cluster(Tuplesortstate *state)
static int comparetup_cluster(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
static void writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
static void removeabbrev_cluster(Tuplesortstate *state, SortTuple *stups, int count)

References _bt_mkscankey(), SortSupportData::abbreviate, arg, TuplesortPublic::arg, Assert(), BTGreaterStrategyNumber, BTLessStrategyNumber, BuildIndexInfo(), CLUSTER_SORT, TuplesortPublic::comparetup, comparetup_cluster(), CreateExecutorState(), CurrentMemoryContext, ExprContext::ecxt_scantuple, elog(), TuplesortPublic::freestate, freestate_cluster(), GetPerTupleExprContext, TuplesortPublic::haveDatum1, i, IndexRelationGetNumberOfKeyAttributes, LOG, TuplesortPublic::maincontext, MakeSingleTupleTableSlot(), MemoryContextSwitchTo(), TuplesortPublic::nKeys, palloc0(), PARALLEL_SORT, pfree(), PrepareSortSupportFromIndexRel(), RelationData::rd_rel, TuplesortPublic::readtup, readtup_cluster(), RelationGetNumberOfAttributes, TuplesortPublic::removeabbrev, removeabbrev_cluster(), BTScanInsertData::scankeys, ScanKeyData::sk_attno, SK_BT_DESC, SK_BT_NULLS_FIRST, ScanKeyData::sk_collation, ScanKeyData::sk_flags, TuplesortPublic::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, TTSOpsHeapTuple, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TuplesortPublic::writetup, and writetup_cluster().

Referenced by heapam_relation_copy_for_cluster().

◆ tuplesort_begin_datum()

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

Definition at line 517 of file tuplesortvariants.c.

520 {
521  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
522  sortopt);
525  MemoryContext oldcontext;
526  int16 typlen;
527  bool typbyval;
528 
529  oldcontext = MemoryContextSwitchTo(base->maincontext);
531 
532 #ifdef TRACE_SORT
533  if (trace_sort)
534  elog(LOG,
535  "begin datum sort: workMem = %d, randomAccess = %c",
536  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
537 #endif
538 
539  base->nKeys = 1; /* always a one-column sort */
540 
541  TRACE_POSTGRESQL_SORT_START(DATUM_SORT,
542  false, /* no unique check */
543  1,
544  workMem,
545  sortopt & TUPLESORT_RANDOMACCESS,
546  PARALLEL_SORT(coordinate));
547 
550  base->writetup = writetup_datum;
551  base->readtup = readtup_datum;
552  base->haveDatum1 = true;
553  base->arg = arg;
554 
555  arg->datumType = datumType;
556 
557  /* lookup necessary attributes of the datum type */
558  get_typlenbyval(datumType, &typlen, &typbyval);
559  arg->datumTypeLen = typlen;
560  base->tuples = !typbyval;
561 
562  /* Prepare SortSupport data */
563  base->sortKeys = (SortSupport) palloc0(sizeof(SortSupportData));
564 
566  base->sortKeys->ssup_collation = sortCollation;
567  base->sortKeys->ssup_nulls_first = nullsFirstFlag;
568 
569  /*
570  * Abbreviation is possible here only for by-reference types. In theory,
571  * a pass-by-value datatype could have an abbreviated form that is cheaper
572  * to compare. In a tuple sort, we could support that, because we can
573  * always extract the original datum from the tuple as needed. Here, we
574  * can't, because a datum sort only stores a single copy of the datum; the
575  * "tuple" field of each SortTuple is NULL.
576  */
577  base->sortKeys->abbreviate = !typbyval;
578 
579  PrepareSortSupportFromOrderingOp(sortOperator, base->sortKeys);
580 
581  /*
582  * The "onlyKey" optimization cannot be used with abbreviated keys, since
583  * tie-breaker comparisons may be required. Typically, the optimization
584  * is only of value to pass-by-value types anyway, whereas abbreviated
585  * keys are typically only of value to pass-by-reference types.
586  */
587  if (!base->sortKeys->abbrev_converter)
588  base->onlyKey = base->sortKeys;
589 
590  MemoryContextSwitchTo(oldcontext);
591 
592  return state;
593 }
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2209
void * palloc(Size size)
Definition: mcxt.c:1226
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:135
SortSupport onlyKey
Definition: tuplesort.h:227
static void removeabbrev_datum(Tuplesortstate *state, SortTuple *stups, int count)
static int comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
static void readtup_datum(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static void writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
#define DATUM_SORT

References SortSupportData::abbrev_converter, SortSupportData::abbreviate, arg, TuplesortPublic::arg, TuplesortPublic::comparetup, comparetup_datum(), CurrentMemoryContext, DATUM_SORT, elog(), get_typlenbyval(), TuplesortPublic::haveDatum1, LOG, TuplesortPublic::maincontext, MemoryContextSwitchTo(), TuplesortPublic::nKeys, TuplesortPublic::onlyKey, palloc(), palloc0(), PARALLEL_SORT, PrepareSortSupportFromOrderingOp(), TuplesortPublic::readtup, readtup_datum(), TuplesortPublic::removeabbrev, removeabbrev_datum(), TuplesortPublic::sortKeys, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, TuplesortPublic::tuples, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TuplesortPublic::writetup, and writetup_datum().

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

◆ tuplesort_begin_heap()

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

Definition at line 134 of file tuplesortvariants.c.

139 {
140  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
141  sortopt);
143  MemoryContext oldcontext;
144  int i;
145 
146  oldcontext = MemoryContextSwitchTo(base->maincontext);
147 
148  Assert(nkeys > 0);
149 
150 #ifdef TRACE_SORT
151  if (trace_sort)
152  elog(LOG,
153  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
154  nkeys, workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
155 #endif
156 
157  base->nKeys = nkeys;
158 
159  TRACE_POSTGRESQL_SORT_START(HEAP_SORT,
160  false, /* no unique check */
161  nkeys,
162  workMem,
163  sortopt & TUPLESORT_RANDOMACCESS,
164  PARALLEL_SORT(coordinate));
165 
167  base->comparetup = comparetup_heap;
168  base->writetup = writetup_heap;
169  base->readtup = readtup_heap;
170  base->haveDatum1 = true;
171  base->arg = tupDesc; /* assume we need not copy tupDesc */
172 
173  /* Prepare SortSupport data for each column */
174  base->sortKeys = (SortSupport) palloc0(nkeys * sizeof(SortSupportData));
175 
176  for (i = 0; i < nkeys; i++)
177  {
178  SortSupport sortKey = base->sortKeys + i;
179 
180  Assert(attNums[i] != 0);
181  Assert(sortOperators[i] != 0);
182 
183  sortKey->ssup_cxt = CurrentMemoryContext;
184  sortKey->ssup_collation = sortCollations[i];
185  sortKey->ssup_nulls_first = nullsFirstFlags[i];
186  sortKey->ssup_attno = attNums[i];
187  /* Convey if abbreviation optimization is applicable in principle */
188  sortKey->abbreviate = (i == 0 && base->haveDatum1);
189 
190  PrepareSortSupportFromOrderingOp(sortOperators[i], sortKey);
191  }
192 
193  /*
194  * The "onlyKey" optimization cannot be used with abbreviated keys, since
195  * tie-breaker comparisons may be required. Typically, the optimization
196  * is only of value to pass-by-value types anyway, whereas abbreviated
197  * keys are typically only of value to pass-by-reference types.
198  */
199  if (nkeys == 1 && !base->sortKeys->abbrev_converter)
200  base->onlyKey = base->sortKeys;
201 
202  MemoryContextSwitchTo(oldcontext);
203 
204  return state;
205 }
static void readtup_heap(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static int comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
static void writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
static void removeabbrev_heap(Tuplesortstate *state, SortTuple *stups, int count)
#define HEAP_SORT

References SortSupportData::abbrev_converter, SortSupportData::abbreviate, TuplesortPublic::arg, Assert(), TuplesortPublic::comparetup, comparetup_heap(), CurrentMemoryContext, elog(), TuplesortPublic::haveDatum1, HEAP_SORT, i, LOG, TuplesortPublic::maincontext, MemoryContextSwitchTo(), TuplesortPublic::nKeys, TuplesortPublic::onlyKey, palloc0(), PARALLEL_SORT, PrepareSortSupportFromOrderingOp(), TuplesortPublic::readtup, readtup_heap(), TuplesortPublic::removeabbrev, removeabbrev_heap(), TuplesortPublic::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TuplesortPublic::writetup, and writetup_heap().

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

◆ tuplesort_begin_index_btree()

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

Definition at line 317 of file tuplesortvariants.c.

324 {
325  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
326  sortopt);
328  BTScanInsert indexScanKey;
330  MemoryContext oldcontext;
331  int i;
332 
333  oldcontext = MemoryContextSwitchTo(base->maincontext);
335 
336 #ifdef TRACE_SORT
337  if (trace_sort)
338  elog(LOG,
339  "begin index sort: unique = %c, workMem = %d, randomAccess = %c",
340  enforceUnique ? 't' : 'f',
341  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
342 #endif
343 
345 
346  TRACE_POSTGRESQL_SORT_START(INDEX_SORT,
347  enforceUnique,
348  base->nKeys,
349  workMem,
350  sortopt & TUPLESORT_RANDOMACCESS,
351  PARALLEL_SORT(coordinate));
352 
355  base->writetup = writetup_index;
356  base->readtup = readtup_index;
357  base->haveDatum1 = true;
358  base->arg = arg;
359 
360  arg->index.heapRel = heapRel;
361  arg->index.indexRel = indexRel;
362  arg->enforceUnique = enforceUnique;
363  arg->uniqueNullsNotDistinct = uniqueNullsNotDistinct;
364 
365  indexScanKey = _bt_mkscankey(indexRel, heapRel, NULL);
366 
367  /* Prepare SortSupport data for each column */
368  base->sortKeys = (SortSupport) palloc0(base->nKeys *
369  sizeof(SortSupportData));
370 
371  for (i = 0; i < base->nKeys; i++)
372  {
373  SortSupport sortKey = base->sortKeys + i;
374  ScanKey scanKey = indexScanKey->scankeys + i;
375  int16 strategy;
376 
377  sortKey->ssup_cxt = CurrentMemoryContext;
378  sortKey->ssup_collation = scanKey->sk_collation;
379  sortKey->ssup_nulls_first =
380  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
381  sortKey->ssup_attno = scanKey->sk_attno;
382  /* Convey if abbreviation optimization is applicable in principle */
383  sortKey->abbreviate = (i == 0 && base->haveDatum1);
384 
385  Assert(sortKey->ssup_attno != 0);
386 
387  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
389 
390  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
391  }
392 
393  pfree(indexScanKey);
394 
395  MemoryContextSwitchTo(oldcontext);
396 
397  return state;
398 }
static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
static void readtup_index(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static void removeabbrev_index(Tuplesortstate *state, SortTuple *stups, int count)
#define INDEX_SORT
static void writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)

References _bt_mkscankey(), SortSupportData::abbreviate, arg, TuplesortPublic::arg, Assert(), BTGreaterStrategyNumber, BTLessStrategyNumber, TuplesortPublic::comparetup, comparetup_index_btree(), CurrentMemoryContext, elog(), TuplesortPublic::haveDatum1, i, INDEX_SORT, IndexRelationGetNumberOfKeyAttributes, LOG, TuplesortPublic::maincontext, MemoryContextSwitchTo(), TuplesortPublic::nKeys, palloc(), palloc0(), PARALLEL_SORT, pfree(), PrepareSortSupportFromIndexRel(), TuplesortPublic::readtup, readtup_index(), TuplesortPublic::removeabbrev, removeabbrev_index(), BTScanInsertData::scankeys, ScanKeyData::sk_attno, SK_BT_DESC, SK_BT_NULLS_FIRST, ScanKeyData::sk_collation, ScanKeyData::sk_flags, TuplesortPublic::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TuplesortPublic::writetup, and writetup_index().

Referenced by _bt_parallel_scan_and_sort(), and _bt_spools_heapscan().

◆ tuplesort_begin_index_gist()

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

Definition at line 453 of file tuplesortvariants.c.

458 {
459  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
460  sortopt);
462  MemoryContext oldcontext;
464  int i;
465 
466  oldcontext = MemoryContextSwitchTo(base->maincontext);
468 
469 #ifdef TRACE_SORT
470  if (trace_sort)
471  elog(LOG,
472  "begin index sort: workMem = %d, randomAccess = %c",
473  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
474 #endif
475 
477 
480  base->writetup = writetup_index;
481  base->readtup = readtup_index;
482  base->haveDatum1 = true;
483  base->arg = arg;
484 
485  arg->index.heapRel = heapRel;
486  arg->index.indexRel = indexRel;
487  arg->enforceUnique = false;
488  arg->uniqueNullsNotDistinct = false;
489 
490  /* Prepare SortSupport data for each column */
491  base->sortKeys = (SortSupport) palloc0(base->nKeys *
492  sizeof(SortSupportData));
493 
494  for (i = 0; i < base->nKeys; i++)
495  {
496  SortSupport sortKey = base->sortKeys + i;
497 
498  sortKey->ssup_cxt = CurrentMemoryContext;
499  sortKey->ssup_collation = indexRel->rd_indcollation[i];
500  sortKey->ssup_nulls_first = false;
501  sortKey->ssup_attno = i + 1;
502  /* Convey if abbreviation optimization is applicable in principle */
503  sortKey->abbreviate = (i == 0 && base->haveDatum1);
504 
505  Assert(sortKey->ssup_attno != 0);
506 
507  /* Look for a sort support function */
508  PrepareSortSupportFromGistIndexRel(indexRel, sortKey);
509  }
510 
511  MemoryContextSwitchTo(oldcontext);
512 
513  return state;
514 }
void PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup)
Definition: sortsupport.c:189
Oid * rd_indcollation
Definition: rel.h:216

References SortSupportData::abbreviate, arg, TuplesortPublic::arg, Assert(), TuplesortPublic::comparetup, comparetup_index_btree(), CurrentMemoryContext, elog(), TuplesortPublic::haveDatum1, i, IndexRelationGetNumberOfKeyAttributes, LOG, TuplesortPublic::maincontext, MemoryContextSwitchTo(), TuplesortPublic::nKeys, palloc(), palloc0(), PrepareSortSupportFromGistIndexRel(), RelationData::rd_indcollation, TuplesortPublic::readtup, readtup_index(), TuplesortPublic::removeabbrev, removeabbrev_index(), TuplesortPublic::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TuplesortPublic::writetup, and writetup_index().

Referenced by gistbuild().

◆ tuplesort_begin_index_hash()

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

Definition at line 401 of file tuplesortvariants.c.

409 {
410  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
411  sortopt);
413  MemoryContext oldcontext;
415 
416  oldcontext = MemoryContextSwitchTo(base->maincontext);
418 
419 #ifdef TRACE_SORT
420  if (trace_sort)
421  elog(LOG,
422  "begin index sort: high_mask = 0x%x, low_mask = 0x%x, "
423  "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
424  high_mask,
425  low_mask,
426  max_buckets,
427  workMem,
428  sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
429 #endif
430 
431  base->nKeys = 1; /* Only one sort column, the hash code */
432 
435  base->writetup = writetup_index;
436  base->readtup = readtup_index;
437  base->haveDatum1 = true;
438  base->arg = arg;
439 
440  arg->index.heapRel = heapRel;
441  arg->index.indexRel = indexRel;
442 
443  arg->high_mask = high_mask;
444  arg->low_mask = low_mask;
445  arg->max_buckets = max_buckets;
446 
447  MemoryContextSwitchTo(oldcontext);
448 
449  return state;
450 }
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)

References arg, TuplesortPublic::arg, TuplesortPublic::comparetup, comparetup_index_hash(), elog(), TuplesortPublic::haveDatum1, LOG, TuplesortPublic::maincontext, MemoryContextSwitchTo(), TuplesortPublic::nKeys, palloc(), TuplesortPublic::readtup, readtup_index(), TuplesortPublic::removeabbrev, removeabbrev_index(), trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TuplesortPublic::writetup, and writetup_index().

Referenced by _h_spoolinit().

◆ tuplesort_getdatum()

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

Definition at line 864 of file tuplesortvariants.c.

866 {
868  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
870  SortTuple stup;
871 
872  if (!tuplesort_gettuple_common(state, forward, &stup))
873  {
874  MemoryContextSwitchTo(oldcontext);
875  return false;
876  }
877 
878  /* Ensure we copy into caller's memory context */
879  MemoryContextSwitchTo(oldcontext);
880 
881  /* Record abbreviated key for caller */
882  if (base->sortKeys->abbrev_converter && abbrev)
883  *abbrev = stup.datum1;
884 
885  if (stup.isnull1 || !base->tuples)
886  {
887  *val = stup.datum1;
888  *isNull = stup.isnull1;
889  }
890  else
891  {
892  /* use stup.tuple because stup.datum1 may be an abbreviation */
893  if (copy)
894  *val = datumCopy(PointerGetDatum(stup.tuple), false,
895  arg->datumTypeLen);
896  else
897  *val = PointerGetDatum(stup.tuple);
898  *isNull = false;
899  }
900 
901  return true;
902 }
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
long val
Definition: informix.c:664
MemoryContext sortcontext
Definition: tuplesort.h:202
bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1496

References SortSupportData::abbrev_converter, arg, TuplesortPublic::arg, datumCopy(), if(), MemoryContextSwitchTo(), PointerGetDatum(), TuplesortPublic::sortcontext, TuplesortPublic::sortKeys, TuplesortPublic::tuples, tuplesort_gettuple_common(), TuplesortstateGetPublic, and val.

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

◆ tuplesort_getheaptuple()

HeapTuple tuplesort_getheaptuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 803 of file tuplesortvariants.c.

804 {
806  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
807  SortTuple stup;
808 
809  if (!tuplesort_gettuple_common(state, forward, &stup))
810  stup.tuple = NULL;
811 
812  MemoryContextSwitchTo(oldcontext);
813 
814  return stup.tuple;
815 }

References MemoryContextSwitchTo(), TuplesortPublic::sortcontext, SortTuple::tuple, tuplesort_gettuple_common(), and TuplesortstateGetPublic.

Referenced by heapam_relation_copy_for_cluster().

◆ tuplesort_getindextuple()

IndexTuple tuplesort_getindextuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 824 of file tuplesortvariants.c.

825 {
827  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
828  SortTuple stup;
829 
830  if (!tuplesort_gettuple_common(state, forward, &stup))
831  stup.tuple = NULL;
832 
833  MemoryContextSwitchTo(oldcontext);
834 
835  return (IndexTuple) stup.tuple;
836 }

References MemoryContextSwitchTo(), TuplesortPublic::sortcontext, SortTuple::tuple, tuplesort_gettuple_common(), and TuplesortstateGetPublic.

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

◆ tuplesort_gettupleslot()

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

Definition at line 765 of file tuplesortvariants.c.

767 {
769  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
770  SortTuple stup;
771 
772  if (!tuplesort_gettuple_common(state, forward, &stup))
773  stup.tuple = NULL;
774 
775  MemoryContextSwitchTo(oldcontext);
776 
777  if (stup.tuple)
778  {
779  /* Record abbreviated key for caller */
780  if (base->sortKeys->abbrev_converter && abbrev)
781  *abbrev = stup.datum1;
782 
783  if (copy)
785 
786  ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, copy);
787  return true;
788  }
789  else
790  {
791  ExecClearTuple(slot);
792  return false;
793  }
794 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1447
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1439
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:432

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

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

◆ tuplesort_putdatum()

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

Definition at line 701 of file tuplesortvariants.c.

702 {
706  SortTuple stup;
707 
708  /*
709  * Pass-by-value types or null values are just stored directly in
710  * stup.datum1 (and stup.tuple is not used and set to NULL).
711  *
712  * Non-null pass-by-reference values need to be copied into memory we
713  * control, and possibly abbreviated. The copied value is pointed to by
714  * stup.tuple and is treated as the canonical copy (e.g. to return via
715  * tuplesort_getdatum or when writing to tape); stup.datum1 gets the
716  * abbreviated value if abbreviation is happening, otherwise it's
717  * identical to stup.tuple.
718  */
719 
720  if (isNull || !base->tuples)
721  {
722  /*
723  * Set datum1 to zeroed representation for NULLs (to be consistent,
724  * and to support cheap inequality tests for NULL abbreviated keys).
725  */
726  stup.datum1 = !isNull ? val : (Datum) 0;
727  stup.isnull1 = isNull;
728  stup.tuple = NULL; /* no separate storage */
729  }
730  else
731  {
732  stup.isnull1 = false;
733  stup.datum1 = datumCopy(val, false, arg->datumTypeLen);
734  stup.tuple = DatumGetPointer(stup.datum1);
735  }
736 
738  base->tuples &&
739  base->sortKeys->abbrev_converter && !isNull);
740 
741  MemoryContextSwitchTo(oldcontext);
742 }
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
MemoryContext tuplecontext
Definition: tuplesort.h:203
void tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
Definition: tuplesort.c:1190

References SortSupportData::abbrev_converter, arg, TuplesortPublic::arg, datumCopy(), DatumGetPointer(), if(), MemoryContextSwitchTo(), TuplesortPublic::sortKeys, TuplesortPublic::tuplecontext, TuplesortPublic::tuples, tuplesort_puttuple_common(), TuplesortstateGetPublic, and val.

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

◆ tuplesort_putheaptuple()

void tuplesort_putheaptuple ( Tuplesortstate state,
HeapTuple  tup 
)

Definition at line 634 of file tuplesortvariants.c.

635 {
636  SortTuple stup;
640 
641  /* copy the tuple into sort storage */
642  tup = heap_copytuple(tup);
643  stup.tuple = (void *) tup;
644 
645  /*
646  * set up first-column key value, and potentially abbreviate, if it's a
647  * simple column
648  */
649  if (base->haveDatum1)
650  {
651  stup.datum1 = heap_getattr(tup,
652  arg->indexInfo->ii_IndexAttrNumbers[0],
653  arg->tupDesc,
654  &stup.isnull1);
655  }
656 
658  base->haveDatum1 &&
659  base->sortKeys->abbrev_converter &&
660  !stup.isnull1);
661 
662  MemoryContextSwitchTo(oldcontext);
663 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680

References SortSupportData::abbrev_converter, arg, TuplesortPublic::arg, SortTuple::datum1, TuplesortPublic::haveDatum1, heap_copytuple(), heap_getattr(), SortTuple::isnull1, MemoryContextSwitchTo(), TuplesortPublic::sortKeys, SortTuple::tuple, TuplesortPublic::tuplecontext, tuplesort_puttuple_common(), and TuplesortstateGetPublic.

Referenced by heapam_relation_copy_for_cluster().

◆ tuplesort_putindextuplevalues()

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

Definition at line 670 of file tuplesortvariants.c.

673 {
674  SortTuple stup;
675  IndexTuple tuple;
678 
680  isnull, base->tuplecontext);
681  tuple = ((IndexTuple) stup.tuple);
682  tuple->t_tid = *self;
683  /* set up first-column key value */
684  stup.datum1 = index_getattr(tuple,
685  1,
686  RelationGetDescr(arg->indexRel),
687  &stup.isnull1);
688 
690  base->sortKeys &&
691  base->sortKeys->abbrev_converter &&
692  !stup.isnull1);
693 }
IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor, Datum *values, bool *isnull, MemoryContext context)
Definition: indextuple.c:65

References SortSupportData::abbrev_converter, arg, TuplesortPublic::arg, SortTuple::datum1, index_form_tuple_context(), index_getattr(), SortTuple::isnull1, RelationGetDescr, TuplesortPublic::sortKeys, IndexTupleData::t_tid, SortTuple::tuple, TuplesortPublic::tuplecontext, tuplesort_puttuple_common(), TuplesortstateGetPublic, and values.

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

◆ tuplesort_puttupleslot()

void tuplesort_puttupleslot ( Tuplesortstate state,
TupleTableSlot slot 
)

Definition at line 601 of file tuplesortvariants.c.

602 {
605  TupleDesc tupDesc = (TupleDesc) base->arg;
606  SortTuple stup;
607  MinimalTuple tuple;
608  HeapTupleData htup;
609 
610  /* copy the tuple into sort storage */
611  tuple = ExecCopySlotMinimalTuple(slot);
612  stup.tuple = (void *) tuple;
613  /* set up first-column key value */
614  htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
615  htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
616  stup.datum1 = heap_getattr(&htup,
617  base->sortKeys[0].ssup_attno,
618  tupDesc,
619  &stup.isnull1);
620 
622  base->sortKeys->abbrev_converter &&
623  !stup.isnull1);
624 
625  MemoryContextSwitchTo(oldcontext);
626 }
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
Definition: tuptable.h:470

References SortSupportData::abbrev_converter, TuplesortPublic::arg, ExecCopySlotMinimalTuple(), heap_getattr(), MemoryContextSwitchTo(), MINIMAL_TUPLE_OFFSET, TuplesortPublic::sortKeys, SortSupportData::ssup_attno, MinimalTupleData::t_len, TuplesortPublic::tuplecontext, tuplesort_puttuple_common(), and TuplesortstateGetPublic.

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

◆ writetup_cluster()

static void writetup_cluster ( Tuplesortstate state,
LogicalTape tape,
SortTuple stup 
)
static

Definition at line 1177 of file tuplesortvariants.c.

1178 {
1180  HeapTuple tuple = (HeapTuple) stup->tuple;
1181  unsigned int tuplen = tuple->t_len + sizeof(ItemPointerData) + sizeof(int);
1182 
1183  /* We need to store t_self, but not other fields of HeapTupleData */
1184  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1185  LogicalTapeWrite(tape, &tuple->t_self, sizeof(ItemPointerData));
1186  LogicalTapeWrite(tape, tuple->t_data, tuple->t_len);
1187  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1188  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1189 }
void LogicalTapeWrite(LogicalTape *lt, const void *ptr, size_t size)
Definition: logtape.c:761

References LogicalTapeWrite(), TuplesortPublic::sortopt, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, SortTuple::tuple, TUPLESORT_RANDOMACCESS, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_cluster().

◆ writetup_datum()

static void writetup_datum ( Tuplesortstate state,
LogicalTape tape,
SortTuple stup 
)
static

Definition at line 1541 of file tuplesortvariants.c.

1542 {
1545  void *waddr;
1546  unsigned int tuplen;
1547  unsigned int writtenlen;
1548 
1549  if (stup->isnull1)
1550  {
1551  waddr = NULL;
1552  tuplen = 0;
1553  }
1554  else if (!base->tuples)
1555  {
1556  waddr = &stup->datum1;
1557  tuplen = sizeof(Datum);
1558  }
1559  else
1560  {
1561  waddr = stup->tuple;
1562  tuplen = datumGetSize(PointerGetDatum(stup->tuple), false, arg->datumTypeLen);
1563  Assert(tuplen != 0);
1564  }
1565 
1566  writtenlen = tuplen + sizeof(unsigned int);
1567 
1568  LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
1569  LogicalTapeWrite(tape, waddr, tuplen);
1570  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1571  LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
1572 }
Size datumGetSize(Datum value, bool typByVal, int typLen)
Definition: datum.c:65

References arg, TuplesortPublic::arg, Assert(), SortTuple::datum1, datumGetSize(), if(), SortTuple::isnull1, LogicalTapeWrite(), PointerGetDatum(), TuplesortPublic::sortopt, SortTuple::tuple, TuplesortPublic::tuples, TUPLESORT_RANDOMACCESS, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_datum().

◆ writetup_heap()

static void writetup_heap ( Tuplesortstate state,
LogicalTape tape,
SortTuple stup 
)
static

Definition at line 994 of file tuplesortvariants.c.

995 {
997  MinimalTuple tuple = (MinimalTuple) stup->tuple;
998 
999  /* the part of the MinimalTuple we'll write: */
1000  char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1001  unsigned int tupbodylen = tuple->t_len - MINIMAL_TUPLE_DATA_OFFSET;
1002 
1003  /* total on-disk footprint: */
1004  unsigned int tuplen = tupbodylen + sizeof(int);
1005 
1006  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1007  LogicalTapeWrite(tape, tupbody, tupbodylen);
1008  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1009  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1010 }

References LogicalTapeWrite(), MINIMAL_TUPLE_DATA_OFFSET, TuplesortPublic::sortopt, MinimalTupleData::t_len, SortTuple::tuple, TUPLESORT_RANDOMACCESS, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_heap().

◆ writetup_index()

static void writetup_index ( Tuplesortstate state,
LogicalTape tape,
SortTuple stup 
)
static

Definition at line 1472 of file tuplesortvariants.c.

1473 {
1475  IndexTuple tuple = (IndexTuple) stup->tuple;
1476  unsigned int tuplen;
1477 
1478  tuplen = IndexTupleSize(tuple) + sizeof(tuplen);
1479  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1480  LogicalTapeWrite(tape, tuple, IndexTupleSize(tuple));
1481  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1482  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1483 }
#define IndexTupleSize(itup)
Definition: itup.h:70

References IndexTupleSize, LogicalTapeWrite(), TuplesortPublic::sortopt, SortTuple::tuple, TUPLESORT_RANDOMACCESS, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_btree(), tuplesort_begin_index_gist(), and tuplesort_begin_index_hash().