@@ -300,10 +300,20 @@ struct Tuplesortstate
300300 * the already-read length of the stored tuple. Create a palloc'd copy,
301301 * initialize tuple/datum1/isnull1 in the target SortTuple struct, and
302302 * decrease state->availMem by the amount of memory space consumed.
303+ * (See batchUsed notes for details on how memory is handled when
304+ * incremental accounting is abandoned.)
303305 */
304306void (* readtup ) (Tuplesortstate * state ,SortTuple * stup ,
305307int tapenum ,unsignedint len );
306308
309+ /*
310+ * Function to move a caller tuple. This is usually implemented as a
311+ * memmove() shim, but function may also perform additional fix-up of
312+ * caller tuple where needed. Batch memory support requires the
313+ * movement of caller tuples from one location in memory to another.
314+ */
315+ void (* movetup ) (void * dest ,void * src ,unsignedint len );
316+
307317/*
308318 * This array holds the tuples now in sort memory. If we are in state
309319 * INITIAL, the tuples are in no particular order; if we are in state
@@ -475,6 +485,7 @@ struct Tuplesortstate
475485#define COPYTUP (state ,stup ,tup ) ((*(state)->copytup) (state, stup, tup))
476486#define WRITETUP (state ,tape ,stup )((*(state)->writetup) (state, tape, stup))
477487#define READTUP (state ,stup ,tape ,len ) ((*(state)->readtup) (state, stup, tape, len))
488+ #define MOVETUP (dest ,src ,len ) ((*(state)->movetup) (dest, src, len))
478489#define LACKMEM (state )((state)->availMem < 0 && !(state)->batchUsed)
479490#define USEMEM (state ,amt )((state)->availMem -= (amt))
480491#define FREEMEM (state ,amt )((state)->availMem += (amt))
@@ -571,13 +582,15 @@ static void writetup_heap(Tuplesortstate *state, int tapenum,
571582SortTuple * stup );
572583static void readtup_heap (Tuplesortstate * state ,SortTuple * stup ,
573584int tapenum ,unsignedint len );
585+ static void movetup_heap (void * dest ,void * src ,unsignedint len );
574586static int comparetup_cluster (const SortTuple * a ,const SortTuple * b ,
575587Tuplesortstate * state );
576588static void copytup_cluster (Tuplesortstate * state ,SortTuple * stup ,void * tup );
577589static void writetup_cluster (Tuplesortstate * state ,int tapenum ,
578590SortTuple * stup );
579591static void readtup_cluster (Tuplesortstate * state ,SortTuple * stup ,
580592int tapenum ,unsignedint len );
593+ static void movetup_cluster (void * dest ,void * src ,unsignedint len );
581594static int comparetup_index_btree (const SortTuple * a ,const SortTuple * b ,
582595Tuplesortstate * state );
583596static int comparetup_index_hash (const SortTuple * a ,const SortTuple * b ,
@@ -587,13 +600,15 @@ static void writetup_index(Tuplesortstate *state, int tapenum,
587600SortTuple * stup );
588601static void readtup_index (Tuplesortstate * state ,SortTuple * stup ,
589602int tapenum ,unsignedint len );
603+ static void movetup_index (void * dest ,void * src ,unsignedint len );
590604static int comparetup_datum (const SortTuple * a ,const SortTuple * b ,
591605Tuplesortstate * state );
592606static void copytup_datum (Tuplesortstate * state ,SortTuple * stup ,void * tup );
593607static void writetup_datum (Tuplesortstate * state ,int tapenum ,
594608SortTuple * stup );
595609static void readtup_datum (Tuplesortstate * state ,SortTuple * stup ,
596610int tapenum ,unsignedint len );
611+ static void movetup_datum (void * dest ,void * src ,unsignedint len );
597612static void free_sort_tuple (Tuplesortstate * state ,SortTuple * stup );
598613
599614/*
@@ -749,6 +764,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
749764state -> copytup = copytup_heap ;
750765state -> writetup = writetup_heap ;
751766state -> readtup = readtup_heap ;
767+ state -> movetup = movetup_heap ;
752768
753769state -> tupDesc = tupDesc ;/* assume we need not copy tupDesc */
754770state -> abbrevNext = 10 ;
@@ -821,6 +837,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
821837state -> copytup = copytup_cluster ;
822838state -> writetup = writetup_cluster ;
823839state -> readtup = readtup_cluster ;
840+ state -> movetup = movetup_cluster ;
824841state -> abbrevNext = 10 ;
825842
826843state -> indexInfo = BuildIndexInfo (indexRel );
@@ -912,6 +929,7 @@ tuplesort_begin_index_btree(Relation heapRel,
912929state -> copytup = copytup_index ;
913930state -> writetup = writetup_index ;
914931state -> readtup = readtup_index ;
932+ state -> movetup = movetup_index ;
915933state -> abbrevNext = 10 ;
916934
917935state -> heapRel = heapRel ;
@@ -979,6 +997,7 @@ tuplesort_begin_index_hash(Relation heapRel,
979997state -> copytup = copytup_index ;
980998state -> writetup = writetup_index ;
981999state -> readtup = readtup_index ;
1000+ state -> movetup = movetup_index ;
9821001
9831002state -> heapRel = heapRel ;
9841003state -> indexRel = indexRel ;
@@ -1021,6 +1040,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
10211040state -> copytup = copytup_datum ;
10221041state -> writetup = writetup_datum ;
10231042state -> readtup = readtup_datum ;
1043+ state -> movetup = movetup_datum ;
10241044state -> abbrevNext = 10 ;
10251045
10261046state -> datumType = datumType ;
@@ -2975,7 +2995,7 @@ mergebatchone(Tuplesortstate *state, int srcTape, SortTuple *rtup,
29752995 */
29762996tupLen = state -> mergecurrent [srcTape ]- state -> mergetail [srcTape ];
29772997state -> mergecurrent [srcTape ]= state -> mergetuples [srcTape ];
2978- memmove (state -> mergecurrent [srcTape ],state -> mergetail [srcTape ],
2998+ MOVETUP (state -> mergecurrent [srcTape ],state -> mergetail [srcTape ],
29792999tupLen );
29803000
29813001/* Make SortTuple at top of the merge heap point to new tuple */
@@ -3039,7 +3059,7 @@ mergebatchfreetape(Tuplesortstate *state, int srcTape, SortTuple *rtup,
30393059
30403060tuplen = state -> mergecurrent [srcTape ]- state -> mergetail [srcTape ];
30413061rtup -> tuple = MemoryContextAlloc (state -> sortcontext ,tuplen );
3042- memcpy (rtup -> tuple ,oldTuple ,tuplen );
3062+ MOVETUP (rtup -> tuple ,oldTuple ,tuplen );
30433063* should_free = true;
30443064}
30453065
@@ -4061,6 +4081,12 @@ readtup_heap(Tuplesortstate *state, SortTuple *stup,
40614081& stup -> isnull1 );
40624082}
40634083
4084+ static void
4085+ movetup_heap (void * dest ,void * src ,unsignedint len )
4086+ {
4087+ memmove (dest ,src ,len );
4088+ }
4089+
40644090/*
40654091 * Routines specialized for the CLUSTER case (HeapTuple data, with
40664092 * comparisons per a btree index definition)
@@ -4302,6 +4328,18 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup,
43024328& stup -> isnull1 );
43034329}
43044330
4331+ static void
4332+ movetup_cluster (void * dest ,void * src ,unsignedint len )
4333+ {
4334+ HeapTuple tuple ;
4335+
4336+ memmove (dest ,src ,len );
4337+
4338+ /* Repoint the HeapTupleData header */
4339+ tuple = (HeapTuple )dest ;
4340+ tuple -> t_data = (HeapTupleHeader ) ((char * )tuple + HEAPTUPLESIZE );
4341+ }
4342+
43054343
43064344/*
43074345 * Routines specialized for IndexTuple case
@@ -4594,6 +4632,12 @@ readtup_index(Tuplesortstate *state, SortTuple *stup,
45944632& stup -> isnull1 );
45954633}
45964634
4635+ static void
4636+ movetup_index (void * dest ,void * src ,unsignedint len )
4637+ {
4638+ memmove (dest ,src ,len );
4639+ }
4640+
45974641/*
45984642 * Routines specialized for DatumTuple case
45994643 */
@@ -4704,6 +4748,12 @@ readtup_datum(Tuplesortstate *state, SortTuple *stup,
47044748& tuplen ,sizeof (tuplen ));
47054749}
47064750
4751+ static void
4752+ movetup_datum (void * dest ,void * src ,unsignedint len )
4753+ {
4754+ memmove (dest ,src ,len );
4755+ }
4756+
47074757/*
47084758 * Convenience routine to free a tuple previously loaded into sort memory
47094759 */