Add new Tuplesortstate.removeabbrev function
authorAlexander Korotkov <akorotkov@postgresql.org>
Wed, 27 Jul 2022 05:27:29 +0000 (08:27 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Wed, 27 Jul 2022 05:27:29 +0000 (08:27 +0300)
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.

Discussion: https://postgr.es/m/CAPpHfdvjix0Ahx-H3Jp1M2R%2B_74P-zKnGGygx4OWr%3DbUQ8BNdw%40mail.gmail.com
Author: Alexander Korotkov
Reviewed-by: Pavel Borisov, Maxim Orlov, Matthias van de Meent
Reviewed-by: Andres Freund, John Naylor
src/backend/utils/sort/tuplesort.c

index 3e06e5391a6a6762ea79bee316a190e36c364892..7e6b2b8c888f268c39e5a4cdb706192a63b32963 100644 (file)
@@ -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;
@@ -1858,8 +1880,6 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
        else
        {
                /* Abort abbreviation */
-               int                     i;
-
                stup.datum1 = original;
 
                /*
@@ -1871,20 +1891,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);
@@ -1943,8 +1950,6 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
                else
                {
                        /* Abort abbreviation */
-                       int                     i;
-
                        stup.datum1 = original;
 
                        /*
@@ -1957,16 +1962,7 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
                         * (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);
-                       }
+                       REMOVEABBREV(state, state->memtuples, state->memtupcount);
                }
        }
 
@@ -2023,8 +2019,6 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
        else
        {
                /* Abort abbreviation */
-               int                     i;
-
                stup.datum1 = original;
 
                /*
@@ -2036,16 +2030,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);
@@ -2109,8 +2094,6 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
                else
                {
                        /* Abort abbreviation */
-                       int                     i;
-
                        stup.datum1 = original;
 
                        /*
@@ -2123,12 +2106,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);
                }
        }
 
@@ -3985,6 +3963,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)
 {
@@ -4103,6 +4101,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)
@@ -4272,6 +4287,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)
@@ -4504,6 +4536,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)
 {