@@ -288,11 +288,7 @@ struct Tuplesortstate
288288
289289 /*
290290 * Function to write a stored tuple onto tape. The representation of the
291- * tuple on tape need not be the same as it is in memory; requirements on
292- * the tape representation are given below. Unless the slab allocator is
293- * used, after writing the tuple, pfree() the out-of-line data (not the
294- * SortTuple struct!), and increase state->availMem by the amount of
295- * memory space thereby released.
291+ * tuple on tape need not be the same as it is in memory.
296292 */
297293 void (* writetup ) (Tuplesortstate * state , LogicalTape * tape ,
298294 SortTuple * stup );
@@ -549,7 +545,7 @@ struct Sharedsort
549545
550546#define REMOVEABBREV (state ,stup ,count ) ((*(state)->removeabbrev) (state, stup, count))
551547#define COMPARETUP (state ,a ,b ) ((*(state)->comparetup) (a, b, state))
552- #define WRITETUP (state ,tape ,stup ) ((*(state)->writetup) (state, tape, stup))
548+ #define WRITETUP (state ,tape ,stup ) (writetuple (state, tape, stup))
553549#define READTUP (state ,stup ,tape ,len ) ((*(state)->readtup) (state, stup, tape, len))
554550#define LACKMEM (state ) ((state)->availMem < 0 && !(state)->slabAllocatorUsed)
555551#define USEMEM (state ,amt ) ((state)->availMem -= (amt))
@@ -618,6 +614,8 @@ static Tuplesortstate *tuplesort_begin_common(int workMem,
618614static void tuplesort_begin_batch (Tuplesortstate * state );
619615static void puttuple_common (Tuplesortstate * state , SortTuple * tuple ,
620616 bool useAbbrev );
617+ static void writetuple (Tuplesortstate * state , LogicalTape * tape ,
618+ SortTuple * stup );
621619static bool consider_abort_common (Tuplesortstate * state );
622620static void inittapes (Tuplesortstate * state , bool mergeruns );
623621static void inittapestate (Tuplesortstate * state , int maxTapes );
@@ -1848,7 +1846,6 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
18481846 /* copy the tuple into sort storage */
18491847 tuple = ExecCopySlotMinimalTuple (slot );
18501848 stup .tuple = (void * ) tuple ;
1851- USEMEM (state , GetMemoryChunkSpace (tuple ));
18521849 /* set up first-column key value */
18531850 htup .t_len = tuple -> t_len + MINIMAL_TUPLE_OFFSET ;
18541851 htup .t_data = (HeapTupleHeader ) ((char * ) tuple - MINIMAL_TUPLE_OFFSET );
@@ -1857,8 +1854,6 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
18571854 state -> tupDesc ,
18581855 & stup .isnull1 );
18591856
1860- MemoryContextSwitchTo (state -> sortcontext );
1861-
18621857 puttuple_common (state , & stup ,
18631858 state -> sortKeys -> abbrev_converter && !stup .isnull1 );
18641859
@@ -1879,9 +1874,6 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
18791874 /* copy the tuple into sort storage */
18801875 tup = heap_copytuple (tup );
18811876 stup .tuple = (void * ) tup ;
1882- USEMEM (state , GetMemoryChunkSpace (tup ));
1883-
1884- MemoryContextSwitchTo (state -> sortcontext );
18851877
18861878 /*
18871879 * set up first-column key value, and potentially abbreviate, if it's a
@@ -1910,27 +1902,21 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
19101902 ItemPointer self , Datum * values ,
19111903 bool * isnull )
19121904{
1913- MemoryContext oldcontext ;
19141905 SortTuple stup ;
19151906 IndexTuple tuple ;
19161907
19171908 stup .tuple = index_form_tuple_context (RelationGetDescr (rel ), values ,
19181909 isnull , state -> tuplecontext );
19191910 tuple = ((IndexTuple ) stup .tuple );
19201911 tuple -> t_tid = * self ;
1921- USEMEM (state , GetMemoryChunkSpace (stup .tuple ));
19221912 /* set up first-column key value */
19231913 stup .datum1 = index_getattr (tuple ,
19241914 1 ,
19251915 RelationGetDescr (state -> indexRel ),
19261916 & stup .isnull1 );
19271917
1928- oldcontext = MemoryContextSwitchTo (state -> sortcontext );
1929-
19301918 puttuple_common (state , & stup ,
19311919 state -> sortKeys && state -> sortKeys -> abbrev_converter && !stup .isnull1 );
1932-
1933- MemoryContextSwitchTo (oldcontext );
19341920}
19351921
19361922/*
@@ -1965,15 +1951,12 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
19651951 stup .datum1 = !isNull ? val : (Datum ) 0 ;
19661952 stup .isnull1 = isNull ;
19671953 stup .tuple = NULL ; /* no separate storage */
1968- MemoryContextSwitchTo (state -> sortcontext );
19691954 }
19701955 else
19711956 {
19721957 stup .isnull1 = false;
19731958 stup .datum1 = datumCopy (val , false, state -> datumTypeLen );
19741959 stup .tuple = DatumGetPointer (stup .datum1 );
1975- USEMEM (state , GetMemoryChunkSpace (stup .tuple ));
1976- MemoryContextSwitchTo (state -> sortcontext );
19771960 }
19781961
19791962 puttuple_common (state , & stup ,
@@ -1988,8 +1971,14 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
19881971static void
19891972puttuple_common (Tuplesortstate * state , SortTuple * tuple , bool useAbbrev )
19901973{
1974+ MemoryContext oldcontext = MemoryContextSwitchTo (state -> sortcontext );
1975+
19911976 Assert (!LEADER (state ));
19921977
1978+ /* Count the size of the out-of-line data */
1979+ if (tuple -> tuple != NULL )
1980+ USEMEM (state , GetMemoryChunkSpace (tuple -> tuple ));
1981+
19931982 if (!useAbbrev )
19941983 {
19951984 /*
@@ -2062,14 +2051,18 @@ puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
20622051 pg_rusage_show (& state -> ru_start ));
20632052#endif
20642053 make_bounded_heap (state );
2054+ MemoryContextSwitchTo (oldcontext );
20652055 return ;
20662056 }
20672057
20682058 /*
20692059 * Done if we still fit in available memory and have array slots.
20702060 */
20712061 if (state -> memtupcount < state -> memtupsize && !LACKMEM (state ))
2062+ {
2063+ MemoryContextSwitchTo (oldcontext );
20722064 return ;
2065+ }
20732066
20742067 /*
20752068 * Nope; time to switch to tape-based operation.
@@ -2123,6 +2116,25 @@ puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
21232116 elog (ERROR , "invalid tuplesort state" );
21242117 break ;
21252118 }
2119+ MemoryContextSwitchTo (oldcontext );
2120+ }
2121+
2122+ /*
2123+ * Write a stored tuple onto tape.tuple. Unless the slab allocator is
2124+ * used, after writing the tuple, pfree() the out-of-line data (not the
2125+ * SortTuple struct!), and increase state->availMem by the amount of
2126+ * memory space thereby released.
2127+ */
2128+ static void
2129+ writetuple (Tuplesortstate * state , LogicalTape * tape , SortTuple * stup )
2130+ {
2131+ state -> writetup (state , tape , stup );
2132+
2133+ if (!state -> slabAllocatorUsed && stup -> tuple )
2134+ {
2135+ FREEMEM (state , GetMemoryChunkSpace (stup -> tuple ));
2136+ pfree (stup -> tuple );
2137+ }
21262138}
21272139
21282140static bool
@@ -3960,12 +3972,6 @@ writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
39603972 if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
39613973 * word? */
39623974 LogicalTapeWrite (tape , (void * ) & tuplen , sizeof (tuplen ));
3963-
3964- if (!state -> slabAllocatorUsed )
3965- {
3966- FREEMEM (state , GetMemoryChunkSpace (tuple ));
3967- heap_free_minimal_tuple (tuple );
3968- }
39693975}
39703976
39713977static void
@@ -4141,12 +4147,6 @@ writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
41414147 if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
41424148 * word? */
41434149 LogicalTapeWrite (tape , & tuplen , sizeof (tuplen ));
4144-
4145- if (!state -> slabAllocatorUsed )
4146- {
4147- FREEMEM (state , GetMemoryChunkSpace (tuple ));
4148- heap_freetuple (tuple );
4149- }
41504150}
41514151
41524152static void
@@ -4403,12 +4403,6 @@ writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
44034403 if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
44044404 * word? */
44054405 LogicalTapeWrite (tape , (void * ) & tuplen , sizeof (tuplen ));
4406-
4407- if (!state -> slabAllocatorUsed )
4408- {
4409- FREEMEM (state , GetMemoryChunkSpace (tuple ));
4410- pfree (tuple );
4411- }
44124406}
44134407
44144408static void
@@ -4495,12 +4489,6 @@ writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
44954489 if (state -> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing length
44964490 * word? */
44974491 LogicalTapeWrite (tape , (void * ) & writtenlen , sizeof (writtenlen ));
4498-
4499- if (!state -> slabAllocatorUsed && stup -> tuple )
4500- {
4501- FREEMEM (state , GetMemoryChunkSpace (stup -> tuple ));
4502- pfree (stup -> tuple );
4503- }
45044492}
45054493
45064494static void
0 commit comments