39 #define CLUSTER_SORT 3
164 #define BRINSORTTUPLE_SIZE(len) (offsetof(BrinSortTuple, tuple) + (len))
170 Oid *sortOperators,
Oid *sortCollations,
171 bool *nullsFirstFlags,
186 "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
209 for (
i = 0;
i < nkeys;
i++)
261 "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
288 if (
arg->indexInfo->ii_IndexAttrNumbers[0] == 0)
293 arg->tupDesc = tupDesc;
297 if (
arg->indexInfo->ii_Expressions != NULL)
351 bool uniqueNullsNotDistinct,
369 "begin index sort: unique = %c, workMem = %d, randomAccess = %c",
370 enforceUnique ?
't' :
'f',
390 arg->index.heapRel = heapRel;
391 arg->index.indexRel = indexRel;
392 arg->enforceUnique = enforceUnique;
393 arg->uniqueNullsNotDistinct = uniqueNullsNotDistinct;
451 "begin index sort: high_mask = 0x%x, low_mask = 0x%x, "
452 "max_buckets = 0x%x, workMem = %d, randomAccess = %c",
469 arg->index.heapRel = heapRel;
470 arg->index.indexRel = indexRel;
472 arg->high_mask = high_mask;
473 arg->low_mask = low_mask;
474 arg->max_buckets = max_buckets;
500 "begin index sort: workMem = %d, randomAccess = %c",
513 arg->index.heapRel = heapRel;
514 arg->index.indexRel = indexRel;
515 arg->enforceUnique =
false;
516 arg->uniqueNullsNotDistinct =
false;
555 "begin index sort: workMem = %d, randomAccess = %c",
573 bool nullsFirstFlag,
int workMem,
589 "begin datum sort: workMem = %d, randomAccess = %c",
609 arg->datumType = datumType;
613 arg->datumTypeLen = typlen;
684 !stup.isnull1, tuplen);
714 arg->indexInfo->ii_IndexAttrNumbers[0],
751 tuple->
t_tid = *
self;
837 stup.datum1 = !isNull ?
val : (
Datum) 0;
838 stup.isnull1 = isNull;
843 stup.isnull1 =
false;
1023 *abbrev = stup.datum1;
1025 if (stup.isnull1 || !base->
tuples)
1028 *isNull = stup.isnull1;
1055 for (
i = 0;
i < count;
i++)
1080 b->datum1,
b->isnull1,
1115 datum1 =
heap_getattr(<up, attno, tupDesc, &isnull1);
1116 datum2 =
heap_getattr(&rtup, attno, tupDesc, &isnull2);
1126 for (nkey = 1; nkey < base->
nKeys; nkey++, sortKey++)
1130 datum1 =
heap_getattr(<up, attno, tupDesc, &isnull1);
1131 datum2 =
heap_getattr(&rtup, attno, tupDesc, &isnull2);
1154 unsigned int tuplen = tupbodylen +
sizeof(int);
1166 unsigned int tupbodylen =
len -
sizeof(int);
1174 tuple->
t_len = tuplen;
1178 stup->
tuple = tuple;
1200 for (
i = 0;
i < count;
i++)
1206 arg->indexInfo->ii_IndexAttrNumbers[0],
1224 b->datum1,
b->isnull1,
1252 tupDesc =
arg->tupDesc;
1257 if (sortKey->abbrev_converter)
1259 AttrNumber leading =
arg->indexInfo->ii_IndexAttrNumbers[0];
1261 datum1 =
heap_getattr(ltup, leading, tupDesc, &isnull1);
1262 datum2 =
heap_getattr(rtup, leading, tupDesc, &isnull2);
1280 if (
arg->indexInfo->ii_Expressions == NULL)
1284 for (; nkey < base->
nKeys; nkey++, sortKey++)
1286 AttrNumber attno =
arg->indexInfo->ii_IndexAttrNumbers[nkey];
1319 l_index_values, l_index_isnull);
1323 r_index_values, r_index_isnull);
1325 for (; nkey < base->
nKeys; nkey++, sortKey++)
1328 l_index_isnull[nkey],
1329 r_index_values[nkey],
1330 r_index_isnull[nkey],
1367 tuple->
t_len = t_len;
1375 stup->
tuple = tuple;
1379 arg->indexInfo->ii_IndexAttrNumbers[0],
1391 if (
arg->estate != NULL)
1415 for (
i = 0;
i < count;
i++)
1442 b->datum1,
b->isnull1,
1462 bool equal_hasnull =
false;
1472 keysz = base->
nKeys;
1475 if (sortKey->abbrev_converter)
1489 equal_hasnull =
true;
1492 for (nkey = 2; nkey <= keysz; nkey++, sortKey++)
1505 equal_hasnull =
true;
1518 if (
arg->enforceUnique && !(!
arg->uniqueNullsNotDistinct && equal_hasnull))
1530 Assert(tuple1 != tuple2);
1537 (
errcode(ERRCODE_UNIQUE_VIOLATION),
1538 errmsg(
"could not create unique index \"%s\"",
1540 key_desc ?
errdetail(
"Key %s is duplicated.", key_desc) :
1557 return (blk1 < blk2) ? -1 : 1;
1564 return (pos1 < pos2) ? -1 : 1;
1593 arg->max_buckets,
arg->high_mask,
1597 arg->max_buckets,
arg->high_mask,
1599 if (bucket1 > bucket2)
1601 else if (bucket1 < bucket2)
1613 else if (hash1 < hash2)
1629 return (blk1 < blk2) ? -1 : 1;
1636 return (pos1 < pos2) ? -1 : 1;
1663 unsigned int tuplen;
1678 unsigned int tuplen =
len -
sizeof(
unsigned int);
1684 stup->
tuple = tuple;
1701 for (
i = 0;
i < count;
i++)
1731 unsigned int tuplen = tuple->
tuplen;
1733 tuplen = tuplen +
sizeof(tuplen);
1746 unsigned int tuplen =
len -
sizeof(
unsigned int);
1760 stup->
tuple = tuple;
1775 for (
i = 0;
i < count;
i++)
1786 b->datum1,
b->isnull1,
1815 unsigned int tuplen;
1816 unsigned int writtenlen;
1826 tuplen =
sizeof(
Datum);
1830 waddr = stup->
tuple;
1835 writtenlen = tuplen +
sizeof(
unsigned int);
1848 unsigned int tuplen =
len -
sizeof(
unsigned int);
1871 stup->
tuple = raddr;
static Datum values[MAXATTR]
#define Assert(condition)
Datum datumCopy(Datum value, bool typByVal, int typLen)
Size datumGetSize(Datum value, bool typByVal, int typLen)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
const TupleTableSlotOps TTSOpsHeapTuple
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
EState * CreateExecutorState(void)
void FreeExecutorState(EState *estate)
#define ResetPerTupleExprContext(estate)
#define GetPerTupleExprContext(estate)
char * BuildIndexValueDescription(Relation indexRelation, const Datum *values, const bool *isnull)
static int compare(const void *arg1, const void *arg2)
Bucket _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket, uint32 highmask, uint32 lowmask)
HeapTuple heap_copytuple(HeapTuple tuple)
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
HeapTupleData * HeapTuple
MinimalTupleData * MinimalTuple
HeapTupleHeaderData * HeapTupleHeader
#define MINIMAL_TUPLE_OFFSET
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define MINIMAL_TUPLE_DATA_OFFSET
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
IndexInfo * BuildIndexInfo(Relation index)
void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull, MemoryContext context)
if(TABLE==NULL||TABLE_index==NULL)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
void LogicalTapeWrite(LogicalTape *lt, const void *ptr, size_t size)
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
void pfree(void *pointer)
Size GetMemoryChunkSpace(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
#define SK_BT_NULLS_FIRST
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
static uint32 DatumGetUInt32(Datum X)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
MemoryContextSwitchTo(old_ctx)
#define RelationGetDescr(relation)
#define RelationGetNumberOfAttributes(relation)
#define RelationGetRelationName(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
int errtableconstraint(Relation rel, const char *conname)
static pg_noinline void Size size
void PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup)
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, SortSupport ssup)
static int ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
struct SortSupportData * SortSupport
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
#define BTGreaterStrategyNumber
#define BTLessStrategyNumber
ScanKeyData scankeys[INDEX_MAX_KEYS]
TupleTableSlot * ecxt_scantuple
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
bool uniqueNullsNotDistinct
MemoryContext maincontext
void(* writetup)(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
void(* removeabbrev)(Tuplesortstate *state, SortTuple *stups, int count)
void(* freestate)(Tuplesortstate *state)
MemoryContext tuplecontext
MemoryContext sortcontext
void(* readtup)(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
SortTupleComparator comparetup
SortTupleComparator comparetup_tiebreak
struct TupleDescData * TupleDesc
Tuplesortstate * tuplesort_begin_common(int workMem, SortCoordinate coordinate, int sortopt)
void tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev, Size tuplen)
bool tuplesort_gettuple_common(Tuplesortstate *state, bool forward, SortTuple *stup)
void * tuplesort_readtup_alloc(Tuplesortstate *state, Size tuplen)
#define TupleSortUseBumpTupleCxt(opt)
#define PARALLEL_SORT(coordinate)
#define TUPLESORT_RANDOMACCESS
#define LogicalTapeReadExact(tape, ptr, len)
#define TuplesortstateGetPublic(state)
IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward)
static void writetup_index_brin(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
HeapTuple tuplesort_getheaptuple(Tuplesortstate *state, bool forward)
static void removeabbrev_datum(Tuplesortstate *state, SortTuple *stups, int count)
static int comparetup_index_btree_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
void tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
Tuplesortstate * tuplesort_begin_index_hash(Relation heapRel, Relation indexRel, uint32 high_mask, uint32 low_mask, uint32 max_buckets, int workMem, SortCoordinate coordinate, int sortopt)
static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
void tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel, ItemPointer self, const Datum *values, const bool *isnull)
static void readtup_index(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static int comparetup_cluster_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
void tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
static int comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Tuplesortstate * tuplesort_begin_index_gist(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
Tuplesortstate * tuplesort_begin_index_btree(Relation heapRel, Relation indexRel, bool enforceUnique, bool uniqueNullsNotDistinct, int workMem, SortCoordinate coordinate, int sortopt)
static void removeabbrev_index(Tuplesortstate *state, SortTuple *stups, int count)
static int comparetup_datum_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
Tuplesortstate * tuplesort_begin_index_brin(int workMem, SortCoordinate coordinate, int sortopt)
static void readtup_datum(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static void readtup_heap(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
static void readtup_cluster(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int tuplen)
static void writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
struct BrinSortTuple BrinSortTuple
Tuplesortstate * tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, SortCoordinate coordinate, int sortopt)
static int comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
bool tuplesort_gettupleslot(Tuplesortstate *state, bool forward, bool copy, TupleTableSlot *slot, Datum *abbrev)
static void removeabbrev_index_brin(Tuplesortstate *state, SortTuple *stups, int count)
#define BRINSORTTUPLE_SIZE(len)
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
static void readtup_index_brin(Tuplesortstate *state, SortTuple *stup, LogicalTape *tape, unsigned int len)
Tuplesortstate * tuplesort_begin_cluster(TupleDesc tupDesc, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
void tuplesort_putbrintuple(Tuplesortstate *state, BrinTuple *tuple, Size size)
static void writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
static void writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
static int comparetup_heap_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
static void freestate_cluster(Tuplesortstate *state)
static void removeabbrev_heap(Tuplesortstate *state, SortTuple *stups, int count)
void tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
static int comparetup_cluster(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_hash_tiebreak(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
bool tuplesort_getdatum(Tuplesortstate *state, bool forward, bool copy, Datum *val, bool *isNull, Datum *abbrev)
BrinTuple * tuplesort_getbrintuple(Tuplesortstate *state, Size *len, bool forward)
static void writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
static void removeabbrev_cluster(Tuplesortstate *state, SortTuple *stups, int count)
Tuplesortstate * tuplesort_begin_heap(TupleDesc tupDesc, int nkeys, AttrNumber *attNums, Oid *sortOperators, Oid *sortCollations, bool *nullsFirstFlags, int workMem, SortCoordinate coordinate, int sortopt)
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)