PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 1213 of file tuplesortvariants.c.

1215{
1217 SortSupport sortKey = base->sortKeys;
1218 int32 compare;
1219
1220 /* Compare the leading sort key, if it's simple */
1221 if (base->haveDatum1)
1222 {
1223 compare = ApplySortComparator(a->datum1, a->isnull1,
1224 b->datum1, b->isnull1,
1225 sortKey);
1226 if (compare != 0)
1227 return compare;
1228 }
1229
1231}
int32_t int32
Definition: c.h:481
static int compare(const void *arg1, const void *arg2)
Definition: geqo_pool.c:145
int b
Definition: isn.c:69
int a
Definition: isn.c:68
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 1234 of file tuplesortvariants.c.

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

1781{
1783 int compare;
1784
1785 compare = ApplySortComparator(a->datum1, a->isnull1,
1786 b->datum1, b->isnull1,
1787 base->sortKeys);
1788 if (compare != 0)
1789 return compare;
1790
1792}
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 1795 of file tuplesortvariants.c.

1796{
1798 int32 compare = 0;
1799
1800 /* if we have abbreviations, then "tuple" has the original value */
1801 if (base->sortKeys->abbrev_converter)
1803 PointerGetDatum(b->tuple), b->isnull1,
1804 base->sortKeys);
1805
1806 return compare;
1807}
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 1071 of file tuplesortvariants.c.

1072{
1074 SortSupport sortKey = base->sortKeys;
1075 int32 compare;
1076
1077
1078 /* Compare the leading sort key */
1079 compare = ApplySortComparator(a->datum1, a->isnull1,
1080 b->datum1, b->isnull1,
1081 sortKey);
1082 if (compare != 0)
1083 return compare;
1084
1085 /* Compare additional sort keys */
1087}
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 1090 of file tuplesortvariants.c.

1091{
1093 SortSupport sortKey = base->sortKeys;
1094 HeapTupleData ltup;
1095 HeapTupleData rtup;
1096 TupleDesc tupDesc;
1097 int nkey;
1098 int32 compare;
1099 AttrNumber attno;
1100 Datum datum1,
1101 datum2;
1102 bool isnull1,
1103 isnull2;
1104
1105 ltup.t_len = ((MinimalTuple) a->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
1106 ltup.t_data = (HeapTupleHeader) ((char *) a->tuple - MINIMAL_TUPLE_OFFSET);
1107 rtup.t_len = ((MinimalTuple) b->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
1108 rtup.t_data = (HeapTupleHeader) ((char *) b->tuple - MINIMAL_TUPLE_OFFSET);
1109 tupDesc = (TupleDesc) base->arg;
1110
1111 if (sortKey->abbrev_converter)
1112 {
1113 attno = sortKey->ssup_attno;
1114
1115 datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
1116 datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
1117
1118 compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1119 datum2, isnull2,
1120 sortKey);
1121 if (compare != 0)
1122 return compare;
1123 }
1124
1125 sortKey++;
1126 for (nkey = 1; nkey < base->nKeys; nkey++, sortKey++)
1127 {
1128 attno = sortKey->ssup_attno;
1129
1130 datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
1131 datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
1132
1133 compare = ApplySortComparator(datum1, isnull1,
1134 datum2, isnull2,
1135 sortKey);
1136 if (compare != 0)
1137 return compare;
1138 }
1139
1140 return 0;
1141}
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:137

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

1713{
1714 Assert(TuplesortstateGetPublic(state)->haveDatum1);
1715
1716 if (DatumGetUInt32(a->datum1) > DatumGetUInt32(b->datum1))
1717 return 1;
1718
1719 if (DatumGetUInt32(a->datum1) < DatumGetUInt32(b->datum1))
1720 return -1;
1721
1722 /* silence compilers */
1723 return 0;
1724}
#define Assert(condition)
Definition: c.h:812
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 1428 of file tuplesortvariants.c.

1430{
1431 /*
1432 * This is similar to comparetup_heap(), but expects index tuples. There
1433 * is also special handling for enforcing uniqueness, and special
1434 * treatment for equal keys at the end.
1435 */
1437 SortSupport sortKey = base->sortKeys;
1438 int32 compare;
1439
1440 /* Compare the leading sort key */
1441 compare = ApplySortComparator(a->datum1, a->isnull1,
1442 b->datum1, b->isnull1,
1443 sortKey);
1444 if (compare != 0)
1445 return compare;
1446
1447 /* Compare additional sort keys */
1449}
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 1452 of file tuplesortvariants.c.

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

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

1576{
1577 Bucket bucket1;
1578 Bucket bucket2;
1579 uint32 hash1;
1580 uint32 hash2;
1581 IndexTuple tuple1;
1582 IndexTuple tuple2;
1585
1586 /*
1587 * Fetch hash keys and mask off bits we don't want to sort by, so that the
1588 * initial sort is just on the bucket number. We know that the first
1589 * column of the index tuple is the hash key.
1590 */
1591 Assert(!a->isnull1);
1592 bucket1 = _hash_hashkey2bucket(DatumGetUInt32(a->datum1),
1593 arg->max_buckets, arg->high_mask,
1594 arg->low_mask);
1595 Assert(!b->isnull1);
1596 bucket2 = _hash_hashkey2bucket(DatumGetUInt32(b->datum1),
1597 arg->max_buckets, arg->high_mask,
1598 arg->low_mask);
1599 if (bucket1 > bucket2)
1600 return 1;
1601 else if (bucket1 < bucket2)
1602 return -1;
1603
1604 /*
1605 * If bucket values are equal, sort by hash values. This allows us to
1606 * insert directly onto bucket/overflow pages, where the index tuples are
1607 * stored in hash order to allow fast binary search within each page.
1608 */
1609 hash1 = DatumGetUInt32(a->datum1);
1610 hash2 = DatumGetUInt32(b->datum1);
1611 if (hash1 > hash2)
1612 return 1;
1613 else if (hash1 < hash2)
1614 return -1;
1615
1616 /*
1617 * If hash values are equal, we sort on ItemPointer. This does not affect
1618 * validity of the finished index, but it may be useful to have index
1619 * scans in physical order.
1620 */
1621 tuple1 = (IndexTuple) a->tuple;
1622 tuple2 = (IndexTuple) b->tuple;
1623
1624 {
1627
1628 if (blk1 != blk2)
1629 return (blk1 < blk2) ? -1 : 1;
1630 }
1631 {
1634
1635 if (pos1 != pos2)
1636 return (pos1 < pos2) ? -1 : 1;
1637 }
1638
1639 /* ItemPointer values should never be equal */
1640 Assert(false);
1641
1642 return 0;
1643}
uint32_t uint32
Definition: c.h:485
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 1650 of file tuplesortvariants.c.

1652{
1653 Assert(false);
1654
1655 return 0;
1656}

References Assert.

Referenced by tuplesort_begin_index_hash().

◆ freestate_cluster()

static void freestate_cluster ( Tuplesortstate state)
static

Definition at line 1385 of file tuplesortvariants.c.

1386{
1389
1390 /* Free any execution state created for CLUSTER case */
1391 if (arg->estate != NULL)
1392 {
1393 ExprContext *econtext = GetPerTupleExprContext(arg->estate);
1394
1396 FreeExecutorState(arg->estate);
1397 }
1398}
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1441
void FreeExecutorState(EState *estate)
Definition: execUtils.c:191
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:258

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

1358{
1361 unsigned int t_len = tuplen - sizeof(ItemPointerData) - sizeof(int);
1363 t_len + HEAPTUPLESIZE);
1364
1365 /* Reconstruct the HeapTupleData header */
1366 tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1367 tuple->t_len = t_len;
1368 LogicalTapeReadExact(tape, &tuple->t_self, sizeof(ItemPointerData));
1369 /* We don't currently bother to reconstruct t_tableOid */
1370 tuple->t_tableOid = InvalidOid;
1371 /* Read in the tuple body */
1372 LogicalTapeReadExact(tape, tuple->t_data, tuple->t_len);
1373 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1374 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1375 stup->tuple = tuple;
1376 /* set up first-column key value, if it's a simple column */
1377 if (base->haveDatum1)
1378 stup->datum1 = heap_getattr(tuple,
1379 arg->indexInfo->ii_IndexAttrNumbers[0],
1380 arg->tupDesc,
1381 &stup->isnull1);
1382}
#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:2883
#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 1844 of file tuplesortvariants.c.

1846{
1848 unsigned int tuplen = len - sizeof(unsigned int);
1849
1850 if (tuplen == 0)
1851 {
1852 /* it's NULL */
1853 stup->datum1 = (Datum) 0;
1854 stup->isnull1 = true;
1855 stup->tuple = NULL;
1856 }
1857 else if (!base->tuples)
1858 {
1859 Assert(tuplen == sizeof(Datum));
1860 LogicalTapeReadExact(tape, &stup->datum1, tuplen);
1861 stup->isnull1 = false;
1862 stup->tuple = NULL;
1863 }
1864 else
1865 {
1866 void *raddr = tuplesort_readtup_alloc(state, tuplen);
1867
1868 LogicalTapeReadExact(tape, raddr, tuplen);
1869 stup->datum1 = PointerGetDatum(raddr);
1870 stup->isnull1 = false;
1871 stup->tuple = raddr;
1872 }
1873
1874 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1875 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1876}
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 1163 of file tuplesortvariants.c.

1165{
1166 unsigned int tupbodylen = len - sizeof(int);
1167 unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
1169 char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1171 HeapTupleData htup;
1172
1173 /* read in the tuple proper */
1174 tuple->t_len = tuplen;
1175 LogicalTapeReadExact(tape, tupbody, tupbodylen);
1176 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1177 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1178 stup->tuple = tuple;
1179 /* set up first-column key value */
1180 htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
1181 htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
1182 stup->datum1 = heap_getattr(&htup,
1183 base->sortKeys[0].ssup_attno,
1184 (TupleDesc) base->arg,
1185 &stup->isnull1);
1186}
#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 1673 of file tuplesortvariants.c.

1675{
1678 unsigned int tuplen = len - sizeof(unsigned int);
1680
1681 LogicalTapeReadExact(tape, tuple, tuplen);
1682 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1683 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1684 stup->tuple = tuple;
1685 /* set up first-column key value */
1686 stup->datum1 = index_getattr(tuple,
1687 1,
1688 RelationGetDescr(arg->indexRel),
1689 &stup->isnull1);
1690}

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

1743{
1744 BrinSortTuple *tuple;
1746 unsigned int tuplen = len - sizeof(unsigned int);
1747
1748 /*
1749 * Allocate space for the BRIN sort tuple, which is BrinTuple with an
1750 * extra length field.
1751 */
1753 BRINSORTTUPLE_SIZE(tuplen));
1754
1755 tuple->tuplen = tuplen;
1756
1757 LogicalTapeReadExact(tape, &tuple->tuple, tuplen);
1758 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1759 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1760 stup->tuple = tuple;
1761
1762 /* set up first-column key value, which is block number */
1763 stup->datum1 = tuple->tuple.bt_blkno;
1764}
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 1194 of file tuplesortvariants.c.

1195{
1196 int i;
1199
1200 for (i = 0; i < count; i++)
1201 {
1202 HeapTuple tup;
1203
1204 tup = (HeapTuple) stups[i].tuple;
1205 stups[i].datum1 = heap_getattr(tup,
1206 arg->indexInfo->ii_IndexAttrNumbers[0],
1207 arg->tupDesc,
1208 &stups[i].isnull1);
1209 }
1210}
for(;;)
int i
Definition: isn.c:72

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

1772{
1773 int i;
1774
1775 for (i = 0; i < count; i++)
1776 stups[i].datum1 = PointerGetDatum(stups[i].tuple);
1777}

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

1051{
1052 int i;
1054
1055 for (i = 0; i < count; i++)
1056 {
1057 HeapTupleData htup;
1058
1059 htup.t_len = ((MinimalTuple) stups[i].tuple)->t_len +
1061 htup.t_data = (HeapTupleHeader) ((char *) stups[i].tuple -
1063 stups[i].datum1 = heap_getattr(&htup,
1064 base->sortKeys[0].ssup_attno,
1065 (TupleDesc) base->arg,
1066 &stups[i].isnull1);
1067 }
1068}

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

1410{
1413 int i;
1414
1415 for (i = 0; i < count; i++)
1416 {
1417 IndexTuple tuple;
1418
1419 tuple = stups[i].tuple;
1420 stups[i].datum1 = index_getattr(tuple,
1421 1,
1422 RelationGetDescr(arg->indexRel),
1423 &stups[i].isnull1);
1424 }
1425}

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

1698{
1699 int i;
1700
1701 for (i = 0; i < count; i++)
1702 {
1703 BrinSortTuple *tuple;
1704
1705 tuple = stups[i].tuple;
1706 stups[i].datum1 = tuple->tuple.bt_blkno;
1707 }
1708}

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

245{
246 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
247 sortopt);
249 BTScanInsert indexScanKey;
250 MemoryContext oldcontext;
252 int i;
253
254 Assert(indexRel->rd_rel->relam == BTREE_AM_OID);
255
256 oldcontext = MemoryContextSwitchTo(base->maincontext);
258
259 if (trace_sort)
260 elog(LOG,
261 "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
263 workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
264
266
267 TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
268 false, /* no unique check */
269 base->nKeys,
270 workMem,
271 sortopt & TUPLESORT_RANDOMACCESS,
272 PARALLEL_SORT(coordinate));
273
278 base->readtup = readtup_cluster;
280 base->arg = arg;
281
282 arg->indexInfo = BuildIndexInfo(indexRel);
283
284 /*
285 * If we don't have a simple leading attribute, we don't currently
286 * initialize datum1, so disable optimizations that require it.
287 */
288 if (arg->indexInfo->ii_IndexAttrNumbers[0] == 0)
289 base->haveDatum1 = false;
290 else
291 base->haveDatum1 = true;
292
293 arg->tupDesc = tupDesc; /* assume we need not copy tupDesc */
294
295 indexScanKey = _bt_mkscankey(indexRel, NULL);
296
297 if (arg->indexInfo->ii_Expressions != NULL)
298 {
299 TupleTableSlot *slot;
300 ExprContext *econtext;
301
302 /*
303 * We will need to use FormIndexDatum to evaluate the index
304 * expressions. To do that, we need an EState, as well as a
305 * TupleTableSlot to put the table tuples into. The econtext's
306 * scantuple has to point to that slot, too.
307 */
308 arg->estate = CreateExecutorState();
310 econtext = GetPerTupleExprContext(arg->estate);
311 econtext->ecxt_scantuple = slot;
312 }
313
314 /* Prepare SortSupport data for each column */
315 base->sortKeys = (SortSupport) palloc0(base->nKeys *
316 sizeof(SortSupportData));
317
318 for (i = 0; i < base->nKeys; i++)
319 {
320 SortSupport sortKey = base->sortKeys + i;
321 ScanKey scanKey = indexScanKey->scankeys + i;
322 int16 strategy;
323
325 sortKey->ssup_collation = scanKey->sk_collation;
326 sortKey->ssup_nulls_first =
327 (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
328 sortKey->ssup_attno = scanKey->sk_attno;
329 /* Convey if abbreviation optimization is applicable in principle */
330 sortKey->abbreviate = (i == 0 && base->haveDatum1);
331
332 Assert(sortKey->ssup_attno != 0);
333
334 strategy = (scanKey->sk_flags & SK_BT_DESC) != 0 ?
336
337 PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey);
338 }
339
340 pfree(indexScanKey);
341
342 MemoryContextSwitchTo(oldcontext);
343
344 return state;
345}
int16_t int16
Definition: c.h:480
#define LOG
Definition: elog.h:31
#define elog(elevel,...)
Definition: elog.h:225
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1425
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:85
EState * CreateExecutorState(void)
Definition: execUtils.c:88
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:2426
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:1118
#define SK_BT_DESC
Definition: nbtree.h:1117
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:642
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 572 of file tuplesortvariants.c.

575{
576 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
577 sortopt);
580 MemoryContext oldcontext;
581 int16 typlen;
582 bool typbyval;
583
584 oldcontext = MemoryContextSwitchTo(base->maincontext);
586
587 if (trace_sort)
588 elog(LOG,
589 "begin datum sort: workMem = %d, randomAccess = %c",
590 workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
591
592 base->nKeys = 1; /* always a one-column sort */
593
594 TRACE_POSTGRESQL_SORT_START(DATUM_SORT,
595 false, /* no unique check */
596 1,
597 workMem,
598 sortopt & TUPLESORT_RANDOMACCESS,
599 PARALLEL_SORT(coordinate));
600
604 base->writetup = writetup_datum;
605 base->readtup = readtup_datum;
606 base->haveDatum1 = true;
607 base->arg = arg;
608
609 arg->datumType = datumType;
610
611 /* lookup necessary attributes of the datum type */
612 get_typlenbyval(datumType, &typlen, &typbyval);
613 arg->datumTypeLen = typlen;
614 base->tuples = !typbyval;
615
616 /* Prepare SortSupport data */
617 base->sortKeys = (SortSupport) palloc0(sizeof(SortSupportData));
618
620 base->sortKeys->ssup_collation = sortCollation;
621 base->sortKeys->ssup_nulls_first = nullsFirstFlag;
622
623 /*
624 * Abbreviation is possible here only for by-reference types. In theory,
625 * a pass-by-value datatype could have an abbreviated form that is cheaper
626 * to compare. In a tuple sort, we could support that, because we can
627 * always extract the original datum from the tuple as needed. Here, we
628 * can't, because a datum sort only stores a single copy of the datum; the
629 * "tuple" field of each SortTuple is NULL.
630 */
631 base->sortKeys->abbreviate = !typbyval;
632
633 PrepareSortSupportFromOrderingOp(sortOperator, base->sortKeys);
634
635 /*
636 * The "onlyKey" optimization cannot be used with abbreviated keys, since
637 * tie-breaker comparisons may be required. Typically, the optimization
638 * is only of value to pass-by-value types anyway, whereas abbreviated
639 * keys are typically only of value to pass-by-reference types.
640 */
641 if (!base->sortKeys->abbrev_converter)
642 base->onlyKey = base->sortKeys;
643
644 MemoryContextSwitchTo(oldcontext);
645
646 return state;
647}
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2251
void * palloc(Size size)
Definition: mcxt.c:1317
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 if (trace_sort)
185 elog(LOG,
186 "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
187 nkeys, workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
188
189 base->nKeys = nkeys;
190
191 TRACE_POSTGRESQL_SORT_START(HEAP_SORT,
192 false, /* no unique check */
193 nkeys,
194 workMem,
195 sortopt & TUPLESORT_RANDOMACCESS,
196 PARALLEL_SORT(coordinate));
197
201 base->writetup = writetup_heap;
202 base->readtup = readtup_heap;
203 base->haveDatum1 = true;
204 base->arg = tupDesc; /* assume we need not copy tupDesc */
205
206 /* Prepare SortSupport data for each column */
207 base->sortKeys = (SortSupport) palloc0(nkeys * sizeof(SortSupportData));
208
209 for (i = 0; i < nkeys; i++)
210 {
211 SortSupport sortKey = base->sortKeys + i;
212
213 Assert(attNums[i] != 0);
214 Assert(sortOperators[i] != 0);
215
217 sortKey->ssup_collation = sortCollations[i];
218 sortKey->ssup_nulls_first = nullsFirstFlags[i];
219 sortKey->ssup_attno = attNums[i];
220 /* Convey if abbreviation optimization is applicable in principle */
221 sortKey->abbreviate = (i == 0 && base->haveDatum1);
222
223 PrepareSortSupportFromOrderingOp(sortOperators[i], sortKey);
224 }
225
226 /*
227 * The "onlyKey" optimization cannot be used with abbreviated keys, since
228 * tie-breaker comparisons may be required. Typically, the optimization
229 * is only of value to pass-by-value types anyway, whereas abbreviated
230 * keys are typically only of value to pass-by-reference types.
231 */
232 if (nkeys == 1 && !base->sortKeys->abbrev_converter)
233 base->onlyKey = base->sortKeys;
234
235 MemoryContextSwitchTo(oldcontext);
236
237 return state;
238}
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 545 of file tuplesortvariants.c.

548{
549 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
550 sortopt);
552
553 if (trace_sort)
554 elog(LOG,
555 "begin index sort: workMem = %d, randomAccess = %c",
556 workMem,
557 sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
558
559 base->nKeys = 1; /* Only one sort column, the block number */
560
565 base->haveDatum1 = true;
566 base->arg = NULL;
567
568 return state;
569}
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 348 of file tuplesortvariants.c.

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

487{
488 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
489 sortopt);
491 MemoryContext oldcontext;
493 int i;
494
495 oldcontext = MemoryContextSwitchTo(base->maincontext);
497
498 if (trace_sort)
499 elog(LOG,
500 "begin index sort: workMem = %d, randomAccess = %c",
501 workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
502
504
508 base->writetup = writetup_index;
509 base->readtup = readtup_index;
510 base->haveDatum1 = true;
511 base->arg = arg;
512
513 arg->index.heapRel = heapRel;
514 arg->index.indexRel = indexRel;
515 arg->enforceUnique = false;
516 arg->uniqueNullsNotDistinct = false;
517
518 /* Prepare SortSupport data for each column */
519 base->sortKeys = (SortSupport) palloc0(base->nKeys *
520 sizeof(SortSupportData));
521
522 for (i = 0; i < base->nKeys; i++)
523 {
524 SortSupport sortKey = base->sortKeys + i;
525
527 sortKey->ssup_collation = indexRel->rd_indcollation[i];
528 sortKey->ssup_nulls_first = false;
529 sortKey->ssup_attno = i + 1;
530 /* Convey if abbreviation optimization is applicable in principle */
531 sortKey->abbreviate = (i == 0 && base->haveDatum1);
532
533 Assert(sortKey->ssup_attno != 0);
534
535 /* Look for a sort support function */
536 PrepareSortSupportFromGistIndexRel(indexRel, sortKey);
537 }
538
539 MemoryContextSwitchTo(oldcontext);
540
541 return state;
542}
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 431 of file tuplesortvariants.c.

439{
440 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
441 sortopt);
443 MemoryContext oldcontext;
445
446 oldcontext = MemoryContextSwitchTo(base->maincontext);
448
449 if (trace_sort)
450 elog(LOG,
451 "begin index sort: high_mask = 0x%x, low_mask = 0x%x, "
452 "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
453 high_mask,
454 low_mask,
455 max_buckets,
456 workMem,
457 sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
458
459 base->nKeys = 1; /* Only one sort column, the hash code */
460
464 base->writetup = writetup_index;
465 base->readtup = readtup_index;
466 base->haveDatum1 = true;
467 base->arg = arg;
468
469 arg->index.heapRel = heapRel;
470 arg->index.indexRel = indexRel;
471
472 arg->high_mask = high_mask;
473 arg->low_mask = low_mask;
474 arg->max_buckets = max_buckets;
475
476 MemoryContextSwitchTo(oldcontext);
477
478 return state;
479}
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 956 of file tuplesortvariants.c.

957{
960 SortTuple stup;
961 BrinSortTuple *btup;
962
963 if (!tuplesort_gettuple_common(state, forward, &stup))
964 stup.tuple = NULL;
965
966 MemoryContextSwitchTo(oldcontext);
967
968 if (!stup.tuple)
969 return NULL;
970
971 btup = (BrinSortTuple *) stup.tuple;
972
973 *len = btup->tuplen;
974
975 return &btup->tuple;
976}
MemoryContext sortcontext
Definition: tuplesort.h:220
bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1470

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

1006{
1010 SortTuple stup;
1011
1012 if (!tuplesort_gettuple_common(state, forward, &stup))
1013 {
1014 MemoryContextSwitchTo(oldcontext);
1015 return false;
1016 }
1017
1018 /* Ensure we copy into caller's memory context */
1019 MemoryContextSwitchTo(oldcontext);
1020
1021 /* Record abbreviated key for caller */
1022 if (base->sortKeys->abbrev_converter && abbrev)
1023 *abbrev = stup.datum1;
1024
1025 if (stup.isnull1 || !base->tuples)
1026 {
1027 *val = stup.datum1;
1028 *isNull = stup.isnull1;
1029 }
1030 else
1031 {
1032 /* use stup.tuple because stup.datum1 may be an abbreviation */
1033 if (copy)
1034 *val = datumCopy(PointerGetDatum(stup.tuple), false,
1035 arg->datumTypeLen);
1036 else
1037 *val = PointerGetDatum(stup.tuple);
1038 *isNull = false;
1039 }
1040
1041 return true;
1042}
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
long val
Definition: informix.c:689

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

915{
918 SortTuple stup;
919
920 if (!tuplesort_gettuple_common(state, forward, &stup))
921 stup.tuple = NULL;
922
923 MemoryContextSwitchTo(oldcontext);
924
925 return stup.tuple;
926}

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

936{
939 SortTuple stup;
940
941 if (!tuplesort_gettuple_common(state, forward, &stup))
942 stup.tuple = NULL;
943
944 MemoryContextSwitchTo(oldcontext);
945
946 return (IndexTuple) stup.tuple;
947}

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

878{
881 SortTuple stup;
882
883 if (!tuplesort_gettuple_common(state, forward, &stup))
884 stup.tuple = NULL;
885
886 MemoryContextSwitchTo(oldcontext);
887
888 if (stup.tuple)
889 {
890 /* Record abbreviated key for caller */
891 if (base->sortKeys->abbrev_converter && abbrev)
892 *abbrev = stup.datum1;
893
894 if (copy)
896
897 ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, copy);
898 return true;
899 }
900 else
901 {
902 ExecClearTuple(slot);
903 return false;
904 }
905}
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1633
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1536
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 774 of file tuplesortvariants.c.

775{
776 SortTuple stup;
777 BrinSortTuple *bstup;
780 Size tuplen;
781
782 /* allocate space for the whole BRIN sort tuple */
784
785 bstup->tuplen = size;
786 memcpy(&bstup->tuple, tuple, size);
787
788 stup.tuple = bstup;
789 stup.datum1 = tuple->bt_blkno;
790 stup.isnull1 = false;
791
792 /* GetMemoryChunkSpace is not supported for bump contexts */
795 else
796 tuplen = GetMemoryChunkSpace(bstup);
797
799 base->sortKeys &&
800 base->sortKeys->abbrev_converter &&
801 !stup.isnull1, tuplen);
802
803 MemoryContextSwitchTo(oldcontext);
804}
#define MAXALIGN(LEN)
Definition: c.h:765
size_t Size
Definition: c.h:559
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:1169
#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 812 of file tuplesortvariants.c.

813{
817 SortTuple stup;
818
819 /*
820 * Pass-by-value types or null values are just stored directly in
821 * stup.datum1 (and stup.tuple is not used and set to NULL).
822 *
823 * Non-null pass-by-reference values need to be copied into memory we
824 * control, and possibly abbreviated. The copied value is pointed to by
825 * stup.tuple and is treated as the canonical copy (e.g. to return via
826 * tuplesort_getdatum or when writing to tape); stup.datum1 gets the
827 * abbreviated value if abbreviation is happening, otherwise it's
828 * identical to stup.tuple.
829 */
830
831 if (isNull || !base->tuples)
832 {
833 /*
834 * Set datum1 to zeroed representation for NULLs (to be consistent,
835 * and to support cheap inequality tests for NULL abbreviated keys).
836 */
837 stup.datum1 = !isNull ? val : (Datum) 0;
838 stup.isnull1 = isNull;
839 stup.tuple = NULL; /* no separate storage */
840 }
841 else
842 {
843 stup.isnull1 = false;
844 stup.datum1 = datumCopy(val, false, arg->datumTypeLen);
845 stup.tuple = DatumGetPointer(stup.datum1);
846 }
847
849 base->tuples &&
850 base->sortKeys->abbrev_converter && !isNull, 0);
851
852 MemoryContextSwitchTo(oldcontext);
853}
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 695 of file tuplesortvariants.c.

696{
697 SortTuple stup;
701 Size tuplen;
702
703 /* copy the tuple into sort storage */
704 tup = heap_copytuple(tup);
705 stup.tuple = tup;
706
707 /*
708 * set up first-column key value, and potentially abbreviate, if it's a
709 * simple column
710 */
711 if (base->haveDatum1)
712 {
713 stup.datum1 = heap_getattr(tup,
714 arg->indexInfo->ii_IndexAttrNumbers[0],
715 arg->tupDesc,
716 &stup.isnull1);
717 }
718
719 /* GetMemoryChunkSpace is not supported for bump contexts */
721 tuplen = MAXALIGN(HEAPTUPLESIZE + tup->t_len);
722 else
723 tuplen = GetMemoryChunkSpace(tup);
724
726 base->haveDatum1 &&
727 base->sortKeys->abbrev_converter &&
728 !stup.isnull1, tuplen);
729
730 MemoryContextSwitchTo(oldcontext);
731}
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:778

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

741{
742 SortTuple stup;
743 IndexTuple tuple;
746 Size tuplen;
747
749 isnull, base->tuplecontext);
750 tuple = ((IndexTuple) stup.tuple);
751 tuple->t_tid = *self;
752 /* set up first-column key value */
753 stup.datum1 = index_getattr(tuple,
754 1,
755 RelationGetDescr(arg->indexRel),
756 &stup.isnull1);
757
758 /* GetMemoryChunkSpace is not supported for bump contexts */
760 tuplen = MAXALIGN(tuple->t_info & INDEX_SIZE_MASK);
761 else
762 tuplen = GetMemoryChunkSpace(tuple);
763
765 base->sortKeys &&
766 base->sortKeys->abbrev_converter &&
767 !stup.isnull1, tuplen);
768}
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 655 of file tuplesortvariants.c.

656{
659 TupleDesc tupDesc = (TupleDesc) base->arg;
660 SortTuple stup;
661 MinimalTuple tuple;
662 HeapTupleData htup;
663 Size tuplen;
664
665 /* copy the tuple into sort storage */
666 tuple = ExecCopySlotMinimalTuple(slot);
667 stup.tuple = tuple;
668 /* set up first-column key value */
669 htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
670 htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
671 stup.datum1 = heap_getattr(&htup,
672 base->sortKeys[0].ssup_attno,
673 tupDesc,
674 &stup.isnull1);
675
676 /* GetMemoryChunkSpace is not supported for bump contexts */
678 tuplen = MAXALIGN(tuple->t_len);
679 else
680 tuplen = GetMemoryChunkSpace(tuple);
681
683 base->sortKeys->abbrev_converter &&
684 !stup.isnull1, tuplen);
685
686 MemoryContextSwitchTo(oldcontext);
687}
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 1341 of file tuplesortvariants.c.

1342{
1344 HeapTuple tuple = (HeapTuple) stup->tuple;
1345 unsigned int tuplen = tuple->t_len + sizeof(ItemPointerData) + sizeof(int);
1346
1347 /* We need to store t_self, but not other fields of HeapTupleData */
1348 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1349 LogicalTapeWrite(tape, &tuple->t_self, sizeof(ItemPointerData));
1350 LogicalTapeWrite(tape, tuple->t_data, tuple->t_len);
1351 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1352 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1353}
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 1810 of file tuplesortvariants.c.

1811{
1814 void *waddr;
1815 unsigned int tuplen;
1816 unsigned int writtenlen;
1817
1818 if (stup->isnull1)
1819 {
1820 waddr = NULL;
1821 tuplen = 0;
1822 }
1823 else if (!base->tuples)
1824 {
1825 waddr = &stup->datum1;
1826 tuplen = sizeof(Datum);
1827 }
1828 else
1829 {
1830 waddr = stup->tuple;
1831 tuplen = datumGetSize(PointerGetDatum(stup->tuple), false, arg->datumTypeLen);
1832 Assert(tuplen != 0);
1833 }
1834
1835 writtenlen = tuplen + sizeof(unsigned int);
1836
1837 LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
1838 LogicalTapeWrite(tape, waddr, tuplen);
1839 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1840 LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
1841}
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 1144 of file tuplesortvariants.c.

1145{
1147 MinimalTuple tuple = (MinimalTuple) stup->tuple;
1148
1149 /* the part of the MinimalTuple we'll write: */
1150 char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1151 unsigned int tupbodylen = tuple->t_len - MINIMAL_TUPLE_DATA_OFFSET;
1152
1153 /* total on-disk footprint: */
1154 unsigned int tuplen = tupbodylen + sizeof(int);
1155
1156 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1157 LogicalTapeWrite(tape, tupbody, tupbodylen);
1158 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1159 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1160}

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

1660{
1662 IndexTuple tuple = (IndexTuple) stup->tuple;
1663 unsigned int tuplen;
1664
1665 tuplen = IndexTupleSize(tuple) + sizeof(tuplen);
1666 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1667 LogicalTapeWrite(tape, tuple, IndexTupleSize(tuple));
1668 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1669 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1670}
#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 1727 of file tuplesortvariants.c.

1728{
1730 BrinSortTuple *tuple = (BrinSortTuple *) stup->tuple;
1731 unsigned int tuplen = tuple->tuplen;
1732
1733 tuplen = tuplen + sizeof(tuplen);
1734 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1735 LogicalTapeWrite(tape, &tuple->tuple, tuple->tuplen);
1736 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1737 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1738}

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

Referenced by tuplesort_begin_index_brin().