Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1b0fc85

Browse files
committed
Properly adjust pointers when tuples are moved during CLUSTER.
Otherwise, when we abandon incremental memory accounting and use batch allocation for the final merge pass, we might crash. This has been broken since 0011c00. Peter Geoghegan, tested by Noah Misch
1 parent b22934d commit 1b0fc85

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

src/backend/utils/sort/tuplesort.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
304306
void (*readtup) (Tuplesortstate *state, SortTuple *stup,
305307
int tapenum, unsigned int 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, unsigned int 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,
571582
SortTuple *stup);
572583
static void readtup_heap(Tuplesortstate *state, SortTuple *stup,
573584
int tapenum, unsigned int len);
585+
static void movetup_heap(void *dest, void *src, unsigned int len);
574586
static int comparetup_cluster(const SortTuple *a, const SortTuple *b,
575587
Tuplesortstate *state);
576588
static void copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup);
577589
static void writetup_cluster(Tuplesortstate *state, int tapenum,
578590
SortTuple *stup);
579591
static void readtup_cluster(Tuplesortstate *state, SortTuple *stup,
580592
int tapenum, unsigned int len);
593+
static void movetup_cluster(void *dest, void *src, unsigned int len);
581594
static int comparetup_index_btree(const SortTuple *a, const SortTuple *b,
582595
Tuplesortstate *state);
583596
static int comparetup_index_hash(const SortTuple *a, const SortTuple *b,
@@ -587,13 +600,15 @@ static void writetup_index(Tuplesortstate *state, int tapenum,
587600
SortTuple *stup);
588601
static void readtup_index(Tuplesortstate *state, SortTuple *stup,
589602
int tapenum, unsigned int len);
603+
static void movetup_index(void *dest, void *src, unsigned int len);
590604
static int comparetup_datum(const SortTuple *a, const SortTuple *b,
591605
Tuplesortstate *state);
592606
static void copytup_datum(Tuplesortstate *state, SortTuple *stup, void *tup);
593607
static void writetup_datum(Tuplesortstate *state, int tapenum,
594608
SortTuple *stup);
595609
static void readtup_datum(Tuplesortstate *state, SortTuple *stup,
596610
int tapenum, unsigned int len);
611+
static void movetup_datum(void *dest, void *src, unsigned int len);
597612
static void free_sort_tuple(Tuplesortstate *state, SortTuple *stup);
598613

599614
/*
@@ -749,6 +764,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
749764
state->copytup = copytup_heap;
750765
state->writetup = writetup_heap;
751766
state->readtup = readtup_heap;
767+
state->movetup = movetup_heap;
752768

753769
state->tupDesc = tupDesc; /* assume we need not copy tupDesc */
754770
state->abbrevNext = 10;
@@ -821,6 +837,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
821837
state->copytup = copytup_cluster;
822838
state->writetup = writetup_cluster;
823839
state->readtup = readtup_cluster;
840+
state->movetup = movetup_cluster;
824841
state->abbrevNext = 10;
825842

826843
state->indexInfo = BuildIndexInfo(indexRel);
@@ -912,6 +929,7 @@ tuplesort_begin_index_btree(Relation heapRel,
912929
state->copytup = copytup_index;
913930
state->writetup = writetup_index;
914931
state->readtup = readtup_index;
932+
state->movetup = movetup_index;
915933
state->abbrevNext = 10;
916934

917935
state->heapRel = heapRel;
@@ -979,6 +997,7 @@ tuplesort_begin_index_hash(Relation heapRel,
979997
state->copytup = copytup_index;
980998
state->writetup = writetup_index;
981999
state->readtup = readtup_index;
1000+
state->movetup = movetup_index;
9821001

9831002
state->heapRel = heapRel;
9841003
state->indexRel = indexRel;
@@ -1021,6 +1040,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
10211040
state->copytup = copytup_datum;
10221041
state->writetup = writetup_datum;
10231042
state->readtup = readtup_datum;
1043+
state->movetup = movetup_datum;
10241044
state->abbrevNext = 10;
10251045

10261046
state->datumType = datumType;
@@ -2975,7 +2995,7 @@ mergebatchone(Tuplesortstate *state, int srcTape, SortTuple *rtup,
29752995
*/
29762996
tupLen = state->mergecurrent[srcTape] - state->mergetail[srcTape];
29772997
state->mergecurrent[srcTape] = state->mergetuples[srcTape];
2978-
memmove(state->mergecurrent[srcTape], state->mergetail[srcTape],
2998+
MOVETUP(state->mergecurrent[srcTape], state->mergetail[srcTape],
29792999
tupLen);
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

30403060
tuplen = state->mergecurrent[srcTape] - state->mergetail[srcTape];
30413061
rtup->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, unsigned int 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, unsigned int 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, unsigned int 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, unsigned int len)
4753+
{
4754+
memmove(dest, src, len);
4755+
}
4756+
47074757
/*
47084758
* Convenience routine to free a tuple previously loaded into sort memory
47094759
*/

0 commit comments

Comments
 (0)