From 0ae121f5756241e8bc5831f74130d74bf4e5f8a4 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 21 Jun 2022 14:03:13 +0300 Subject: [PATCH 2/6] Add new Tuplesortstate.removeabbrev function This commit is the preparation to move abbreviation logic into puttuple_common(). The new removeabbrev function turns datum1 representation of SortTuple's from the abbreviated key to the first column value. Therefore, it encapsulates the differential part of abbreviation handling code in tuplesort_put*() functions, making these functions similar. --- src/backend/utils/sort/tuplesort.c | 156 +++++++++++++++++++---------- 1 file changed, 103 insertions(+), 53 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 4812b1d9ae3..8b6b2bc1d38 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -279,6 +279,13 @@ struct Tuplesortstate */ SortTupleComparator comparetup; + /* + * Alter datum1 representation in the SortTuple's array back from the + * abbreviated key to the first column value. + */ + void (*removeabbrev) (Tuplesortstate *state, SortTuple *stups, + int count); + /* * Function to write a stored tuple onto tape. The representation of the * tuple on tape need not be the same as it is in memory; requirements on @@ -540,6 +547,7 @@ struct Sharedsort pfree(buf); \ } while(0) +#define REMOVEABBREV(state,stup,count) ((*(state)->removeabbrev) (state, stup, count)) #define COMPARETUP(state,a,b) ((*(state)->comparetup) (a, b, state)) #define WRITETUP(state,tape,stup) ((*(state)->writetup) (state, tape, stup)) #define READTUP(state,stup,tape,len) ((*(state)->readtup) (state, stup, tape, len)) @@ -629,6 +637,14 @@ static void reversedirection(Tuplesortstate *state); static unsigned int getlen(LogicalTape *tape, bool eofOK); static void markrunend(LogicalTape *tape); static void *readtup_alloc(Tuplesortstate *state, Size tuplen); +static void removeabbrev_heap(Tuplesortstate *state, SortTuple *stups, + int count); +static void removeabbrev_cluster(Tuplesortstate *state, SortTuple *stups, + int count); +static void removeabbrev_index(Tuplesortstate *state, SortTuple *stups, + int count); +static void removeabbrev_datum(Tuplesortstate *state, SortTuple *stups, + int count); static int comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state); static void writetup_heap(Tuplesortstate *state, LogicalTape *tape, @@ -1042,6 +1058,7 @@ tuplesort_begin_heap(TupleDesc tupDesc, sortopt & TUPLESORT_RANDOMACCESS, PARALLEL_SORT(state)); + state->removeabbrev = removeabbrev_heap; state->comparetup = comparetup_heap; state->writetup = writetup_heap; state->readtup = readtup_heap; @@ -1117,6 +1134,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc, sortopt & TUPLESORT_RANDOMACCESS, PARALLEL_SORT(state)); + state->removeabbrev = removeabbrev_cluster; state->comparetup = comparetup_cluster; state->writetup = writetup_cluster; state->readtup = readtup_cluster; @@ -1221,6 +1239,7 @@ tuplesort_begin_index_btree(Relation heapRel, sortopt & TUPLESORT_RANDOMACCESS, PARALLEL_SORT(state)); + state->removeabbrev = removeabbrev_index; state->comparetup = comparetup_index_btree; state->writetup = writetup_index; state->readtup = readtup_index; @@ -1297,6 +1316,7 @@ tuplesort_begin_index_hash(Relation heapRel, state->nKeys = 1; /* Only one sort column, the hash code */ + state->removeabbrev = removeabbrev_index; state->comparetup = comparetup_index_hash; state->writetup = writetup_index; state->readtup = readtup_index; @@ -1337,6 +1357,7 @@ tuplesort_begin_index_gist(Relation heapRel, state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel); + state->removeabbrev = removeabbrev_index; state->comparetup = comparetup_index_btree; state->writetup = writetup_index; state->readtup = readtup_index; @@ -1400,6 +1421,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, sortopt & TUPLESORT_RANDOMACCESS, PARALLEL_SORT(state)); + state->removeabbrev = removeabbrev_datum; state->comparetup = comparetup_datum; state->writetup = writetup_datum; state->readtup = readtup_datum; @@ -1871,20 +1893,7 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot) * sorted on tape, since serialized tuples lack abbreviated keys * (TSS_BUILDRUNS state prevents control reaching here in any case). */ - for (i = 0; i < state->memtupcount; i++) - { - SortTuple *mtup = &state->memtuples[i]; - - htup.t_len = ((MinimalTuple) mtup->tuple)->t_len + - MINIMAL_TUPLE_OFFSET; - htup.t_data = (HeapTupleHeader) ((char *) mtup->tuple - - MINIMAL_TUPLE_OFFSET); - - mtup->datum1 = heap_getattr(&htup, - state->sortKeys[0].ssup_attno, - state->tupDesc, - &mtup->isnull1); - } + REMOVEABBREV(state, state->memtuples, state->memtupcount); } puttuple_common(state, &stup); @@ -1925,12 +1934,12 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup) if (!state->sortKeys->abbrev_converter || stup.isnull1) { /* - * Store ordinary Datum representation, or NULL value. If there is a - * converter it won't expect NULL values, and cost model is not - * required to account for NULL, so in that case we avoid calling - * converter and just set datum1 to zeroed representation (to be - * consistent, and to support cheap inequality tests for NULL - * abbreviated keys). + * Store ordinary Datum representation, or NULL value. If there + * is a converter it won't expect NULL values, and cost model is + * not required to account for NULL, so in that case we avoid + * calling converter and just set datum1 to zeroed representation + * (to be consistent, and to support cheap inequality tests for + * NULL abbreviated keys). */ stup.datum1 = original; } @@ -1949,23 +1958,15 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup) /* * Set state to be consistent with never trying abbreviation. - * - * Alter datum1 representation in already-copied tuples, so as to - * ensure a consistent representation (current tuple was just - * handled). It does not matter if some dumped tuples are already - * sorted on tape, since serialized tuples lack abbreviated keys - * (TSS_BUILDRUNS state prevents control reaching here in any case). - */ - for (i = 0; i < state->memtupcount; i++) - { - SortTuple *mtup = &state->memtuples[i]; - - tup = (HeapTuple) mtup->tuple; - mtup->datum1 = heap_getattr(tup, - state->indexInfo->ii_IndexAttrNumbers[0], - state->tupDesc, - &mtup->isnull1); - } + * + * Alter datum1 representation in already-copied tuples, so as to + * ensure a consistent representation (current tuple was just + * handled). It does not matter if some dumped tuples are already + * sorted on tape, since serialized tuples lack abbreviated keys + * (TSS_BUILDRUNS state prevents control reaching here in any + * case). + */ + REMOVEABBREV(state, state->memtuples, state->memtupcount); } } @@ -2035,16 +2036,7 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel, * sorted on tape, since serialized tuples lack abbreviated keys * (TSS_BUILDRUNS state prevents control reaching here in any case). */ - for (i = 0; i < state->memtupcount; i++) - { - SortTuple *mtup = &state->memtuples[i]; - - tuple = mtup->tuple; - mtup->datum1 = index_getattr(tuple, - 1, - RelationGetDescr(state->indexRel), - &mtup->isnull1); - } + REMOVEABBREV(state, state->memtuples, state->memtupcount); } puttuple_common(state, &stup); @@ -2122,12 +2114,7 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull) * (TSS_BUILDRUNS state prevents control reaching here in any * case). */ - for (i = 0; i < state->memtupcount; i++) - { - SortTuple *mtup = &state->memtuples[i]; - - mtup->datum1 = PointerGetDatum(mtup->tuple); - } + REMOVEABBREV(state, state->memtuples, state->memtupcount); } } @@ -3984,6 +3971,26 @@ readtup_alloc(Tuplesortstate *state, Size tuplen) * Routines specialized for HeapTuple (actually MinimalTuple) case */ +static void +removeabbrev_heap(Tuplesortstate *state, SortTuple *stups, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + HeapTupleData htup; + + htup.t_len = ((MinimalTuple) stups[i].tuple)->t_len + + MINIMAL_TUPLE_OFFSET; + htup.t_data = (HeapTupleHeader) ((char *) stups[i].tuple - + MINIMAL_TUPLE_OFFSET); + stups[i].datum1 = heap_getattr(&htup, + state->sortKeys[0].ssup_attno, + state->tupDesc, + &stups[i].isnull1); + } +} + static int comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) { @@ -4102,6 +4109,23 @@ readtup_heap(Tuplesortstate *state, SortTuple *stup, * comparisons per a btree index definition) */ +static void +removeabbrev_cluster(Tuplesortstate *state, SortTuple *stups, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + HeapTuple tup; + + tup = (HeapTuple) stups[i].tuple; + stups[i].datum1 = heap_getattr(tup, + state->indexInfo->ii_IndexAttrNumbers[0], + state->tupDesc, + &stups[i].isnull1); + } +} + static int comparetup_cluster(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) @@ -4271,6 +4295,23 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup, * functions can be shared. */ +static void +removeabbrev_index(Tuplesortstate *state, SortTuple *stups, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + IndexTuple tuple; + + tuple = stups[i].tuple; + stups[i].datum1 = index_getattr(tuple, + 1, + RelationGetDescr(state->indexRel), + &stups[i].isnull1); + } +} + static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) @@ -4503,6 +4544,15 @@ readtup_index(Tuplesortstate *state, SortTuple *stup, * Routines specialized for DatumTuple case */ +static void +removeabbrev_datum(Tuplesortstate *state, SortTuple *stups, int count) +{ + int i; + + for (i = 0; i < count; i++) + stups[i].datum1 = PointerGetDatum(stups[i].tuple); +} + static int comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) { -- 2.24.3 (Apple Git-128)