PostgreSQL Source Code git master
tuplesortvariants.c File Reference
#include "postgres.h"
#include "access/brin_tuple.h"
#include "access/gin_tuple.h"
#include "access/hash.h"
#include "access/htup_details.h"
#include "access/nbtree.h"
#include "catalog/index.h"
#include "catalog/pg_collation.h"
#include "executor/executor.h"
#include "pg_trace.h"
#include "utils/datum.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/rel.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_index_gin (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 int comparetup_index_gin (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 void writetup_index_gin (Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
 
static void readtup_index_gin (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_index_gin (Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
 
Tuplesortstatetuplesort_begin_datum (Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, SortCoordinate coordinate, int sortopt)
 
void tuplesort_puttupleslot (Tuplesortstate *state, TupleTableSlot *slot)
 
void tuplesort_putheaptuple (Tuplesortstate *state, HeapTuple tup)
 
void tuplesort_putindextuplevalues (Tuplesortstate *state, Relation rel, const ItemPointerData *self, const Datum *values, const bool *isnull)
 
void tuplesort_putbrintuple (Tuplesortstate *state, BrinTuple *tuple, Size size)
 
void tuplesort_putgintuple (Tuplesortstate *state, GinTuple *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)
 
GinTupletuplesort_getgintuple (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 175 of file tuplesortvariants.c.

◆ CLUSTER_SORT

#define CLUSTER_SORT   3

Definition at line 42 of file tuplesortvariants.c.

◆ DATUM_SORT

#define DATUM_SORT   2

Definition at line 41 of file tuplesortvariants.c.

◆ HEAP_SORT

#define HEAP_SORT   0

Definition at line 39 of file tuplesortvariants.c.

◆ INDEX_SORT

#define INDEX_SORT   1

Definition at line 40 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 1346 of file tuplesortvariants.c.

1348{
1350 SortSupport sortKey = base->sortKeys;
1351 int32 compare;
1352
1353 /* Compare the leading sort key, if it's simple */
1354 if (base->haveDatum1)
1355 {
1356 compare = ApplySortComparator(a->datum1, a->isnull1,
1357 b->datum1, b->isnull1,
1358 sortKey);
1359 if (compare != 0)
1360 return compare;
1361 }
1362
1364}
int32_t int32
Definition: c.h:548
static int compare(const void *arg1, const void *arg2)
Definition: geqo_pool.c:145
int b
Definition: isn.c:74
int a
Definition: isn.c:73
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
Definition: sortsupport.h:200
SortSupport sortKeys
Definition: tuplesort.h:236
Definition: regguts.h:323
#define TuplesortstateGetPublic(state)
Definition: tuplesort.h:260
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 1367 of file tuplesortvariants.c.

1369{
1372 SortSupport sortKey = base->sortKeys;
1373 HeapTuple ltup;
1374 HeapTuple rtup;
1375 TupleDesc tupDesc;
1376 int nkey;
1377 int32 compare = 0;
1378 Datum datum1,
1379 datum2;
1380 bool isnull1,
1381 isnull2;
1382
1383 ltup = (HeapTuple) a->tuple;
1384 rtup = (HeapTuple) b->tuple;
1385 tupDesc = arg->tupDesc;
1386
1387 /* Compare the leading sort key, if it's simple */
1388 if (base->haveDatum1)
1389 {
1390 if (sortKey->abbrev_converter)
1391 {
1392 AttrNumber leading = arg->indexInfo->ii_IndexAttrNumbers[0];
1393
1394 datum1 = heap_getattr(ltup, leading, tupDesc, &isnull1);
1395 datum2 = heap_getattr(rtup, leading, tupDesc, &isnull2);
1396
1397 compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1398 datum2, isnull2,
1399 sortKey);
1400 }
1401 if (compare != 0 || base->nKeys == 1)
1402 return compare;
1403 /* Compare additional columns the hard way */
1404 sortKey++;
1405 nkey = 1;
1406 }
1407 else
1408 {
1409 /* Must compare all keys the hard way */
1410 nkey = 0;
1411 }
1412
1413 if (arg->indexInfo->ii_Expressions == NULL)
1414 {
1415 /* If not expression index, just compare the proper heap attrs */
1416
1417 for (; nkey < base->nKeys; nkey++, sortKey++)
1418 {
1419 AttrNumber attno = arg->indexInfo->ii_IndexAttrNumbers[nkey];
1420
1421 datum1 = heap_getattr(ltup, attno, tupDesc, &isnull1);
1422 datum2 = heap_getattr(rtup, attno, tupDesc, &isnull2);
1423
1424 compare = ApplySortComparator(datum1, isnull1,
1425 datum2, isnull2,
1426 sortKey);
1427 if (compare != 0)
1428 return compare;
1429 }
1430 }
1431 else
1432 {
1433 /*
1434 * In the expression index case, compute the whole index tuple and
1435 * then compare values. It would perhaps be faster to compute only as
1436 * many columns as we need to compare, but that would require
1437 * duplicating all the logic in FormIndexDatum.
1438 */
1439 Datum l_index_values[INDEX_MAX_KEYS];
1440 bool l_index_isnull[INDEX_MAX_KEYS];
1441 Datum r_index_values[INDEX_MAX_KEYS];
1442 bool r_index_isnull[INDEX_MAX_KEYS];
1443 TupleTableSlot *ecxt_scantuple;
1444
1445 /* Reset context each time to prevent memory leakage */
1447
1448 ecxt_scantuple = GetPerTupleExprContext(arg->estate)->ecxt_scantuple;
1449
1450 ExecStoreHeapTuple(ltup, ecxt_scantuple, false);
1451 FormIndexDatum(arg->indexInfo, ecxt_scantuple, arg->estate,
1452 l_index_values, l_index_isnull);
1453
1454 ExecStoreHeapTuple(rtup, ecxt_scantuple, false);
1455 FormIndexDatum(arg->indexInfo, ecxt_scantuple, arg->estate,
1456 r_index_values, r_index_isnull);
1457
1458 for (; nkey < base->nKeys; nkey++, sortKey++)
1459 {
1460 compare = ApplySortComparator(l_index_values[nkey],
1461 l_index_isnull[nkey],
1462 r_index_values[nkey],
1463 r_index_isnull[nkey],
1464 sortKey);
1465 if (compare != 0)
1466 return compare;
1467 }
1468 }
1469
1470 return 0;
1471}
int16 AttrNumber
Definition: attnum.h:21
TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1541
#define ResetPerTupleExprContext(estate)
Definition: executor.h:665
#define GetPerTupleExprContext(estate)
Definition: executor.h:656
HeapTupleData * HeapTuple
Definition: htup.h:71
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:904
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:2730
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
void * arg
#define INDEX_MAX_KEYS
uint64_t Datum
Definition: postgres.h:70
static int ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
Definition: sortsupport.h:339

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

1977{
1979 int compare;
1980
1981 compare = ApplySortComparator(a->datum1, a->isnull1,
1982 b->datum1, b->isnull1,
1983 base->sortKeys);
1984 if (compare != 0)
1985 return compare;
1986
1988}
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 1991 of file tuplesortvariants.c.

1992{
1994 int32 compare = 0;
1995
1996 /* if we have abbreviations, then "tuple" has the original value */
1997 if (base->sortKeys->abbrev_converter)
1999 PointerGetDatum(b->tuple), b->isnull1,
2000 base->sortKeys);
2001
2002 return compare;
2003}
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
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 1204 of file tuplesortvariants.c.

1205{
1207 SortSupport sortKey = base->sortKeys;
1208 int32 compare;
1209
1210
1211 /* Compare the leading sort key */
1212 compare = ApplySortComparator(a->datum1, a->isnull1,
1213 b->datum1, b->isnull1,
1214 sortKey);
1215 if (compare != 0)
1216 return compare;
1217
1218 /* Compare additional sort keys */
1220}
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 1223 of file tuplesortvariants.c.

1224{
1226 SortSupport sortKey = base->sortKeys;
1227 HeapTupleData ltup;
1228 HeapTupleData rtup;
1229 TupleDesc tupDesc;
1230 int nkey;
1231 int32 compare;
1232 AttrNumber attno;
1233 Datum datum1,
1234 datum2;
1235 bool isnull1,
1236 isnull2;
1237
1238 ltup.t_len = ((MinimalTuple) a->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
1239 ltup.t_data = (HeapTupleHeader) ((char *) a->tuple - MINIMAL_TUPLE_OFFSET);
1240 rtup.t_len = ((MinimalTuple) b->tuple)->t_len + MINIMAL_TUPLE_OFFSET;
1241 rtup.t_data = (HeapTupleHeader) ((char *) b->tuple - MINIMAL_TUPLE_OFFSET);
1242 tupDesc = (TupleDesc) base->arg;
1243
1244 if (sortKey->abbrev_converter)
1245 {
1246 attno = sortKey->ssup_attno;
1247
1248 datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
1249 datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
1250
1251 compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1252 datum2, isnull2,
1253 sortKey);
1254 if (compare != 0)
1255 return compare;
1256 }
1257
1258 sortKey++;
1259 for (nkey = 1; nkey < base->nKeys; nkey++, sortKey++)
1260 {
1261 attno = sortKey->ssup_attno;
1262
1263 datum1 = heap_getattr(&ltup, attno, tupDesc, &isnull1);
1264 datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
1265
1266 compare = ApplySortComparator(datum1, isnull1,
1267 datum2, isnull2,
1268 sortKey);
1269 if (compare != 0)
1270 return compare;
1271 }
1272
1273 return 0;
1274}
MinimalTupleData * MinimalTuple
Definition: htup.h:27
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:669
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:145

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

1846{
1847 Assert(TuplesortstateGetPublic(state)->haveDatum1);
1848
1849 if (DatumGetUInt32(a->datum1) > DatumGetUInt32(b->datum1))
1850 return 1;
1851
1852 if (DatumGetUInt32(a->datum1) < DatumGetUInt32(b->datum1))
1853 return -1;
1854
1855 /* silence compilers */
1856 return 0;
1857}
Assert(PointerIsAligned(start, uint64))
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:232

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

1563{
1564 /*
1565 * This is similar to comparetup_heap(), but expects index tuples. There
1566 * is also special handling for enforcing uniqueness, and special
1567 * treatment for equal keys at the end.
1568 */
1570 SortSupport sortKey = base->sortKeys;
1571 int32 compare;
1572
1573 /* Compare the leading sort key */
1574 compare = ApplySortComparator(a->datum1, a->isnull1,
1575 b->datum1, b->isnull1,
1576 sortKey);
1577 if (compare != 0)
1578 return compare;
1579
1580 /* Compare additional sort keys */
1582}
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 1585 of file tuplesortvariants.c.

1587{
1590 SortSupport sortKey = base->sortKeys;
1591 IndexTuple tuple1;
1592 IndexTuple tuple2;
1593 int keysz;
1594 TupleDesc tupDes;
1595 bool equal_hasnull = false;
1596 int nkey;
1597 int32 compare;
1598 Datum datum1,
1599 datum2;
1600 bool isnull1,
1601 isnull2;
1602
1603 tuple1 = (IndexTuple) a->tuple;
1604 tuple2 = (IndexTuple) b->tuple;
1605 keysz = base->nKeys;
1606 tupDes = RelationGetDescr(arg->index.indexRel);
1607
1608 if (sortKey->abbrev_converter)
1609 {
1610 datum1 = index_getattr(tuple1, 1, tupDes, &isnull1);
1611 datum2 = index_getattr(tuple2, 1, tupDes, &isnull2);
1612
1613 compare = ApplySortAbbrevFullComparator(datum1, isnull1,
1614 datum2, isnull2,
1615 sortKey);
1616 if (compare != 0)
1617 return compare;
1618 }
1619
1620 /* they are equal, so we only need to examine one null flag */
1621 if (a->isnull1)
1622 equal_hasnull = true;
1623
1624 sortKey++;
1625 for (nkey = 2; nkey <= keysz; nkey++, sortKey++)
1626 {
1627 datum1 = index_getattr(tuple1, nkey, tupDes, &isnull1);
1628 datum2 = index_getattr(tuple2, nkey, tupDes, &isnull2);
1629
1630 compare = ApplySortComparator(datum1, isnull1,
1631 datum2, isnull2,
1632 sortKey);
1633 if (compare != 0)
1634 return compare; /* done when we find unequal attributes */
1635
1636 /* they are equal, so we only need to examine one null flag */
1637 if (isnull1)
1638 equal_hasnull = true;
1639 }
1640
1641 /*
1642 * If btree has asked us to enforce uniqueness, complain if two equal
1643 * tuples are detected (unless there was at least one NULL field and NULLS
1644 * NOT DISTINCT was not set).
1645 *
1646 * It is sufficient to make the test here, because if two tuples are equal
1647 * they *must* get compared at some stage of the sort --- otherwise the
1648 * sort algorithm wouldn't have checked whether one must appear before the
1649 * other.
1650 */
1651 if (arg->enforceUnique && !(!arg->uniqueNullsNotDistinct && equal_hasnull))
1652 {
1654 bool isnull[INDEX_MAX_KEYS];
1655 char *key_desc;
1656
1657 /*
1658 * Some rather brain-dead implementations of qsort (such as the one in
1659 * QNX 4) will sometimes call the comparison routine to compare a
1660 * value to itself, but we always use our own implementation, which
1661 * does not.
1662 */
1663 Assert(tuple1 != tuple2);
1664
1665 index_deform_tuple(tuple1, tupDes, values, isnull);
1666
1667 key_desc = BuildIndexValueDescription(arg->index.indexRel, values, isnull);
1668
1669 ereport(ERROR,
1670 (errcode(ERRCODE_UNIQUE_VIOLATION),
1671 errmsg("could not create unique index \"%s\"",
1672 RelationGetRelationName(arg->index.indexRel)),
1673 key_desc ? errdetail("Key %s is duplicated.", key_desc) :
1674 errdetail("Duplicate keys exist."),
1675 errtableconstraint(arg->index.heapRel,
1676 RelationGetRelationName(arg->index.indexRel))));
1677 }
1678
1679 /*
1680 * If key values are equal, we sort on ItemPointer. This is required for
1681 * btree indexes, since heap TID is treated as an implicit last key
1682 * attribute in order to ensure that all keys in the index are physically
1683 * unique.
1684 */
1685 {
1686 BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid);
1687 BlockNumber blk2 = ItemPointerGetBlockNumber(&tuple2->t_tid);
1688
1689 if (blk1 != blk2)
1690 return (blk1 < blk2) ? -1 : 1;
1691 }
1692 {
1693 OffsetNumber pos1 = ItemPointerGetOffsetNumber(&tuple1->t_tid);
1694 OffsetNumber pos2 = ItemPointerGetOffsetNumber(&tuple2->t_tid);
1695
1696 if (pos1 != pos2)
1697 return (pos1 < pos2) ? -1 : 1;
1698 }
1699
1700 /* ItemPointer values should never be equal */
1701 Assert(false);
1702
1703 return 0;
1704}
uint32 BlockNumber
Definition: block.h:31
static Datum values[MAXATTR]
Definition: bootstrap.c:153
int errdetail(const char *fmt,...)
Definition: elog.c:1216
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
char * BuildIndexValueDescription(Relation indexRelation, const Datum *values, const bool *isnull)
Definition: genam.c:178
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:131
uint16 OffsetNumber
Definition: off.h:24
#define RelationGetDescr(relation)
Definition: rel.h:541
#define RelationGetRelationName(relation)
Definition: rel.h:549
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:6103

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

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

Definition at line 1911 of file tuplesortvariants.c.

1913{
1915
1916 Assert(!TuplesortstateGetPublic(state)->haveDatum1);
1917
1918 return _gin_compare_tuples((GinTuple *) a->tuple,
1919 (GinTuple *) b->tuple,
1920 base->sortKeys);
1921}
int _gin_compare_tuples(GinTuple *a, GinTuple *b, SortSupport ssup)
Definition: gininsert.c:2433

References _gin_compare_tuples(), a, Assert(), b, TuplesortPublic::sortKeys, and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_gin().

◆ comparetup_index_hash()

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

Definition at line 1707 of file tuplesortvariants.c.

1709{
1710 Bucket bucket1;
1711 Bucket bucket2;
1712 uint32 hash1;
1713 uint32 hash2;
1714 IndexTuple tuple1;
1715 IndexTuple tuple2;
1718
1719 /*
1720 * Fetch hash keys and mask off bits we don't want to sort by, so that the
1721 * initial sort is just on the bucket number. We know that the first
1722 * column of the index tuple is the hash key.
1723 */
1724 Assert(!a->isnull1);
1725 bucket1 = _hash_hashkey2bucket(DatumGetUInt32(a->datum1),
1726 arg->max_buckets, arg->high_mask,
1727 arg->low_mask);
1728 Assert(!b->isnull1);
1729 bucket2 = _hash_hashkey2bucket(DatumGetUInt32(b->datum1),
1730 arg->max_buckets, arg->high_mask,
1731 arg->low_mask);
1732 if (bucket1 > bucket2)
1733 return 1;
1734 else if (bucket1 < bucket2)
1735 return -1;
1736
1737 /*
1738 * If bucket values are equal, sort by hash values. This allows us to
1739 * insert directly onto bucket/overflow pages, where the index tuples are
1740 * stored in hash order to allow fast binary search within each page.
1741 */
1742 hash1 = DatumGetUInt32(a->datum1);
1743 hash2 = DatumGetUInt32(b->datum1);
1744 if (hash1 > hash2)
1745 return 1;
1746 else if (hash1 < hash2)
1747 return -1;
1748
1749 /*
1750 * If hash values are equal, we sort on ItemPointer. This does not affect
1751 * validity of the finished index, but it may be useful to have index
1752 * scans in physical order.
1753 */
1754 tuple1 = (IndexTuple) a->tuple;
1755 tuple2 = (IndexTuple) b->tuple;
1756
1757 {
1760
1761 if (blk1 != blk2)
1762 return (blk1 < blk2) ? -1 : 1;
1763 }
1764 {
1767
1768 if (pos1 != pos2)
1769 return (pos1 < pos2) ? -1 : 1;
1770 }
1771
1772 /* ItemPointer values should never be equal */
1773 Assert(false);
1774
1775 return 0;
1776}
uint32_t uint32
Definition: c.h:552
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 1783 of file tuplesortvariants.c.

1785{
1786 Assert(false);
1787
1788 return 0;
1789}

References Assert().

Referenced by tuplesort_begin_index_hash().

◆ freestate_cluster()

static void freestate_cluster ( Tuplesortstate state)
static

Definition at line 1518 of file tuplesortvariants.c.

1519{
1522
1523 /* Free any execution state created for CLUSTER case */
1524 if (arg->estate != NULL)
1525 {
1526 ExprContext *econtext = GetPerTupleExprContext(arg->estate);
1527
1529 FreeExecutorState(arg->estate);
1530 }
1531}
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1443
void FreeExecutorState(EState *estate)
Definition: execUtils.c:192
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:273

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

1491{
1494 unsigned int t_len = tuplen - sizeof(ItemPointerData) - sizeof(int);
1496 t_len + HEAPTUPLESIZE);
1497
1498 /* Reconstruct the HeapTupleData header */
1499 tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
1500 tuple->t_len = t_len;
1501 LogicalTapeReadExact(tape, &tuple->t_self, sizeof(ItemPointerData));
1502 /* We don't currently bother to reconstruct t_tableOid */
1503 tuple->t_tableOid = InvalidOid;
1504 /* Read in the tuple body */
1505 LogicalTapeReadExact(tape, tuple->t_data, tuple->t_len);
1506 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1507 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1508 stup->tuple = tuple;
1509 /* set up first-column key value, if it's a simple column */
1510 if (base->haveDatum1)
1511 stup->datum1 = heap_getattr(tuple,
1512 arg->indexInfo->ii_IndexAttrNumbers[0],
1513 arg->tupDesc,
1514 &stup->isnull1);
1515}
#define HEAPTUPLESIZE
Definition: htup.h:73
#define InvalidOid
Definition: postgres_ext.h:37
ItemPointerData t_self
Definition: htup.h:65
Oid t_tableOid
Definition: htup.h:66
bool isnull1
Definition: tuplesort.h:152
void * tuple
Definition: tuplesort.h:150
Datum datum1
Definition: tuplesort.h:151
void * tuplesort_readtup_alloc(Tuplesortstate *state, Size tuplen)
Definition: tuplesort.c:2867
#define TUPLESORT_RANDOMACCESS
Definition: tuplesort.h:97
#define LogicalTapeReadExact(tape, ptr, len)
Definition: tuplesort.h:263

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

2042{
2044 unsigned int tuplen = len - sizeof(unsigned int);
2045
2046 if (tuplen == 0)
2047 {
2048 /* it's NULL */
2049 stup->datum1 = (Datum) 0;
2050 stup->isnull1 = true;
2051 stup->tuple = NULL;
2052 }
2053 else if (!base->tuples)
2054 {
2055 Assert(tuplen == sizeof(Datum));
2056 LogicalTapeReadExact(tape, &stup->datum1, tuplen);
2057 stup->isnull1 = false;
2058 stup->tuple = NULL;
2059 }
2060 else
2061 {
2062 void *raddr = tuplesort_readtup_alloc(state, tuplen);
2063
2064 LogicalTapeReadExact(tape, raddr, tuplen);
2065 stup->datum1 = PointerGetDatum(raddr);
2066 stup->isnull1 = false;
2067 stup->tuple = raddr;
2068 }
2069
2070 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
2071 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
2072}
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 1296 of file tuplesortvariants.c.

1298{
1299 unsigned int tupbodylen = len - sizeof(int);
1300 unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
1302 char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1304 HeapTupleData htup;
1305
1306 /* read in the tuple proper */
1307 tuple->t_len = tuplen;
1308 LogicalTapeReadExact(tape, tupbody, tupbodylen);
1309 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1310 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1311 stup->tuple = tuple;
1312 /* set up first-column key value */
1313 htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
1314 htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
1315 stup->datum1 = heap_getattr(&htup,
1316 base->sortKeys[0].ssup_attno,
1317 (TupleDesc) base->arg,
1318 &stup->isnull1);
1319}
#define MINIMAL_TUPLE_DATA_OFFSET
Definition: htup_details.h:673

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

1808{
1811 unsigned int tuplen = len - sizeof(unsigned int);
1813
1814 LogicalTapeReadExact(tape, tuple, tuplen);
1815 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1816 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1817 stup->tuple = tuple;
1818 /* set up first-column key value */
1819 stup->datum1 = index_getattr(tuple,
1820 1,
1821 RelationGetDescr(arg->indexRel),
1822 &stup->isnull1);
1823}

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

1876{
1877 BrinSortTuple *tuple;
1879 unsigned int tuplen = len - sizeof(unsigned int);
1880
1881 /*
1882 * Allocate space for the BRIN sort tuple, which is BrinTuple with an
1883 * extra length field.
1884 */
1886 BRINSORTTUPLE_SIZE(tuplen));
1887
1888 tuple->tuplen = tuplen;
1889
1890 LogicalTapeReadExact(tape, &tuple->tuple, tuplen);
1891 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1892 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1893 stup->tuple = tuple;
1894
1895 /* set up first-column key value, which is block number */
1896 stup->datum1 = UInt32GetDatum(tuple->tuple.bt_blkno);
1897}
static Datum UInt32GetDatum(uint32 X)
Definition: postgres.h:242
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(), TuplesortstateGetPublic, and UInt32GetDatum().

Referenced by tuplesort_begin_index_brin().

◆ readtup_index_gin()

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

Definition at line 1938 of file tuplesortvariants.c.

1940{
1941 GinTuple *tuple;
1943 unsigned int tuplen = len - sizeof(unsigned int);
1944
1945 /*
1946 * Allocate space for the GIN sort tuple, which already has the proper
1947 * length included in the header.
1948 */
1949 tuple = (GinTuple *) tuplesort_readtup_alloc(state, tuplen);
1950
1951 tuple->tuplen = tuplen;
1952
1953 LogicalTapeReadExact(tape, tuple, tuplen);
1954 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1955 LogicalTapeReadExact(tape, &tuplen, sizeof(tuplen));
1956 stup->tuple = tuple;
1957
1958 /* no abbreviations (FIXME maybe use attrnum for this?) */
1959 stup->datum1 = (Datum) 0;
1960}
int tuplen
Definition: gin_tuple.h:24

References SortTuple::datum1, len, LogicalTapeReadExact, TuplesortPublic::sortopt, SortTuple::tuple, GinTuple::tuplen, TUPLESORT_RANDOMACCESS, tuplesort_readtup_alloc(), and TuplesortstateGetPublic.

Referenced by tuplesort_begin_index_gin().

◆ removeabbrev_cluster()

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

Definition at line 1327 of file tuplesortvariants.c.

1328{
1329 int i;
1332
1333 for (i = 0; i < count; i++)
1334 {
1335 HeapTuple tup;
1336
1337 tup = (HeapTuple) stups[i].tuple;
1338 stups[i].datum1 = heap_getattr(tup,
1339 arg->indexInfo->ii_IndexAttrNumbers[0],
1340 arg->tupDesc,
1341 &stups[i].isnull1);
1342 }
1343}
for(;;)
int i
Definition: isn.c:77

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

1968{
1969 int i;
1970
1971 for (i = 0; i < count; i++)
1972 stups[i].datum1 = PointerGetDatum(stups[i].tuple);
1973}

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

1184{
1185 int i;
1187
1188 for (i = 0; i < count; i++)
1189 {
1190 HeapTupleData htup;
1191
1192 htup.t_len = ((MinimalTuple) stups[i].tuple)->t_len +
1194 htup.t_data = (HeapTupleHeader) ((char *) stups[i].tuple -
1196 stups[i].datum1 = heap_getattr(&htup,
1197 base->sortKeys[0].ssup_attno,
1198 (TupleDesc) base->arg,
1199 &stups[i].isnull1);
1200 }
1201}

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

1543{
1546 int i;
1547
1548 for (i = 0; i < count; i++)
1549 {
1550 IndexTuple tuple;
1551
1552 tuple = stups[i].tuple;
1553 stups[i].datum1 = index_getattr(tuple,
1554 1,
1555 RelationGetDescr(arg->indexRel),
1556 &stups[i].isnull1);
1557 }
1558}

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

1831{
1832 int i;
1833
1834 for (i = 0; i < count; i++)
1835 {
1836 BrinSortTuple *tuple;
1837
1838 tuple = stups[i].tuple;
1839 stups[i].datum1 = UInt32GetDatum(tuple->tuple.bt_blkno);
1840 }
1841}

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

Referenced by tuplesort_begin_index_brin().

◆ removeabbrev_index_gin()

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

Definition at line 1904 of file tuplesortvariants.c.

1905{
1906 Assert(false);
1907 elog(ERROR, "removeabbrev_index_gin not implemented");
1908}
#define elog(elevel,...)
Definition: elog.h:226

References Assert(), elog, and ERROR.

Referenced by tuplesort_begin_index_gin().

◆ tuplesort_begin_cluster()

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

Definition at line 252 of file tuplesortvariants.c.

256{
257 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
258 sortopt);
260 BTScanInsert indexScanKey;
261 MemoryContext oldcontext;
263 int i;
264
265 Assert(indexRel->rd_rel->relam == BTREE_AM_OID);
266
267 oldcontext = MemoryContextSwitchTo(base->maincontext);
269
270 if (trace_sort)
271 elog(LOG,
272 "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
274 workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
275
277
278 TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
279 false, /* no unique check */
280 base->nKeys,
281 workMem,
282 sortopt & TUPLESORT_RANDOMACCESS,
283 PARALLEL_SORT(coordinate));
284
289 base->readtup = readtup_cluster;
291 base->arg = arg;
292
293 arg->indexInfo = BuildIndexInfo(indexRel);
294
295 /*
296 * If we don't have a simple leading attribute, we don't currently
297 * initialize datum1, so disable optimizations that require it.
298 */
299 if (arg->indexInfo->ii_IndexAttrNumbers[0] == 0)
300 base->haveDatum1 = false;
301 else
302 base->haveDatum1 = true;
303
304 arg->tupDesc = tupDesc; /* assume we need not copy tupDesc */
305
306 indexScanKey = _bt_mkscankey(indexRel, NULL);
307
308 if (arg->indexInfo->ii_Expressions != NULL)
309 {
310 TupleTableSlot *slot;
311 ExprContext *econtext;
312
313 /*
314 * We will need to use FormIndexDatum to evaluate the index
315 * expressions. To do that, we need an EState, as well as a
316 * TupleTableSlot to put the table tuples into. The econtext's
317 * scantuple has to point to that slot, too.
318 */
319 arg->estate = CreateExecutorState();
321 econtext = GetPerTupleExprContext(arg->estate);
322 econtext->ecxt_scantuple = slot;
323 }
324
325 /* Prepare SortSupport data for each column */
326 base->sortKeys = (SortSupport) palloc0(base->nKeys *
327 sizeof(SortSupportData));
328
329 for (i = 0; i < base->nKeys; i++)
330 {
331 SortSupport sortKey = base->sortKeys + i;
332 ScanKey scanKey = indexScanKey->scankeys + i;
333 bool reverse;
334
336 sortKey->ssup_collation = scanKey->sk_collation;
337 sortKey->ssup_nulls_first =
338 (scanKey->sk_flags & SK_BT_NULLS_FIRST) != 0;
339 sortKey->ssup_attno = scanKey->sk_attno;
340 /* Convey if abbreviation optimization is applicable in principle */
341 sortKey->abbreviate = (i == 0 && base->haveDatum1);
342
343 Assert(sortKey->ssup_attno != 0);
344
345 reverse = (scanKey->sk_flags & SK_BT_DESC) != 0;
346
347 PrepareSortSupportFromIndexRel(indexRel, reverse, sortKey);
348 }
349
350 pfree(indexScanKey);
351
352 MemoryContextSwitchTo(oldcontext);
353
354 return state;
355}
#define LOG
Definition: elog.h:31
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1427
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:85
EState * CreateExecutorState(void)
Definition: execUtils.c:88
#define palloc0_object(type)
Definition: fe_memutils.h:75
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:2428
void pfree(void *pointer)
Definition: mcxt.c:1594
void * palloc0(Size size)
Definition: mcxt.c:1395
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
#define SK_BT_NULLS_FIRST
Definition: nbtree.h:1117
#define SK_BT_DESC
Definition: nbtree.h:1116
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
Definition: nbtutils.c:59
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:521
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:534
void PrepareSortSupportFromIndexRel(Relation indexRel, bool reverse, SortSupport ssup)
Definition: sortsupport.c:161
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
ScanKeyData scankeys[INDEX_MAX_KEYS]
Definition: nbtree.h:804
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:219
void(* writetup)(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
Definition: tuplesort.h:195
void(* removeabbrev)(Tuplesortstate *state, SortTuple *stups, int count)
Definition: tuplesort.h:188
void(* freestate)(Tuplesortstate *state)
Definition: tuplesort.h:213
void(* readtup)(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Definition: tuplesort.h:204
SortTupleComparator comparetup
Definition: tuplesort.h:175
SortTupleComparator comparetup_tiebreak
Definition: tuplesort.h:182
Tuplesortstate * tuplesort_begin_common(int workMem, SortCoordinate coordinate, int sortopt)
Definition: tuplesort.c:636
bool trace_sort
Definition: tuplesort.c:122
#define PARALLEL_SORT(coordinate)
Definition: tuplesort.h:256
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(), 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(), palloc0_object, 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 652 of file tuplesortvariants.c.

655{
656 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
657 sortopt);
660 MemoryContext oldcontext;
661 int16 typlen;
662 bool typbyval;
663
664 oldcontext = MemoryContextSwitchTo(base->maincontext);
666
667 if (trace_sort)
668 elog(LOG,
669 "begin datum sort: workMem = %d, randomAccess = %c",
670 workMem, sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
671
672 base->nKeys = 1; /* always a one-column sort */
673
674 TRACE_POSTGRESQL_SORT_START(DATUM_SORT,
675 false, /* no unique check */
676 1,
677 workMem,
678 sortopt & TUPLESORT_RANDOMACCESS,
679 PARALLEL_SORT(coordinate));
680
684 base->writetup = writetup_datum;
685 base->readtup = readtup_datum;
686 base->haveDatum1 = true;
687 base->arg = arg;
688
689 arg->datumType = datumType;
690
691 /* lookup necessary attributes of the datum type */
692 get_typlenbyval(datumType, &typlen, &typbyval);
693 arg->datumTypeLen = typlen;
694 base->tuples = !typbyval;
695
696 /* Prepare SortSupport data */
698
700 base->sortKeys->ssup_collation = sortCollation;
701 base->sortKeys->ssup_nulls_first = nullsFirstFlag;
702
703 /*
704 * Abbreviation is possible here only for by-reference types. In theory,
705 * a pass-by-value datatype could have an abbreviated form that is cheaper
706 * to compare. In a tuple sort, we could support that, because we can
707 * always extract the original datum from the tuple as needed. Here, we
708 * can't, because a datum sort only stores a single copy of the datum; the
709 * "tuple" field of each SortTuple is NULL.
710 */
711 base->sortKeys->abbreviate = !typbyval;
712
713 PrepareSortSupportFromOrderingOp(sortOperator, base->sortKeys);
714
715 /*
716 * The "onlyKey" optimization cannot be used with abbreviated keys, since
717 * tie-breaker comparisons may be required. Typically, the optimization
718 * is only of value to pass-by-value types anyway, whereas abbreviated
719 * keys are typically only of value to pass-by-reference types.
720 */
721 if (!base->sortKeys->abbrev_converter)
722 base->onlyKey = base->sortKeys;
723
724 MemoryContextSwitchTo(oldcontext);
725
726 return state;
727}
int16_t int16
Definition: c.h:547
#define palloc_object(type)
Definition: fe_memutils.h:74
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2416
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
Definition: sortsupport.c:134
SortSupport onlyKey
Definition: tuplesort.h:246
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, palloc0_object, palloc_object, 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 array_sort_internal(), 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 179 of file tuplesortvariants.c.

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

557{
558 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
559 sortopt);
561
562 if (trace_sort)
563 elog(LOG,
564 "begin index sort: workMem = %d, randomAccess = %c",
565 workMem,
566 sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
567
568 base->nKeys = 1; /* Only one sort column, the block number */
569
574 base->haveDatum1 = true;
575 base->arg = NULL;
576
577 return state;
578}
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 358 of file tuplesortvariants.c.

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

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

Definition at line 581 of file tuplesortvariants.c.

585{
586 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
587 sortopt);
589 MemoryContext oldcontext;
590 int i;
591 TupleDesc desc = RelationGetDescr(indexRel);
592
593 oldcontext = MemoryContextSwitchTo(base->maincontext);
594
595#ifdef TRACE_SORT
596 if (trace_sort)
597 elog(LOG,
598 "begin index sort: workMem = %d, randomAccess = %c",
599 workMem,
600 sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
601#endif
602
603 /*
604 * Multi-column GIN indexes expand the row into a separate index entry for
605 * attribute, and that's what we write into the tuplesort. But we still
606 * need to initialize sortsupport for all the attributes.
607 */
609
610 /* Prepare SortSupport data for each column */
611 base->sortKeys = (SortSupport) palloc0(base->nKeys *
612 sizeof(SortSupportData));
613
614 for (i = 0; i < base->nKeys; i++)
615 {
616 SortSupport sortKey = base->sortKeys + i;
617 Form_pg_attribute att = TupleDescAttr(desc, i);
618 TypeCacheEntry *typentry;
619
621 sortKey->ssup_collation = indexRel->rd_indcollation[i];
622 sortKey->ssup_nulls_first = false;
623 sortKey->ssup_attno = i + 1;
624 sortKey->abbreviate = false;
625
626 Assert(sortKey->ssup_attno != 0);
627
628 if (!OidIsValid(sortKey->ssup_collation))
629 sortKey->ssup_collation = DEFAULT_COLLATION_OID;
630
631 /*
632 * Look for a ordering for the index key data type, and then the sort
633 * support function.
634 */
635 typentry = lookup_type_cache(att->atttypid, TYPECACHE_LT_OPR);
636 PrepareSortSupportFromOrderingOp(typentry->lt_opr, sortKey);
637 }
638
643 base->haveDatum1 = false;
644 base->arg = NULL;
645
646 MemoryContextSwitchTo(oldcontext);
647
648 return state;
649}
#define OidIsValid(objectId)
Definition: c.h:788
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
Oid * rd_indcollation
Definition: rel.h:217
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
static void writetup_index_gin(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
static void readtup_index_gin(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static void removeabbrev_index_gin(Tuplesortstate *state, SortTuple *stups, int count)
static int comparetup_index_gin(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:386
#define TYPECACHE_LT_OPR
Definition: typcache.h:139

References SortSupportData::abbreviate, TuplesortPublic::arg, Assert(), TuplesortPublic::comparetup, comparetup_index_gin(), CurrentMemoryContext, elog, TuplesortPublic::haveDatum1, i, IndexRelationGetNumberOfKeyAttributes, LOG, lookup_type_cache(), TypeCacheEntry::lt_opr, TuplesortPublic::maincontext, MemoryContextSwitchTo(), TuplesortPublic::nKeys, OidIsValid, palloc0(), PrepareSortSupportFromOrderingOp(), RelationData::rd_indcollation, TuplesortPublic::readtup, readtup_index_gin(), RelationGetDescr, TuplesortPublic::removeabbrev, removeabbrev_index_gin(), TuplesortPublic::sortKeys, SortSupportData::ssup_attno, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, SortSupportData::ssup_nulls_first, trace_sort, TupleDescAttr(), tuplesort_begin_common(), TUPLESORT_RANDOMACCESS, TuplesortstateGetPublic, TYPECACHE_LT_OPR, TuplesortPublic::writetup, and writetup_index_gin().

Referenced by _gin_parallel_scan_and_build(), and ginbuild().

◆ tuplesort_begin_index_gist()

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

Definition at line 491 of file tuplesortvariants.c.

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

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, palloc0(), palloc_object, 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 440 of file tuplesortvariants.c.

448{
449 Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate,
450 sortopt);
452 MemoryContext oldcontext;
454
455 oldcontext = MemoryContextSwitchTo(base->maincontext);
457
458 if (trace_sort)
459 elog(LOG,
460 "begin index sort: high_mask = 0x%x, low_mask = 0x%x, "
461 "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
462 high_mask,
463 low_mask,
464 max_buckets,
465 workMem,
466 sortopt & TUPLESORT_RANDOMACCESS ? 't' : 'f');
467
468 base->nKeys = 1; /* Only one sort column, the hash code */
469
473 base->writetup = writetup_index;
474 base->readtup = readtup_index;
475 base->haveDatum1 = true;
476 base->arg = arg;
477
478 arg->index.heapRel = heapRel;
479 arg->index.indexRel = indexRel;
480
481 arg->high_mask = high_mask;
482 arg->low_mask = low_mask;
483 arg->max_buckets = max_buckets;
484
485 MemoryContextSwitchTo(oldcontext);
486
487 return state;
488}
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_object, 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 1067 of file tuplesortvariants.c.

1068{
1071 SortTuple stup;
1072 BrinSortTuple *btup;
1073
1074 if (!tuplesort_gettuple_common(state, forward, &stup))
1075 stup.tuple = NULL;
1076
1077 MemoryContextSwitchTo(oldcontext);
1078
1079 if (!stup.tuple)
1080 return NULL;
1081
1082 btup = (BrinSortTuple *) stup.tuple;
1083
1084 *len = btup->tuplen;
1085
1086 return &btup->tuple;
1087}
MemoryContext sortcontext
Definition: tuplesort.h:221
bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
Definition: tuplesort.c:1456

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

1139{
1143 SortTuple stup;
1144
1145 if (!tuplesort_gettuple_common(state, forward, &stup))
1146 {
1147 MemoryContextSwitchTo(oldcontext);
1148 return false;
1149 }
1150
1151 /* Ensure we copy into caller's memory context */
1152 MemoryContextSwitchTo(oldcontext);
1153
1154 /* Record abbreviated key for caller */
1155 if (base->sortKeys->abbrev_converter && abbrev)
1156 *abbrev = stup.datum1;
1157
1158 if (stup.isnull1 || !base->tuples)
1159 {
1160 *val = stup.datum1;
1161 *isNull = stup.isnull1;
1162 }
1163 else
1164 {
1165 /* use stup.tuple because stup.datum1 may be an abbreviation */
1166 if (copy)
1167 *val = datumCopy(PointerGetDatum(stup.tuple), false,
1168 arg->datumTypeLen);
1169 else
1170 *val = PointerGetDatum(stup.tuple);
1171 *isNull = false;
1172 }
1173
1174 return true;
1175}
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 array_sort_internal(), 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_getgintuple()

GinTuple * tuplesort_getgintuple ( Tuplesortstate state,
Size len,
bool  forward 
)

Definition at line 1090 of file tuplesortvariants.c.

1091{
1094 SortTuple stup;
1095 GinTuple *tup;
1096
1097 if (!tuplesort_gettuple_common(state, forward, &stup))
1098 stup.tuple = NULL;
1099
1100 MemoryContextSwitchTo(oldcontext);
1101
1102 if (!stup.tuple)
1103 return NULL;
1104
1105 tup = (GinTuple *) stup.tuple;
1106
1107 *len = tup->tuplen;
1108
1109 return tup;
1110}

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

Referenced by _gin_parallel_merge(), and _gin_process_worker_data().

◆ tuplesort_getheaptuple()

HeapTuple tuplesort_getheaptuple ( Tuplesortstate state,
bool  forward 
)

Definition at line 1025 of file tuplesortvariants.c.

1026{
1029 SortTuple stup;
1030
1031 if (!tuplesort_gettuple_common(state, forward, &stup))
1032 stup.tuple = NULL;
1033
1034 MemoryContextSwitchTo(oldcontext);
1035
1036 return stup.tuple;
1037}

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

1047{
1050 SortTuple stup;
1051
1052 if (!tuplesort_gettuple_common(state, forward, &stup))
1053 stup.tuple = NULL;
1054
1055 MemoryContextSwitchTo(oldcontext);
1056
1057 return (IndexTuple) stup.tuple;
1058}

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

989{
992 SortTuple stup;
993
994 if (!tuplesort_gettuple_common(state, forward, &stup))
995 stup.tuple = NULL;
996
997 MemoryContextSwitchTo(oldcontext);
998
999 if (stup.tuple)
1000 {
1001 /* Record abbreviated key for caller */
1002 if (base->sortKeys->abbrev_converter && abbrev)
1003 *abbrev = stup.datum1;
1004
1005 if (copy)
1007
1008 ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, copy);
1009 return true;
1010 }
1011 else
1012 {
1013 ExecClearTuple(slot);
1014 return false;
1015 }
1016}
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:1635
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup, Size extra)
Definition: heaptuple.c:1541
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:457

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

855{
856 SortTuple stup;
857 BrinSortTuple *bstup;
860 Size tuplen;
861
862 /* allocate space for the whole BRIN sort tuple */
863 bstup = palloc(BRINSORTTUPLE_SIZE(size));
864
865 bstup->tuplen = size;
866 memcpy(&bstup->tuple, tuple, size);
867
868 stup.tuple = bstup;
869 stup.datum1 = UInt32GetDatum(tuple->bt_blkno);
870 stup.isnull1 = false;
871
872 /* GetMemoryChunkSpace is not supported for bump contexts */
874 tuplen = MAXALIGN(BRINSORTTUPLE_SIZE(size));
875 else
876 tuplen = GetMemoryChunkSpace(bstup);
877
879 base->sortKeys &&
880 base->sortKeys->abbrev_converter &&
881 !stup.isnull1, tuplen);
882
883 MemoryContextSwitchTo(oldcontext);
884}
#define MAXALIGN(LEN)
Definition: c.h:824
size_t Size
Definition: c.h:624
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:767
void * palloc(Size size)
Definition: mcxt.c:1365
MemoryContext tuplecontext
Definition: tuplesort.h:222
void tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev, Size tuplen)
Definition: tuplesort.c:1155
#define TupleSortUseBumpTupleCxt(opt)
Definition: tuplesort.h:109

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

Referenced by form_and_spill_tuple().

◆ tuplesort_putdatum()

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

Definition at line 923 of file tuplesortvariants.c.

924{
928 SortTuple stup;
929
930 /*
931 * Pass-by-value types or null values are just stored directly in
932 * stup.datum1 (and stup.tuple is not used and set to NULL).
933 *
934 * Non-null pass-by-reference values need to be copied into memory we
935 * control, and possibly abbreviated. The copied value is pointed to by
936 * stup.tuple and is treated as the canonical copy (e.g. to return via
937 * tuplesort_getdatum or when writing to tape); stup.datum1 gets the
938 * abbreviated value if abbreviation is happening, otherwise it's
939 * identical to stup.tuple.
940 */
941
942 if (isNull || !base->tuples)
943 {
944 /*
945 * Set datum1 to zeroed representation for NULLs (to be consistent,
946 * and to support cheap inequality tests for NULL abbreviated keys).
947 */
948 stup.datum1 = !isNull ? val : (Datum) 0;
949 stup.isnull1 = isNull;
950 stup.tuple = NULL; /* no separate storage */
951 }
952 else
953 {
954 stup.isnull1 = false;
955 stup.datum1 = datumCopy(val, false, arg->datumTypeLen);
956 stup.tuple = DatumGetPointer(stup.datum1);
957 }
958
960 base->tuples &&
961 base->sortKeys->abbrev_converter && !isNull, 0);
962
963 MemoryContextSwitchTo(oldcontext);
964}
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322

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 array_sort_internal(), ExecEvalAggOrderedTransDatum(), ExecSort(), ordered_set_transition(), and validate_index_callback().

◆ tuplesort_putgintuple()

void tuplesort_putgintuple ( Tuplesortstate state,
GinTuple tuple,
Size  size 
)

Definition at line 887 of file tuplesortvariants.c.

888{
889 SortTuple stup;
890 GinTuple *ctup;
893 Size tuplen;
894
895 /* copy the GinTuple into the right memory context */
896 ctup = palloc(size);
897 memcpy(ctup, tuple, size);
898
899 stup.tuple = ctup;
900 stup.datum1 = (Datum) 0;
901 stup.isnull1 = false;
902
903 /* GetMemoryChunkSpace is not supported for bump contexts */
905 tuplen = MAXALIGN(size);
906 else
907 tuplen = GetMemoryChunkSpace(ctup);
908
910 base->sortKeys &&
911 base->sortKeys->abbrev_converter &&
912 !stup.isnull1, tuplen);
913
914 MemoryContextSwitchTo(oldcontext);
915}

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

Referenced by _gin_process_worker_data(), and ginFlushBuildState().

◆ tuplesort_putheaptuple()

void tuplesort_putheaptuple ( Tuplesortstate state,
HeapTuple  tup 
)

Definition at line 775 of file tuplesortvariants.c.

776{
777 SortTuple stup;
781 Size tuplen;
782
783 /* copy the tuple into sort storage */
784 tup = heap_copytuple(tup);
785 stup.tuple = tup;
786
787 /*
788 * set up first-column key value, and potentially abbreviate, if it's a
789 * simple column
790 */
791 if (base->haveDatum1)
792 {
793 stup.datum1 = heap_getattr(tup,
794 arg->indexInfo->ii_IndexAttrNumbers[0],
795 arg->tupDesc,
796 &stup.isnull1);
797 }
798
799 /* GetMemoryChunkSpace is not supported for bump contexts */
801 tuplen = MAXALIGN(HEAPTUPLESIZE + tup->t_len);
802 else
803 tuplen = GetMemoryChunkSpace(tup);
804
806 base->haveDatum1 &&
807 base->sortKeys->abbrev_converter &&
808 !stup.isnull1, tuplen);
809
810 MemoryContextSwitchTo(oldcontext);
811}
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,
const ItemPointerData self,
const Datum values,
const bool *  isnull 
)

Definition at line 818 of file tuplesortvariants.c.

821{
822 SortTuple stup;
823 IndexTuple tuple;
826 Size tuplen;
827
829 isnull, base->tuplecontext);
830 tuple = ((IndexTuple) stup.tuple);
831 tuple->t_tid = *self;
832 /* set up first-column key value */
833 stup.datum1 = index_getattr(tuple,
834 1,
835 RelationGetDescr(arg->indexRel),
836 &stup.isnull1);
837
838 /* GetMemoryChunkSpace is not supported for bump contexts */
840 tuplen = MAXALIGN(tuple->t_info & INDEX_SIZE_MASK);
841 else
842 tuplen = GetMemoryChunkSpace(tuple);
843
845 base->sortKeys &&
846 base->sortKeys->abbrev_converter &&
847 !stup.isnull1, tuplen);
848}
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 735 of file tuplesortvariants.c.

736{
739 TupleDesc tupDesc = (TupleDesc) base->arg;
740 SortTuple stup;
741 MinimalTuple tuple;
742 HeapTupleData htup;
743 Size tuplen;
744
745 /* copy the tuple into sort storage */
746 tuple = ExecCopySlotMinimalTuple(slot);
747 stup.tuple = tuple;
748 /* set up first-column key value */
749 htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
750 htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
751 stup.datum1 = heap_getattr(&htup,
752 base->sortKeys[0].ssup_attno,
753 tupDesc,
754 &stup.isnull1);
755
756 /* GetMemoryChunkSpace is not supported for bump contexts */
758 tuplen = MAXALIGN(tuple->t_len);
759 else
760 tuplen = GetMemoryChunkSpace(tuple);
761
763 base->sortKeys->abbrev_converter &&
764 !stup.isnull1, tuplen);
765
766 MemoryContextSwitchTo(oldcontext);
767}
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
Definition: tuptable.h:495

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

1475{
1477 HeapTuple tuple = (HeapTuple) stup->tuple;
1478 unsigned int tuplen = tuple->t_len + sizeof(ItemPointerData) + sizeof(int);
1479
1480 /* We need to store t_self, but not other fields of HeapTupleData */
1481 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1482 LogicalTapeWrite(tape, &tuple->t_self, sizeof(ItemPointerData));
1483 LogicalTapeWrite(tape, tuple->t_data, tuple->t_len);
1484 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1485 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1486}
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 2006 of file tuplesortvariants.c.

2007{
2010 void *waddr;
2011 unsigned int tuplen;
2012 unsigned int writtenlen;
2013
2014 if (stup->isnull1)
2015 {
2016 waddr = NULL;
2017 tuplen = 0;
2018 }
2019 else if (!base->tuples)
2020 {
2021 waddr = &stup->datum1;
2022 tuplen = sizeof(Datum);
2023 }
2024 else
2025 {
2026 waddr = stup->tuple;
2027 tuplen = datumGetSize(PointerGetDatum(stup->tuple), false, arg->datumTypeLen);
2028 Assert(tuplen != 0);
2029 }
2030
2031 writtenlen = tuplen + sizeof(unsigned int);
2032
2033 LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
2034 LogicalTapeWrite(tape, waddr, tuplen);
2035 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
2036 LogicalTapeWrite(tape, &writtenlen, sizeof(writtenlen));
2037}
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 1277 of file tuplesortvariants.c.

1278{
1280 MinimalTuple tuple = (MinimalTuple) stup->tuple;
1281
1282 /* the part of the MinimalTuple we'll write: */
1283 char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
1284 unsigned int tupbodylen = tuple->t_len - MINIMAL_TUPLE_DATA_OFFSET;
1285
1286 /* total on-disk footprint: */
1287 unsigned int tuplen = tupbodylen + sizeof(int);
1288
1289 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1290 LogicalTapeWrite(tape, tupbody, tupbodylen);
1291 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1292 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1293}

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

1793{
1795 IndexTuple tuple = (IndexTuple) stup->tuple;
1796 unsigned int tuplen;
1797
1798 tuplen = IndexTupleSize(tuple) + sizeof(tuplen);
1799 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1800 LogicalTapeWrite(tape, tuple, IndexTupleSize(tuple));
1801 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1802 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1803}
static Size IndexTupleSize(const IndexTupleData *itup)
Definition: itup.h:71

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

1861{
1863 BrinSortTuple *tuple = (BrinSortTuple *) stup->tuple;
1864 unsigned int tuplen = tuple->tuplen;
1865
1866 tuplen = tuplen + sizeof(tuplen);
1867 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1868 LogicalTapeWrite(tape, &tuple->tuple, tuple->tuplen);
1869 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1870 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1871}

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

Referenced by tuplesort_begin_index_brin().

◆ writetup_index_gin()

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

Definition at line 1924 of file tuplesortvariants.c.

1925{
1927 GinTuple *tuple = (GinTuple *) stup->tuple;
1928 unsigned int tuplen = tuple->tuplen;
1929
1930 tuplen = tuplen + sizeof(tuplen);
1931 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1932 LogicalTapeWrite(tape, tuple, tuple->tuplen);
1933 if (base->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length word? */
1934 LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
1935}

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

Referenced by tuplesort_begin_index_gin().