PostgreSQL Source Code  git master
tuplesortvariants.c File Reference
#include "postgres.h"
#include "access/brin_tuple.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/guc.h"
#include "utils/lsyscache.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
 
struct  BrinSortTuple
 

Macros

#define HEAP_SORT   0
 
#define INDEX_SORT   1
 
#define DATUM_SORT   2
 
#define CLUSTER_SORT   3
 
#define BRINSORTTUPLE_SIZE(len)   (offsetof(BrinSortTuple, tuple) + (len))
 

Typedefs

typedef struct BrinSortTuple BrinSortTuple
 

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_index_brin (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 int comparetup_heap_tiebreak (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 int comparetup_cluster_tiebreak (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_btree_tiebreak (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static int comparetup_index_hash (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static int comparetup_index_hash_tiebreak (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static int comparetup_index_brin (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 void writetup_index_brin (Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
 
static void readtup_index_brin (Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
 
static int comparetup_datum (const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 
static int comparetup_datum_tiebreak (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, 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_index_brin (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, const Datum *values, const bool *isnull)
 
void tuplesort_putbrintuple (Tuplesortstate *state, BrinTuple *tuple, Size size)
 
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)
 
BrinTupletuplesort_getbrintuple (Tuplesortstate *state, Size *len, bool forward)
 
bool tuplesort_getdatum (Tuplesortstate *state, bool forward, bool copy, Datum *val, bool *isNull, Datum *abbrev)
 

Macro Definition Documentation

◆ BRINSORTTUPLE_SIZE

#define BRINSORTTUPLE_SIZE (   len)    (offsetof(BrinSortTuple, tuple) + (len))

Definition at line 164 of file tuplesortvariants.c.

◆ CLUSTER_SORT

#define CLUSTER_SORT   3

Definition at line 39 of file tuplesortvariants.c.

◆ DATUM_SORT

#define DATUM_SORT   2

Definition at line 38 of file tuplesortvariants.c.

◆ HEAP_SORT

#define HEAP_SORT   0

Definition at line 36 of file tuplesortvariants.c.

◆ INDEX_SORT

#define INDEX_SORT   1

Definition at line 37 of file tuplesortvariants.c.

Typedef Documentation

◆ BrinSortTuple

typedef struct BrinSortTuple BrinSortTuple

Function Documentation

◆ comparetup_cluster()

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

Definition at line 1227 of file tuplesortvariants.c.

1229 {
1231  SortSupport sortKey = base->sortKeys;
1232  int32 compare;
1233 
1234  /* Compare the leading sort key, if it's simple */
1235  if (base->haveDatum1)
1236  {
1237  compare = ApplySortComparator(a->datum1, a->isnull1,
1238  b->datum1, b->isnull1,
1239  sortKey);
1240  if (compare != 0)
1241  return compare;
1242  }
1243 
1245 }
signed int int32
Definition: c.h:494
static int compare(const void *arg1, const void *arg2)
Definition: geqo_pool.c:145
int b
Definition: isn.c:70
int a
Definition: isn.c:69
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
Definition: sortsupport.h:200
SortSupport sortKeys
Definition: tuplesort.h:235
Definition: regguts.h:323
#define TuplesortstateGetPublic(state)
Definition: tuplesort.h:259
static int comparetup_cluster_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)

References a, ApplySortComparator(), b, compare(), comparetup_cluster_tiebreak(), TuplesortPublic::haveDatum1, TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_cluster().

◆ comparetup_cluster_tiebreak()

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

Definition at line 1248 of file tuplesortvariants.c.

1250 {
1253  SortSupport sortKey = base->sortKeys;
1254  HeapTuple ltup;
1255  HeapTuple rtup;
1256  TupleDesc tupDesc;
1257  int nkey;
1258  int32 compare = 0;
1259  Datum datum1,
1260  datum2;
1261  bool isnull1,
1262  isnull2;
1263 
1264  ltup = (HeapTuple) a->tuple;
1265  rtup = (HeapTuple) b->tuple;
1266  tupDesc = arg->tupDesc;
1267 
1268  /* Compare the leading sort key, if it's simple */
1269  if (base->haveDatum1)
1270  {
1271  if (sortKey->abbrev_converter)
1272  {
1273  AttrNumber leading = arg->indexInfo->ii_IndexAttrNumbers[0];
1274 
1275  datum1 = heap_getattr(ltup, leading, tupDesc, &isnull1);
1276  datum2 = heap_getattr(rtup, leading, tupDesc, &isnull2);
1277 
1278  compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1279  datum2, isnull2,
1280  sortKey);
1281  }
1282  if (compare != 0 || base->nKeys == 1)
1283  return compare;
1284  /* Compare additional columns the hard way */
1285  sortKey++;
1286  nkey = 1;
1287  }
1288  else
1289  {
1290  /* Must compare all keys the hard way */
1291  nkey = 0;
1292  }
1293 
1294  if (arg->indexInfo->ii_Expressions == NULL)
1295  {
1296  /* If not expression index, just compare the proper heap attrs */
1297 
1298  for (; nkey < base->nKeys; nkey++, sortKey++)
1299  {
1300  AttrNumber attno = arg->indexInfo->ii_IndexAttrNumbers[nkey];
1301 
1302  datum1 = heap_getattr(ltup, attno, tupDesc, &isnull1);
1303  datum2 = heap_getattr(rtup, attno, tupDesc, &isnull2);
1304 
1305  compare = ApplySortComparator(datum1, isnull1,
1306  datum2, isnull2,
1307  sortKey);
1308  if (compare != 0)
1309  return compare;
1310  }
1311  }
1312  else
1313  {
1314  /*
1315  * In the expression index case, compute the whole index tuple and
1316  * then compare values. It would perhaps be faster to compute only as
1317  * many columns as we need to compare, but that would require
1318  * duplicating all the logic in FormIndexDatum.
1319  */
1320  Datum l_index_values[INDEX_MAX_KEYS];
1321  bool l_index_isnull[INDEX_MAX_KEYS];
1322  Datum r_index_values[INDEX_MAX_KEYS];
1323  bool r_index_isnull[INDEX_MAX_KEYS];
1324  TupleTableSlot *ecxt_scantuple;
1325 
1326  /* Reset context each time to prevent memory leakage */
1327  ResetPerTupleExprContext(arg->estate);
1328 
1329  ecxt_scantuple = GetPerTupleExprContext(arg->estate)->ecxt_scantuple;
1330 
1331  ExecStoreHeapTuple(ltup, ecxt_scantuple, false);
1332  FormIndexDatum(arg->indexInfo, ecxt_scantuple, arg->estate,
1333  l_index_values, l_index_isnull);
1334 
1335  ExecStoreHeapTuple(rtup, ecxt_scantuple, false);
1336  FormIndexDatum(arg->indexInfo, ecxt_scantuple, arg->estate,
1337  r_index_values, r_index_isnull);
1338 
1339  for (; nkey < base->nKeys; nkey++, sortKey++)
1340  {
1341  compare = ApplySortComparator(l_index_values[nkey],
1342  l_index_isnull[nkey],
1343  r_index_values[nkey],
1344  r_index_isnull[nkey],
1345  sortKey);
1346  if (compare != 0)
1347  return compare;
1348  }
1349  }
1350 
1351  return 0;
1352 }
int16 AttrNumber
Definition: attnum.h:21
TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1439
#define ResetPerTupleExprContext(estate)
Definition: executor.h:559
#define GetPerTupleExprContext(estate)
Definition: executor.h:550
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:2705
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

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 comparetup_cluster(), and tuplesort_begin_cluster().

◆ comparetup_datum()

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

Definition at line 1794 of file tuplesortvariants.c.

1795 {
1797  int compare;
1798 
1799  compare = ApplySortComparator(a->datum1, a->isnull1,
1800  b->datum1, b->isnull1,
1801  base->sortKeys);
1802  if (compare != 0)
1803  return compare;
1804 
1805  return comparetup_datum_tiebreak(a, b, state);
1806 }
static int comparetup_datum_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)

References a, ApplySortComparator(), b, compare(), comparetup_datum_tiebreak(), TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_datum().

◆ comparetup_datum_tiebreak()

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

Definition at line 1809 of file tuplesortvariants.c.

1810 {
1812  int32 compare = 0;
1813 
1814  /* if we have abbreviations, then "tuple" has the original value */
1815  if (base->sortKeys->abbrev_converter)
1817  PointerGetDatum(b->tuple), b->isnull1,
1818  base->sortKeys);
1819 
1820  return compare;
1821 }
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(), b, compare(), PointerGetDatum(), TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by comparetup_datum(), and tuplesort_begin_datum().

◆ comparetup_heap()

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

Definition at line 1085 of file tuplesortvariants.c.

1086 {
1088  SortSupport sortKey = base->sortKeys;
1089  int32 compare;
1090 
1091 
1092  /* Compare the leading sort key */
1093  compare = ApplySortComparator(a->datum1, a->isnull1,
1094  b->datum1, b->isnull1,
1095  sortKey);
1096  if (compare != 0)
1097  return compare;
1098 
1099  /* Compare additional sort keys */
1100  return comparetup_heap_tiebreak(a, b, state);
1101 }
static int comparetup_heap_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)

References a, ApplySortComparator(), b, compare(), comparetup_heap_tiebreak(), TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_heap().

◆ comparetup_heap_tiebreak()

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

Definition at line 1104 of file tuplesortvariants.c.

1105 {
1107  SortSupport sortKey = base->sortKeys;
1108  HeapTupleData ltup;
1109  HeapTupleData rtup;
1110  TupleDesc tupDesc;
1111  int nkey;
1112  int32 compare;
1113  AttrNumber attno;
1114  Datum datum1,
1115  datum2;
1116  bool isnull1,
1117  isnull2;
1118 
1119  ltup.t_len = ((MinimalTuple) a->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
1120  ltup.t_data = (HeapTupleHeader) ((char *) a->tuple - MINIMAL_TUPLE_OFFSET);
1121  rtup.t_len = ((MinimalTuple) b->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
1122  rtup.t_data = (HeapTupleHeader) ((char *) b->tuple - MINIMAL_TUPLE_OFFSET);
1123  tupDesc = (TupleDesc) base->arg;
1124 
1125  if (sortKey->abbrev_converter)
1126  {
1127  attno = sortKey->ssup_attno;
1128 
1129  datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
1130  datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
1131 
1132  compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1133  datum2, isnull2,
1134  sortKey);
1135  if (compare != 0)
1136  return compare;
1137  }
1138 
1139  sortKey++;
1140  for (nkey = 1; nkey < base->nKeys; nkey++, sortKey++)
1141  {
1142  attno = sortKey->ssup_attno;
1143 
1144  datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
1145  datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
1146 
1147  compare = ApplySortComparator(datum1, isnull1,
1148  datum2, isnull2,
1149  sortKey);
1150  if (compare != 0)
1151  return compare;
1152  }
1153 
1154  return 0;
1155 }
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 comparetup_heap(), and tuplesort_begin_heap().

◆ comparetup_index_brin()

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

Definition at line 1725 of file tuplesortvariants.c.

1727 {
1728  Assert(TuplesortstateGetPublic(state)->haveDatum1);
1729 
1730  if (DatumGetUInt32(a->datum1) > DatumGetUInt32(b->datum1))
1731  return 1;
1732 
1733  if (DatumGetUInt32(a->datum1) < DatumGetUInt32(b->datum1))
1734  return -1;
1735 
1736  /* silence compilers */
1737  return 0;
1738 }
#define Assert(condition)
Definition: c.h:858
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:222

References a, Assert, b, DatumGetUInt32(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_brin().

◆ comparetup_index_btree()

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

Definition at line 1442 of file tuplesortvariants.c.

1444 {
1445  /*
1446  * This is similar to comparetup_heap(), but expects index tuples. There
1447  * is also special handling for enforcing uniqueness, and special
1448  * treatment for equal keys at the end.
1449  */
1451  SortSupport sortKey = base->sortKeys;
1452  int32 compare;
1453 
1454  /* Compare the leading sort key */
1455  compare = ApplySortComparator(a->datum1, a->isnull1,
1456  b->datum1, b->isnull1,
1457  sortKey);
1458  if (compare != 0)
1459  return compare;
1460 
1461  /* Compare additional sort keys */
1463 }
static int comparetup_index_btree_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)

References a, ApplySortComparator(), b, compare(), comparetup_index_btree_tiebreak(), TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_btree(), and tuplesort_begin_index_gist().

◆ comparetup_index_btree_tiebreak()

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

Definition at line 1466 of file tuplesortvariants.c.

1468 {
1471  SortSupport sortKey = base->sortKeys;
1472  IndexTuple tuple1;
1473  IndexTuple tuple2;
1474  int keysz;
1475  TupleDesc tupDes;
1476  bool equal_hasnull = false;
1477  int nkey;
1478  int32 compare;
1479  Datum datum1,
1480  datum2;
1481  bool isnull1,
1482  isnull2;
1483 
1484  tuple1 = (IndexTuple) a->tuple;
1485  tuple2 = (IndexTuple) b->tuple;
1486  keysz = base->nKeys;
1487  tupDes = RelationGetDescr(arg->index.indexRel);
1488 
1489  if (sortKey->abbrev_converter)
1490  {
1491  datum1 = index_getattr(tuple1, 1, tupDes, &isnull1);
1492  datum2 = index_getattr(tuple2, 1, tupDes, &isnull2);
1493 
1494  compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1495  datum2, isnull2,
1496  sortKey);
1497  if (compare != 0)
1498  return compare;
1499  }
1500 
1501  /* they are equal, so we only need to examine one null flag */
1502  if (a->isnull1)
1503  equal_hasnull = true;
1504 
1505  sortKey++;
1506  for (nkey = 2; nkey <= keysz; nkey++, sortKey++)
1507  {
1508  datum1 = index_getattr(tuple1, nkey, tupDes, &isnull1);
1509  datum2 = index_getattr(tuple2, nkey, tupDes, &isnull2);
1510 
1511  compare = ApplySortComparator(datum1, isnull1,
1512  datum2, isnull2,
1513  sortKey);
1514  if (compare != 0)
1515  return compare; /* done when we find unequal attributes */
1516 
1517  /* they are equal, so we only need to examine one null flag */
1518  if (isnull1)
1519  equal_hasnull = true;
1520  }
1521 
1522  /*
1523  * If btree has asked us to enforce uniqueness, complain if two equal
1524  * tuples are detected (unless there was at least one NULL field and NULLS
1525  * NOT DISTINCT was not set).
1526  *
1527  * It is sufficient to make the test here, because if two tuples are equal
1528  * they *must* get compared at some stage of the sort --- otherwise the
1529  * sort algorithm wouldn't have checked whether one must appear before the
1530  * other.
1531  */
1532  if (arg->enforceUnique && !(!arg->uniqueNullsNotDistinct && equal_hasnull))
1533  {
1535  bool isnull[INDEX_MAX_KEYS];
1536  char *key_desc;
1537 
1538  /*
1539  * Some rather brain-dead implementations of qsort (such as the one in
1540  * QNX 4) will sometimes call the comparison routine to compare a
1541  * value to itself, but we always use our own implementation, which
1542  * does not.
1543  */
1544  Assert(tuple1 != tuple2);
1545 
1546  index_deform_tuple(tuple1, tupDes, values, isnull);
1547 
1548  key_desc = BuildIndexValueDescription(arg->index.indexRel, values, isnull);
1549 
1550  ereport(ERROR,
1551  (errcode(ERRCODE_UNIQUE_VIOLATION),
1552  errmsg("could not create unique index \"%s\"",
1553  RelationGetRelationName(arg->index.indexRel)),
1554  key_desc ? errdetail("Key %s is duplicated.", key_desc) :
1555  errdetail("Duplicate keys exist."),
1556  errtableconstraint(arg->index.heapRel,
1557  RelationGetRelationName(arg->index.indexRel))));
1558  }
1559 
1560  /*
1561  * If key values are equal, we sort on ItemPointer. This is required for
1562  * btree indexes, since heap TID is treated as an implicit last key
1563  * attribute in order to ensure that all keys in the index are physically
1564  * unique.
1565  */
1566  {
1567  BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid);
1568  BlockNumber blk2 = ItemPointerGetBlockNumber(&tuple2->t_tid);
1569 
1570  if (blk1 != blk2)
1571  return (blk1 < blk2) ? -1 : 1;
1572  }
1573  {
1574  OffsetNumber pos1 = ItemPointerGetOffsetNumber(&tuple1->t_tid);
1575  OffsetNumber pos2 = ItemPointerGetOffsetNumber(&tuple2->t_tid);
1576 
1577  if (pos1 != pos2)
1578  return (pos1 < pos2) ? -1 : 1;
1579  }
1580 
1581  /* ItemPointer values should never be equal */
1582  Assert(false);
1583 
1584  return 0;
1585 }
uint32 BlockNumber
Definition: block.h:31
static Datum values[MAXATTR]
Definition: bootstrap.c:152
int errdetail(const char *fmt,...)
Definition: elog.c:1205
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
char * BuildIndexValueDescription(Relation indexRelation, const Datum *values, const bool *isnull)
Definition: genam.c:174
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
uint16 OffsetNumber
Definition: off.h:24
#define RelationGetDescr(relation)
Definition: rel.h:531
#define RelationGetRelationName(relation)
Definition: rel.h:539
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5999

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 comparetup_index_btree(), 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 1588 of file tuplesortvariants.c.

1590 {
1591  Bucket bucket1;
1592  Bucket bucket2;
1593  uint32 hash1;
1594  uint32 hash2;
1595  IndexTuple tuple1;
1596  IndexTuple tuple2;
1599 
1600  /*
1601  * Fetch hash keys and mask off bits we don't want to sort by, so that the
1602  * initial sort is just on the bucket number. We know that the first
1603  * column of the index tuple is the hash key.
1604  */
1605  Assert(!a->isnull1);
1606  bucket1 = _hash_hashkey2bucket(DatumGetUInt32(a->datum1),
1607  arg->max_buckets, arg->high_mask,
1608  arg->low_mask);
1609  Assert(!b->isnull1);
1610  bucket2 = _hash_hashkey2bucket(DatumGetUInt32(b->datum1),
1611  arg->max_buckets, arg->high_mask,
1612  arg->low_mask);
1613  if (bucket1 > bucket2)
1614  return 1;
1615  else if (bucket1 < bucket2)
1616  return -1;
1617 
1618  /*
1619  * If bucket values are equal, sort by hash values. This allows us to
1620  * insert directly onto bucket/overflow pages, where the index tuples are
1621  * stored in hash order to allow fast binary search within each page.
1622  */
1623  hash1 = DatumGetUInt32(a->datum1);
1624  hash2 = DatumGetUInt32(b->datum1);
1625  if (hash1 > hash2)
1626  return 1;
1627  else if (hash1 < hash2)
1628  return -1;
1629 
1630  /*
1631  * If hash values are equal, we sort on ItemPointer. This does not affect
1632  * validity of the finished index, but it may be useful to have index
1633  * scans in physical order.
1634  */
1635  tuple1 = (IndexTuple) a->tuple;
1636  tuple2 = (IndexTuple) b->tuple;
1637 
1638  {
1639  BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid);
1640  BlockNumber blk2 = ItemPointerGetBlockNumber(&tuple2->t_tid);
1641 
1642  if (blk1 != blk2)
1643  return (blk1 < blk2) ? -1 : 1;
1644  }
1645  {
1648 
1649  if (pos1 != pos2)
1650  return (pos1 < pos2) ? -1 : 1;
1651  }
1652 
1653  /* ItemPointer values should never be equal */
1654  Assert(false);
1655 
1656  return 0;
1657 }
unsigned int uint32
Definition: c.h:506
uint32 Bucket
Definition: hash.h:35
Bucket _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket, uint32 highmask, uint32 lowmask)
Definition: hashutil.c:125
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().

◆ comparetup_index_hash_tiebreak()

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

Definition at line 1664 of file tuplesortvariants.c.

1666 {
1667  Assert(false);
1668 
1669  return 0;
1670 }

References Assert.

Referenced by tuplesort_begin_index_hash().

◆ freestate_cluster()

static void freestate_cluster ( Tuplesortstate state)
static

Definition at line 1399 of file tuplesortvariants.c.

1400 {
1403 
1404  /* Free any execution state created for CLUSTER case */
1405  if (arg->estate != NULL)
1406  {
1407  ExprContext *econtext = GetPerTupleExprContext(arg->estate);
1408 
1410  FreeExecutorState(arg->estate);
1411  }
1412 }
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1341
void FreeExecutorState(EState *estate)
Definition: execUtils.c:189
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:255

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 1370 of file tuplesortvariants.c.

1372 {
1375  unsigned int t_len = tuplen - sizeof(ItemPointerData) - sizeof(int);
1377  t_len + HEAPTUPLESIZE);
1378 
1379  /* Reconstruct the HeapTupleData header */
1380  tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1381  tuple->t_len = t_len;
1382  LogicalTapeReadExact(tape, &tuple->t_self, sizeof(ItemPointerData));
1383  /* We don't currently bother to reconstruct t_tableOid */
1384  tuple->t_tableOid = InvalidOid;
1385  /* Read in the tuple body */
1386  LogicalTapeReadExact(tape, tuple->t_data, tuple->t_len);
1387  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1388  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1389  stup->tuple = (void *) tuple;
1390  /* set up first-column key value, if it's a simple column */
1391  if (base->haveDatum1)
1392  stup->datum1 = heap_getattr(tuple,
1393  arg->indexInfo->ii_IndexAttrNumbers[0],
1394  arg->tupDesc,
1395  &stup->isnull1);
1396 }
#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:151
void * tuple
Definition: tuplesort.h:149
Datum datum1
Definition: tuplesort.h:150
void * tuplesort_readtup_alloc(Tuplesortstate *state, Size tuplen)
Definition: tuplesort.c:2921
#define TUPLESORT_RANDOMACCESS
Definition: tuplesort.h:96
#define LogicalTapeReadExact(tape, ptr, len)
Definition: tuplesort.h:262

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 1858 of file tuplesortvariants.c.

1860 {
1862  unsigned int tuplen = len - sizeof(unsigned int);
1863 
1864  if (tuplen == 0)
1865  {
1866  /* it's NULL */
1867  stup->datum1 = (Datum) 0;
1868  stup->isnull1 = true;
1869  stup->tuple = NULL;
1870  }
1871  else if (!base->tuples)
1872  {
1873  Assert(tuplen == sizeof(Datum));
1874  LogicalTapeReadExact(tape, &stup->datum1, tuplen);
1875  stup->isnull1 = false;
1876  stup->tuple = NULL;
1877  }
1878  else
1879  {
1880  void *raddr = tuplesort_readtup_alloc(state, tuplen);
1881 
1882  LogicalTapeReadExact(tape, raddr, tuplen);
1883  stup->datum1 = PointerGetDatum(raddr);
1884  stup->isnull1 = false;
1885  stup->tuple = raddr;
1886  }
1887 
1888  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1889  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1890 }
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 1177 of file tuplesortvariants.c.

1179 {
1180  unsigned int tupbodylen = len - sizeof(int);
1181  unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
1183  char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1185  HeapTupleData htup;
1186 
1187  /* read in the tuple proper */
1188  tuple->t_len = tuplen;
1189  LogicalTapeReadExact(tape, tupbody, tupbodylen);
1190  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1191  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1192  stup->tuple = (void *) tuple;
1193  /* set up first-column key value */
1194  htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
1195  htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
1196  stup->datum1 = heap_getattr(&htup,
1197  base->sortKeys[0].ssup_attno,
1198  (TupleDesc) base->arg,
1199  &stup->isnull1);
1200 }
#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 1687 of file tuplesortvariants.c.

1689 {
1692  unsigned int tuplen = len - sizeof(unsigned int);
1694 
1695  LogicalTapeReadExact(tape, tuple, tuplen);
1696  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1697  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1698  stup->tuple = (void *) tuple;
1699  /* set up first-column key value */
1700  stup->datum1 = index_getattr(tuple,
1701  1,
1702  RelationGetDescr(arg->indexRel),
1703  &stup->isnull1);
1704 }

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().

◆ readtup_index_brin()

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

Definition at line 1755 of file tuplesortvariants.c.

1757 {
1758  BrinSortTuple *tuple;
1760  unsigned int tuplen = len - sizeof(unsigned int);
1761 
1762  /*
1763  * Allocate space for the BRIN sort tuple, which is BrinTuple with an
1764  * extra length field.
1765  */
1767  BRINSORTTUPLE_SIZE(tuplen));
1768 
1769  tuple->tuplen = tuplen;
1770 
1771  LogicalTapeReadExact(tape, &tuple->tuple, tuplen);
1772  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1773  LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1774  stup->tuple = (void *) tuple;
1775 
1776  /* set up first-column key value, which is block number */
1777  stup->datum1 = tuple->tuple.bt_blkno;
1778 }
BlockNumber bt_blkno
Definition: brin_tuple.h:66
#define BRINSORTTUPLE_SIZE(len)

References BRINSORTTUPLE_SIZE, BrinTuple::bt_blkno, SortTuple::datum1, len, LogicalTapeReadExact, TuplesortPublic::sortopt, BrinSortTuple::tuple, SortTuple::tuple, BrinSortTuple::tuplen, TUPLESORT_RANDOMACCESS, tuplesort_readtup_alloc(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_brin().

◆ removeabbrev_cluster()

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

Definition at line 1208 of file tuplesortvariants.c.

1209 {
1210  int i;
1213 
1214  for (i = 0; i < count; i++)
1215  {
1216  HeapTuple tup;
1217 
1218  tup = (HeapTuple) stups[i].tuple;
1219  stups[i].datum1 = heap_getattr(tup,
1220  arg->indexInfo->ii_IndexAttrNumbers[0],
1221  arg->tupDesc,
1222  &stups[i].isnull1);
1223  }
1224 }
for(;;)
int i
Definition: isn.c:73

References arg, TuplesortPublic::arg, SortTuple::datum1, for(), 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 1785 of file tuplesortvariants.c.

1786 {
1787  int i;
1788 
1789  for (i = 0; i < count; i++)
1790  stups[i].datum1 = PointerGetDatum(stups[i].tuple);
1791 }

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 1064 of file tuplesortvariants.c.

1065 {
1066  int i;
1068 
1069  for (i = 0; i < count; i++)
1070  {
1071  HeapTupleData htup;
1072 
1073  htup.t_len = ((MinimalTuple) stups[i].tuple)->t_len +
1075  htup.t_data = (HeapTupleHeader) ((char *) stups[i].tuple -
1077  stups[i].datum1 = heap_getattr(&htup,
1078  base->sortKeys[0].ssup_attno,
1079  (TupleDesc) base->arg,
1080  &stups[i].isnull1);
1081  }
1082 }

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 1423 of file tuplesortvariants.c.

1424 {
1427  int i;
1428 
1429  for (i = 0; i < count; i++)
1430  {
1431  IndexTuple tuple;
1432 
1433  tuple = stups[i].tuple;
1434  stups[i].datum1 = index_getattr(tuple,
1435  1,
1436  RelationGetDescr(arg->indexRel),
1437  &stups[i].isnull1);
1438  }
1439 }

References arg, TuplesortPublic::arg, SortTuple::datum1, for(), 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().

◆ removeabbrev_index_brin()

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

Definition at line 1711 of file tuplesortvariants.c.

1712 {
1713  int i;
1714 
1715  for (i = 0; i < count; i++)
1716  {
1717  BrinSortTuple *tuple;
1718 
1719  tuple = stups[i].tuple;
1720  stups[i].datum1 = tuple->tuple.bt_blkno;
1721  }
1722 }

References BrinTuple::bt_blkno, SortTuple::datum1, i, BrinSortTuple::tuple, and SortTuple::tuple.

Referenced by tuplesort_begin_index_brin().

◆ tuplesort_begin_cluster()

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

Definition at line 243 of file tuplesortvariants.c.

247 {
248  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
249  sortopt);
251  BTScanInsert indexScanKey;
252  MemoryContext oldcontext;
254  int i;
255 
256  Assert(indexRel->rd_rel->relam == BTREE_AM_OID);
257 
258  oldcontext = MemoryContextSwitchTo(base->maincontext);
260 
261 #ifdef TRACE_SORT
262  if (trace_sort)
263  elog(LOG,
264  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
266  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
267 #endif
268 
270 
271  TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
272  false, /* no unique check */
273  base->nKeys,
274  workMem,
275  sortopt & TUPLESORT_RANDOMACCESS,
276  PARALLEL_SORT(coordinate));
277 
281  base->writetup = writetup_cluster;
282  base->readtup = readtup_cluster;
284  base->arg = arg;
285 
286  arg->indexInfo = BuildIndexInfo(indexRel);
287 
288  /*
289  * If we don't have a simple leading attribute, we don't currently
290  * initialize datum1, so disable optimizations that require it.
291  */
292  if (arg->indexInfo->ii_IndexAttrNumbers[0] == 0)
293  base->haveDatum1 = false;
294  else
295  base->haveDatum1 = true;
296 
297  arg->tupDesc = tupDesc; /* assume we need not copy tupDesc */
298 
299  indexScanKey = _bt_mkscankey(indexRel, NULL);
300 
301  if (arg->indexInfo->ii_Expressions != NULL)
302  {
303  TupleTableSlot *slot;
304  ExprContext *econtext;
305 
306  /*
307  * We will need to use FormIndexDatum to evaluate the index
308  * expressions. To do that, we need an EState, as well as a
309  * TupleTableSlot to put the table tuples into. The econtext's
310  * scantuple has to point to that slot, too.
311  */
312  arg->estate = CreateExecutorState();
313  slot = MakeSingleTupleTableSlot(tupDesc, &TTSOpsHeapTuple);
314  econtext = GetPerTupleExprContext(arg->estate);
315  econtext->ecxt_scantuple = slot;
316  }
317 
318  /* Prepare SortSupport data for each column */
319  base->sortKeys = (SortSupport) palloc0(base->nKeys *
320  sizeof(SortSupportData));
321 
322  for (i = 0; i < base->nKeys; i++)
323  {
324  SortSupport sortKey = base->sortKeys + i;
325  ScanKey scanKey = indexScanKey->scankeys + i;
326  int16 strategy;
327 
328  sortKey->ssup_cxt = CurrentMemoryContext;
329  sortKey->ssup_collation = scanKey->sk_collation;
330  sortKey->ssup_nulls_first =
331  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
332  sortKey->ssup_attno = scanKey->sk_attno;
333  /* Convey if abbreviation optimization is applicable in principle */
334  sortKey->abbreviate = (i == 0 && base->haveDatum1);
335 
336  Assert(sortKey->ssup_attno != 0);
337 
338  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
340 
341  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
342  }
343 
344  pfree(indexScanKey);
345 
346  MemoryContextSwitchTo(oldcontext);
347 
348  return state;
349 }
signed short int16
Definition: c.h:493
#define LOG
Definition: elog.h:31
#define elog(elevel,...)
Definition: elog.h:224
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:85
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1325
EState * CreateExecutorState(void)
Definition: execUtils.c:88
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:2407
void pfree(void *pointer)
Definition: mcxt.c:1520
void * palloc0(Size size)
Definition: mcxt.c:1346
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:1128
#define SK_BT_DESC
Definition: nbtree.h:1127
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
Definition: nbtutils.c:129
MemoryContextSwitchTo(old_ctx)
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:511
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:524
void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, SortSupport ssup)
Definition: sortsupport.c:161
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define BTLessStrategyNumber
Definition: stratnum.h:29
ScanKeyData scankeys[INDEX_MAX_KEYS]
Definition: nbtree.h:793
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:218
void(* writetup)(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
Definition: tuplesort.h:194
void(* removeabbrev)(Tuplesortstate *state, SortTuple *stups, int count)
Definition: tuplesort.h:187
void(* freestate)(Tuplesortstate *state)
Definition: tuplesort.h:212
void(* readtup)(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Definition: tuplesort.h:203
SortTupleComparator comparetup
Definition: tuplesort.h:174
SortTupleComparator comparetup_tiebreak
Definition: tuplesort.h:181
Tuplesortstate * tuplesort_begin_common(int workMem, SortCoordinate coordinate, int sortopt)
Definition: tuplesort.c:645
bool trace_sort
Definition: tuplesort.c:124
#define PARALLEL_SORT(coordinate)
Definition: tuplesort.h:255
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(), comparetup_cluster_tiebreak(), TuplesortPublic::comparetup_tiebreak, 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 584 of file tuplesortvariants.c.

587 {
588  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
589  sortopt);
592  MemoryContext oldcontext;
593  int16 typlen;
594  bool typbyval;
595 
596  oldcontext = MemoryContextSwitchTo(base->maincontext);
598 
599 #ifdef TRACE_SORT
600  if (trace_sort)
601  elog(LOG,
602  "begin datum sort: workMem = %d, randomAccess = %c",
603  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
604 #endif
605 
606  base->nKeys = 1; /* always a one-column sort */
607 
608  TRACE_POSTGRESQL_SORT_START(DATUM_SORT,
609  false, /* no unique check */
610  1,
611  workMem,
612  sortopt & TUPLESORT_RANDOMACCESS,
613  PARALLEL_SORT(coordinate));
614 
618  base->writetup = writetup_datum;
619  base->readtup = readtup_datum;
620  base->haveDatum1 = true;
621  base->arg = arg;
622 
623  arg->datumType = datumType;
624 
625  /* lookup necessary attributes of the datum type */
626  get_typlenbyval(datumType, &typlen, &typbyval);
627  arg->datumTypeLen = typlen;
628  base->tuples = !typbyval;
629 
630  /* Prepare SortSupport data */
631  base->sortKeys = (SortSupport) palloc0(sizeof(SortSupportData));
632 
634  base->sortKeys->ssup_collation = sortCollation;
635  base->sortKeys->ssup_nulls_first = nullsFirstFlag;
636 
637  /*
638  * Abbreviation is possible here only for by-reference types. In theory,
639  * a pass-by-value datatype could have an abbreviated form that is cheaper
640  * to compare. In a tuple sort, we could support that, because we can
641  * always extract the original datum from the tuple as needed. Here, we
642  * can't, because a datum sort only stores a single copy of the datum; the
643  * "tuple" field of each SortTuple is NULL.
644  */
645  base->sortKeys->abbreviate = !typbyval;
646 
647  PrepareSortSupportFromOrderingOp(sortOperator, base->sortKeys);
648 
649  /*
650  * The "onlyKey" optimization cannot be used with abbreviated keys, since
651  * tie-breaker comparisons may be required. Typically, the optimization
652  * is only of value to pass-by-value types anyway, whereas abbreviated
653  * keys are typically only of value to pass-by-reference types.
654  */
655  if (!base->sortKeys->abbrev_converter)
656  base->onlyKey = base->sortKeys;
657 
658  MemoryContextSwitchTo(oldcontext);
659 
660  return state;
661 }
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2251
void * palloc(Size size)
Definition: mcxt.c:1316
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:134
SortSupport onlyKey
Definition: tuplesort.h:245
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(), comparetup_datum_tiebreak(), TuplesortPublic::comparetup_tiebreak, 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 168 of file tuplesortvariants.c.

173 {
174  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
175  sortopt);
177  MemoryContext oldcontext;
178  int i;
179 
180  oldcontext = MemoryContextSwitchTo(base->maincontext);
181 
182  Assert(nkeys > 0);
183 
184 #ifdef TRACE_SORT
185  if (trace_sort)
186  elog(LOG,
187  "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
188  nkeys, workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
189 #endif
190 
191  base->nKeys = nkeys;
192 
193  TRACE_POSTGRESQL_SORT_START(HEAP_SORT,
194  false, /* no unique check */
195  nkeys,
196  workMem,
197  sortopt & TUPLESORT_RANDOMACCESS,
198  PARALLEL_SORT(coordinate));
199 
201  base->comparetup = comparetup_heap;
203  base->writetup = writetup_heap;
204  base->readtup = readtup_heap;
205  base->haveDatum1 = true;
206  base->arg = tupDesc; /* assume we need not copy tupDesc */
207 
208  /* Prepare SortSupport data for each column */
209  base->sortKeys = (SortSupport) palloc0(nkeys * sizeof(SortSupportData));
210 
211  for (i = 0; i < nkeys; i++)
212  {
213  SortSupport sortKey = base->sortKeys + i;
214 
215  Assert(attNums[i] != 0);
216  Assert(sortOperators[i] != 0);
217 
218  sortKey->ssup_cxt = CurrentMemoryContext;
219  sortKey->ssup_collation = sortCollations[i];
220  sortKey->ssup_nulls_first = nullsFirstFlags[i];
221  sortKey->ssup_attno = attNums[i];
222  /* Convey if abbreviation optimization is applicable in principle */
223  sortKey->abbreviate = (i == 0 && base->haveDatum1);
224 
225  PrepareSortSupportFromOrderingOp(sortOperators[i], sortKey);
226  }
227 
228  /*
229  * The "onlyKey" optimization cannot be used with abbreviated keys, since
230  * tie-breaker comparisons may be required. Typically, the optimization
231  * is only of value to pass-by-value types anyway, whereas abbreviated
232  * keys are typically only of value to pass-by-reference types.
233  */
234  if (nkeys == 1 && !base->sortKeys->abbrev_converter)
235  base->onlyKey = base->sortKeys;
236 
237  MemoryContextSwitchTo(oldcontext);
238 
239  return state;
240 }
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(), comparetup_heap_tiebreak(), TuplesortPublic::comparetup_tiebreak, 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_brin()

Tuplesortstate* tuplesort_begin_index_brin ( int  workMem,
SortCoordinate  coordinate,
int  sortopt 
)

Definition at line 555 of file tuplesortvariants.c.

558 {
559  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
560  sortopt);
562 
563 #ifdef TRACE_SORT
564  if (trace_sort)
565  elog(LOG,
566  "begin index sort: workMem = %d, randomAccess = %c",
567  workMem,
568  sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
569 #endif
570 
571  base->nKeys = 1; /* Only one sort column, the block number */
572 
576  base->readtup = readtup_index_brin;
577  base->haveDatum1 = true;
578  base->arg = NULL;
579 
580  return state;
581 }
static void writetup_index_brin(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
static void removeabbrev_index_brin(Tuplesortstate *state, SortTuple *stups, int count)
static void readtup_index_brin(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static int comparetup_index_brin(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)

References TuplesortPublic::arg, TuplesortPublic::comparetup, comparetup_index_brin(), elog, TuplesortPublic::haveDatum1, LOG, TuplesortPublic::nKeys, TuplesortPublic::readtup, readtup_index_brin(), TuplesortPublic::removeabbrev, removeabbrev_index_brin(), trace_sort, tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TuplesortPublic::writetup, and writetup_index_brin().

Referenced by _brin_parallel_scan_and_build(), and brinbuild().

◆ 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 352 of file tuplesortvariants.c.

359 {
360  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
361  sortopt);
363  BTScanInsert indexScanKey;
365  MemoryContext oldcontext;
366  int i;
367 
368  oldcontext = MemoryContextSwitchTo(base->maincontext);
370 
371 #ifdef TRACE_SORT
372  if (trace_sort)
373  elog(LOG,
374  "begin index sort: unique = %c, workMem = %d, randomAccess = %c",
375  enforceUnique ? 't' : 'f',
376  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
377 #endif
378 
380 
381  TRACE_POSTGRESQL_SORT_START(INDEX_SORT,
382  enforceUnique,
383  base->nKeys,
384  workMem,
385  sortopt & TUPLESORT_RANDOMACCESS,
386  PARALLEL_SORT(coordinate));
387 
391  base->writetup = writetup_index;
392  base->readtup = readtup_index;
393  base->haveDatum1 = true;
394  base->arg = arg;
395 
396  arg->index.heapRel = heapRel;
397  arg->index.indexRel = indexRel;
398  arg->enforceUnique = enforceUnique;
399  arg->uniqueNullsNotDistinct = uniqueNullsNotDistinct;
400 
401  indexScanKey = _bt_mkscankey(indexRel, NULL);
402 
403  /* Prepare SortSupport data for each column */
404  base->sortKeys = (SortSupport) palloc0(base->nKeys *
405  sizeof(SortSupportData));
406 
407  for (i = 0; i < base->nKeys; i++)
408  {
409  SortSupport sortKey = base->sortKeys + i;
410  ScanKey scanKey = indexScanKey->scankeys + i;
411  int16 strategy;
412 
413  sortKey->ssup_cxt = CurrentMemoryContext;
414  sortKey->ssup_collation = scanKey->sk_collation;
415  sortKey->ssup_nulls_first =
416  (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
417  sortKey->ssup_attno = scanKey->sk_attno;
418  /* Convey if abbreviation optimization is applicable in principle */
419  sortKey->abbreviate = (i == 0 && base->haveDatum1);
420 
421  Assert(sortKey->ssup_attno != 0);
422 
423  strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
425 
426  PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
427  }
428 
429  pfree(indexScanKey);
430 
431  MemoryContextSwitchTo(oldcontext);
432 
433  return state;
434 }
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(), comparetup_index_btree_tiebreak(), TuplesortPublic::comparetup_tiebreak, 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 490 of file tuplesortvariants.c.

495 {
496  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
497  sortopt);
499  MemoryContext oldcontext;
501  int i;
502 
503  oldcontext = MemoryContextSwitchTo(base->maincontext);
505 
506 #ifdef TRACE_SORT
507  if (trace_sort)
508  elog(LOG,
509  "begin index sort: workMem = %d, randomAccess = %c",
510  workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
511 #endif
512 
514 
518  base->writetup = writetup_index;
519  base->readtup = readtup_index;
520  base->haveDatum1 = true;
521  base->arg = arg;
522 
523  arg->index.heapRel = heapRel;
524  arg->index.indexRel = indexRel;
525  arg->enforceUnique = false;
526  arg->uniqueNullsNotDistinct = false;
527 
528  /* Prepare SortSupport data for each column */
529  base->sortKeys = (SortSupport) palloc0(base->nKeys *
530  sizeof(SortSupportData));
531 
532  for (i = 0; i < base->nKeys; i++)
533  {
534  SortSupport sortKey = base->sortKeys + i;
535 
536  sortKey->ssup_cxt = CurrentMemoryContext;
537  sortKey->ssup_collation = indexRel->rd_indcollation[i];
538  sortKey->ssup_nulls_first = false;
539  sortKey->ssup_attno = i + 1;
540  /* Convey if abbreviation optimization is applicable in principle */
541  sortKey->abbreviate = (i == 0 && base->haveDatum1);
542 
543  Assert(sortKey->ssup_attno != 0);
544 
545  /* Look for a sort support function */
546  PrepareSortSupportFromGistIndexRel(indexRel, sortKey);
547  }
548 
549  MemoryContextSwitchTo(oldcontext);
550 
551  return state;
552 }
void PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup)
Definition: sortsupport.c:188
Oid * rd_indcollation
Definition: rel.h:217

References SortSupportData::abbreviate, arg, TuplesortPublic::arg, Assert, TuplesortPublic::comparetup, comparetup_index_btree(), comparetup_index_btree_tiebreak(), TuplesortPublic::comparetup_tiebreak, 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 437 of file tuplesortvariants.c.

445 {
446  Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
447  sortopt);
449  MemoryContext oldcontext;
451 
452  oldcontext = MemoryContextSwitchTo(base->maincontext);
454 
455 #ifdef TRACE_SORT
456  if (trace_sort)
457  elog(LOG,
458  "begin index sort: high_mask = 0x%x, low_mask = 0x%x, "
459  "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
460  high_mask,
461  low_mask,
462  max_buckets,
463  workMem,
464  sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
465 #endif
466 
467  base->nKeys = 1; /* Only one sort column, the hash code */
468 
472  base->writetup = writetup_index;
473  base->readtup = readtup_index;
474  base->haveDatum1 = true;
475  base->arg = arg;
476 
477  arg->index.heapRel = heapRel;
478  arg->index.indexRel = indexRel;
479 
480  arg->high_mask = high_mask;
481  arg->low_mask = low_mask;
482  arg->max_buckets = max_buckets;
483 
484  MemoryContextSwitchTo(oldcontext);
485 
486  return state;
487 }
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
static int comparetup_index_hash_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)

References arg, TuplesortPublic::arg, TuplesortPublic::comparetup, comparetup_index_hash(), comparetup_index_hash_tiebreak(), TuplesortPublic::comparetup_tiebreak, 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_getbrintuple()

BrinTuple* tuplesort_getbrintuple ( Tuplesortstate state,
Size len,
bool  forward 
)

Definition at line 970 of file tuplesortvariants.c.

971 {
973  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
974  SortTuple stup;
975  BrinSortTuple *btup;
976 
977  if (!tuplesort_gettuple_common(state, forward, &stup))
978  stup.tuple = NULL;
979 
980  MemoryContextSwitchTo(oldcontext);
981 
982  if (!stup.tuple)
983  return NULL;
984 
985  btup = (BrinSortTuple *) stup.tuple;
986 
987  *len = btup->tuplen;
988 
989  return &btup->tuple;
990 }
MemoryContext sortcontext
Definition: tuplesort.h:220
bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1496

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

Referenced by _brin_parallel_merge().

◆ tuplesort_getdatum()

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

Definition at line 1018 of file tuplesortvariants.c.

1020 {
1022  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
1024  SortTuple stup;
1025 
1026  if (!tuplesort_gettuple_common(state, forward, &stup))
1027  {
1028  MemoryContextSwitchTo(oldcontext);
1029  return false;
1030  }
1031 
1032  /* Ensure we copy into caller's memory context */
1033  MemoryContextSwitchTo(oldcontext);
1034 
1035  /* Record abbreviated key for caller */
1036  if (base->sortKeys->abbrev_converter && abbrev)
1037  *abbrev = stup.datum1;
1038 
1039  if (stup.isnull1 || !base->tuples)
1040  {
1041  *val = stup.datum1;
1042  *isNull = stup.isnull1;
1043  }
1044  else
1045  {
1046  /* use stup.tuple because stup.datum1 may be an abbreviation */
1047  if (copy)
1048  *val = datumCopy(PointerGetDatum(stup.tuple), false,
1049  arg->datumTypeLen);
1050  else
1051  *val = PointerGetDatum(stup.tuple);
1052  *isNull = false;
1053  }
1054 
1055  return true;
1056 }
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
long val
Definition: informix.c:670

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 928 of file tuplesortvariants.c.

929 {
931  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
932  SortTuple stup;
933 
934  if (!tuplesort_gettuple_common(state, forward, &stup))
935  stup.tuple = NULL;
936 
937  MemoryContextSwitchTo(oldcontext);
938 
939  return stup.tuple;
940 }

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 949 of file tuplesortvariants.c.

950 {
952  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
953  SortTuple stup;
954 
955  if (!tuplesort_gettuple_common(state, forward, &stup))
956  stup.tuple = NULL;
957 
958  MemoryContextSwitchTo(oldcontext);
959 
960  return (IndexTuple) stup.tuple;
961 }

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 890 of file tuplesortvariants.c.

892 {
894  MemoryContext oldcontext = MemoryContextSwitchTo(base->sortcontext);
895  SortTuple stup;
896 
897  if (!tuplesort_gettuple_common(state, forward, &stup))
898  stup.tuple = NULL;
899 
900  MemoryContextSwitchTo(oldcontext);
901 
902  if (stup.tuple)
903  {
904  /* Record abbreviated key for caller */
905  if (base->sortKeys->abbrev_converter && abbrev)
906  *abbrev = stup.datum1;
907 
908  if (copy)
910 
911  ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, copy);
912  return true;
913  }
914  else
915  {
916  ExecClearTuple(slot);
917  return false;
918  }
919 }
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1533
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1535
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454

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_putbrintuple()

void tuplesort_putbrintuple ( Tuplesortstate state,
BrinTuple tuple,
Size  size 
)

Definition at line 788 of file tuplesortvariants.c.

789 {
790  SortTuple stup;
791  BrinSortTuple *bstup;
794  Size tuplen;
795 
796  /* allocate space for the whole BRIN sort tuple */
797  bstup = palloc(BRINSORTTUPLE_SIZE(size));
798 
799  bstup->tuplen = size;
800  memcpy(&bstup->tuple, tuple, size);
801 
802  stup.tuple = bstup;
803  stup.datum1 = tuple->bt_blkno;
804  stup.isnull1 = false;
805 
806  /* GetMemoryChunkSpace is not supported for bump contexts */
808  tuplen = MAXALIGN(BRINSORTTUPLE_SIZE(size));
809  else
810  tuplen = GetMemoryChunkSpace(bstup);
811 
813  base->sortKeys &&
814  base->sortKeys->abbrev_converter &&
815  !stup.isnull1, tuplen);
816 
817  MemoryContextSwitchTo(oldcontext);
818 }
#define MAXALIGN(LEN)
Definition: c.h:811
size_t Size
Definition: c.h:605
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:721
static pg_noinline void Size size
Definition: slab.c:607
MemoryContext tuplecontext
Definition: tuplesort.h:221
void tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev, Size tuplen)
Definition: tuplesort.c:1189
#define TupleSortUseBumpTupleCxt(opt)
Definition: tuplesort.h:108

References SortSupportData::abbrev_converter, BRINSORTTUPLE_SIZE, BrinTuple::bt_blkno, SortTuple::datum1, GetMemoryChunkSpace(), SortTuple::isnull1, MAXALIGN, MemoryContextSwitchTo(), palloc(), size, TuplesortPublic::sortKeys, TuplesortPublic::sortopt, BrinSortTuple::tuple, SortTuple::tuple, TuplesortPublic::tuplecontext, BrinSortTuple::tuplen, tuplesort_puttuple_common(), TuplesortstateGetPublic, and TupleSortUseBumpTupleCxt.

Referenced by form_and_spill_tuple().

◆ tuplesort_putdatum()

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

Definition at line 826 of file tuplesortvariants.c.

827 {
831  SortTuple stup;
832 
833  /*
834  * Pass-by-value types or null values are just stored directly in
835  * stup.datum1 (and stup.tuple is not used and set to NULL).
836  *
837  * Non-null pass-by-reference values need to be copied into memory we
838  * control, and possibly abbreviated. The copied value is pointed to by
839  * stup.tuple and is treated as the canonical copy (e.g. to return via
840  * tuplesort_getdatum or when writing to tape); stup.datum1 gets the
841  * abbreviated value if abbreviation is happening, otherwise it's
842  * identical to stup.tuple.
843  */
844 
845  if (isNull || !base->tuples)
846  {
847  /*
848  * Set datum1 to zeroed representation for NULLs (to be consistent,
849  * and to support cheap inequality tests for NULL abbreviated keys).
850  */
851  stup.datum1 = !isNull ? val : (Datum) 0;
852  stup.isnull1 = isNull;
853  stup.tuple = NULL; /* no separate storage */
854  }
855  else
856  {
857  stup.isnull1 = false;
858  stup.datum1 = datumCopy(val, false, arg->datumTypeLen);
859  stup.tuple = DatumGetPointer(stup.datum1);
860  }
861 
863  base->tuples &&
864  base->sortKeys->abbrev_converter && !isNull, 0);
865 
866  MemoryContextSwitchTo(oldcontext);
867 }
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312

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 709 of file tuplesortvariants.c.

710 {
711  SortTuple stup;
715  Size tuplen;
716 
717  /* copy the tuple into sort storage */
718  tup = heap_copytuple(tup);
719  stup.tuple = (void *) tup;
720 
721  /*
722  * set up first-column key value, and potentially abbreviate, if it's a
723  * simple column
724  */
725  if (base->haveDatum1)
726  {
727  stup.datum1 = heap_getattr(tup,
728  arg->indexInfo->ii_IndexAttrNumbers[0],
729  arg->tupDesc,
730  &stup.isnull1);
731  }
732 
733  /* GetMemoryChunkSpace is not supported for bump contexts */
735  tuplen = MAXALIGN(HEAPTUPLESIZE + tup->t_len);
736  else
737  tuplen = GetMemoryChunkSpace(tup);
738 
740  base->haveDatum1 &&
741  base->sortKeys->abbrev_converter &&
742  !stup.isnull1, tuplen);
743 
744  MemoryContextSwitchTo(oldcontext);
745 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776

References SortSupportData::abbrev_converter, arg, TuplesortPublic::arg, SortTuple::datum1, GetMemoryChunkSpace(), TuplesortPublic::haveDatum1, heap_copytuple(), heap_getattr(), HEAPTUPLESIZE, SortTuple::isnull1, MAXALIGN, MemoryContextSwitchTo(), TuplesortPublic::sortKeys, TuplesortPublic::sortopt, HeapTupleData::t_len, SortTuple::tuple, TuplesortPublic::tuplecontext, tuplesort_puttuple_common(), TuplesortstateGetPublic, and TupleSortUseBumpTupleCxt.

Referenced by heapam_relation_copy_for_cluster().

◆ tuplesort_putindextuplevalues()

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

Definition at line 752 of file tuplesortvariants.c.

755 {
756  SortTuple stup;
757  IndexTuple tuple;
760  Size tuplen;
761 
763  isnull, base->tuplecontext);
764  tuple = ((IndexTuple) stup.tuple);
765  tuple->t_tid = *self;
766  /* set up first-column key value */
767  stup.datum1 = index_getattr(tuple,
768  1,
769  RelationGetDescr(arg->indexRel),
770  &stup.isnull1);
771 
772  /* GetMemoryChunkSpace is not supported for bump contexts */
774  tuplen = MAXALIGN(tuple->t_info & INDEX_SIZE_MASK);
775  else
776  tuplen = GetMemoryChunkSpace(tuple);
777 
779  base->sortKeys &&
780  base->sortKeys->abbrev_converter &&
781  !stup.isnull1, tuplen);
782 }
IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull, MemoryContext context)
Definition: indextuple.c:65
#define INDEX_SIZE_MASK
Definition: itup.h:65
unsigned short t_info
Definition: itup.h:49

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

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

◆ tuplesort_puttupleslot()

void tuplesort_puttupleslot ( Tuplesortstate state,
TupleTableSlot slot 
)

Definition at line 669 of file tuplesortvariants.c.

670 {
673  TupleDesc tupDesc = (TupleDesc) base->arg;
674  SortTuple stup;
675  MinimalTuple tuple;
676  HeapTupleData htup;
677  Size tuplen;
678 
679  /* copy the tuple into sort storage */
680  tuple = ExecCopySlotMinimalTuple(slot);
681  stup.tuple = (void *) tuple;
682  /* set up first-column key value */
683  htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
684  htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
685  stup.datum1 = heap_getattr(&htup,
686  base->sortKeys[0].ssup_attno,
687  tupDesc,
688  &stup.isnull1);
689 
690  /* GetMemoryChunkSpace is not supported for bump contexts */
692  tuplen = MAXALIGN(tuple->t_len);
693  else
694  tuplen = GetMemoryChunkSpace(tuple);
695 
697  base->sortKeys->abbrev_converter &&
698  !stup.isnull1, tuplen);
699 
700  MemoryContextSwitchTo(oldcontext);
701 }
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
Definition: tuptable.h:492

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

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 1355 of file tuplesortvariants.c.

1356 {
1358  HeapTuple tuple = (HeapTuple) stup->tuple;
1359  unsigned int tuplen = tuple->t_len + sizeof(ItemPointerData) + sizeof(int);
1360 
1361  /* We need to store t_self, but not other fields of HeapTupleData */
1362  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1363  LogicalTapeWrite(tape, &tuple->t_self, sizeof(ItemPointerData));
1364  LogicalTapeWrite(tape, tuple->t_data, tuple->t_len);
1365  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1366  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1367 }
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 1824 of file tuplesortvariants.c.

1825 {
1828  void *waddr;
1829  unsigned int tuplen;
1830  unsigned int writtenlen;
1831 
1832  if (stup->isnull1)
1833  {
1834  waddr = NULL;
1835  tuplen = 0;
1836  }
1837  else if (!base->tuples)
1838  {
1839  waddr = &stup->datum1;
1840  tuplen = sizeof(Datum);
1841  }
1842  else
1843  {
1844  waddr = stup->tuple;
1845  tuplen = datumGetSize(PointerGetDatum(stup->tuple), false, arg->datumTypeLen);
1846  Assert(tuplen != 0);
1847  }
1848 
1849  writtenlen = tuplen + sizeof(unsigned int);
1850 
1851  LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
1852  LogicalTapeWrite(tape, waddr, tuplen);
1853  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1854  LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
1855 }
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 1158 of file tuplesortvariants.c.

1159 {
1161  MinimalTuple tuple = (MinimalTuple) stup->tuple;
1162 
1163  /* the part of the MinimalTuple we'll write: */
1164  char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1165  unsigned int tupbodylen = tuple->t_len - MINIMAL_TUPLE_DATA_OFFSET;
1166 
1167  /* total on-disk footprint: */
1168  unsigned int tuplen = tupbodylen + sizeof(int);
1169 
1170  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1171  LogicalTapeWrite(tape, tupbody, tupbodylen);
1172  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1173  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1174 }

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 1673 of file tuplesortvariants.c.

1674 {
1676  IndexTuple tuple = (IndexTuple) stup->tuple;
1677  unsigned int tuplen;
1678 
1679  tuplen = IndexTupleSize(tuple) + sizeof(tuplen);
1680  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1681  LogicalTapeWrite(tape, tuple, IndexTupleSize(tuple));
1682  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1683  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1684 }
#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().

◆ writetup_index_brin()

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

Definition at line 1741 of file tuplesortvariants.c.

1742 {
1744  BrinSortTuple *tuple = (BrinSortTuple *) stup->tuple;
1745  unsigned int tuplen = tuple->tuplen;
1746 
1747  tuplen = tuplen + sizeof(tuplen);
1748  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1749  LogicalTapeWrite(tape, &tuple->tuple, tuple->tuplen);
1750  if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1751  LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1752 }

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

Referenced by tuplesort_begin_index_brin().