@@ -211,8 +211,8 @@ struct Tuplesortstate
211211 * tuples to return? */
212212bool boundUsed ;/* true if we made use of a bounded heap */
213213int bound ;/* if bounded, the maximum number of tuples */
214- long availMem ;/* remaining memory available, in bytes */
215- long allowedMem ;/* total memory allowed, in bytes */
214+ Size availMem ;/* remaining memory available, in bytes */
215+ Size allowedMem ;/* total memory allowed, in bytes */
216216int maxTapes ;/* number of tapes (Knuth's T) */
217217int tapeRange ;/* maxTapes-1 (Knuth's P) */
218218MemoryContext sortcontext ;/* memory context holding all sort data */
@@ -308,7 +308,7 @@ struct Tuplesortstate
308308int * mergenext ;/* first preread tuple for each source */
309309int * mergelast ;/* last preread tuple for each source */
310310int * mergeavailslots ;/* slots left for prereading each tape */
311- long * mergeavailmem ;/* availMem for prereading each tape */
311+ Size * mergeavailmem ;/* availMem for prereading each tape */
312312int mergefreelist ;/* head of freelist of recycled slots */
313313int mergefirstfree ;/* first slot never used in this merge */
314314
@@ -961,25 +961,26 @@ tuplesort_end(Tuplesortstate *state)
961961}
962962
963963/*
964- * Grow the memtuples[] array, if possible within our memory constraint.
965- * Return TRUE if we were able to enlarge the array, FALSE if not.
964+ * Grow the memtuples[] array, if possible within our memory constraint. We
965+ * must not exceed INT_MAX tuples in memory or the caller-provided memory
966+ * limit. Return TRUE if we were able to enlarge the array, FALSE if not.
966967 *
967- * Normally, at each increment we double the size of the array. Whenwe no
968- *longer have enough memory to do that , we attempt one last, smaller increase
969- *(and then clear the growmemtuples flag so we don't try any more). That
970- *allows us to useallowedMem as fully aspossible ; sticking to the pure
971- *doubling rule could result in almost halfof allowedMem going unused.
972- *Because availMem moves around with tuple addition/removal, we need some
973- *rule to prevent making repeated small increases in memtupsize, which would
974- *just be useless thrashing. The growmemtuples flag accomplishes that and
975- *also prevents useless recalculations in this function.
968+ * Normally, at each increment we double the size of the array. Whendoing
969+ *that would exceed a limit , we attempt one last, smaller increase (and then
970+ * clear the growmemtuples flag so we don't try any more). That allows us to
971+ * usememory as fully aspermitted ; sticking to the pure doubling rule could
972+ * result in almost half going unused. Because availMem moves around with
973+ * tuple addition/removal, we need some rule to prevent making repeated small
974+ * increases in memtupsize, which would just be useless thrashing. The
975+ * growmemtuples flag accomplishes that and also prevents useless
976+ * recalculations in this function.
976977 */
977978static bool
978979grow_memtuples (Tuplesortstate * state )
979980{
980981int newmemtupsize ;
981982int memtupsize = state -> memtupsize ;
982- long memNowUsed = state -> allowedMem - state -> availMem ;
983+ Size memNowUsed = state -> allowedMem - state -> availMem ;
983984
984985/* Forget it if we've already maxed out memtuples, per comment above */
985986if (!state -> growmemtuples )
@@ -989,14 +990,16 @@ grow_memtuples(Tuplesortstate *state)
989990if (memNowUsed <=state -> availMem )
990991{
991992/*
992- * It is surely safe to double memtupsize if we've used no more than
993- * half of allowedMem.
994- *
995- * Note: it might seem that we need to worry about memtupsize * 2
996- * overflowing an int, but the MaxAllocSize clamp applied below
997- * ensures the existing memtupsize can't be large enough for that.
993+ * We've used no more than half of allowedMem; double our usage,
994+ * clamping at INT_MAX.
998995 */
999- newmemtupsize = memtupsize * 2 ;
996+ if (memtupsize < INT_MAX /2 )
997+ newmemtupsize = memtupsize * 2 ;
998+ else
999+ {
1000+ newmemtupsize = INT_MAX ;
1001+ state -> growmemtuples = false;
1002+ }
10001003}
10011004else
10021005{
@@ -1012,24 +1015,27 @@ grow_memtuples(Tuplesortstate *state)
10121015 * we've already seen, and thus we can extrapolate from the space
10131016 * consumption so far to estimate an appropriate new size for the
10141017 * memtuples array. The optimal value might be higher or lower than
1015- * this estimate, but it's hard to know that in advance.
1018+ * this estimate, but it's hard to know that in advance. We again
1019+ * clamp at INT_MAX tuples.
10161020 *
10171021 * This calculation is safe against enlarging the array so much that
10181022 * LACKMEM becomes true, because the memory currently used includes
10191023 * the present array; thus, there would be enough allowedMem for the
10201024 * new array elements even if no other memory were currently used.
10211025 *
10221026 * We do the arithmetic in float8, because otherwise the product of
1023- * memtupsize and allowedMem could overflow. (A little algebra shows
1024- * that grow_ratio must be less than 2 here, so we are not risking
1025- * integer overflow this way.)Any inaccuracy in the result should be
1026- * insignificant; but even if we computed a completely insane result,
1027- * the checks below will prevent anything really bad from happening.
1027+ * memtupsize and allowedMem could overflow. Any inaccuracy in the
1028+ * result should be insignificant; but even if we computed a
1029+ * completely insane result, the checks below will prevent anything
1030+ * really bad from happening.
10281031 */
10291032double grow_ratio ;
10301033
10311034grow_ratio = (double )state -> allowedMem / (double )memNowUsed ;
1032- newmemtupsize = (int ) (memtupsize * grow_ratio );
1035+ if (memtupsize * grow_ratio < INT_MAX )
1036+ newmemtupsize = (int ) (memtupsize * grow_ratio );
1037+ else
1038+ newmemtupsize = INT_MAX ;
10331039
10341040/* We won't make any further enlargement attempts */
10351041state -> growmemtuples = false;
@@ -1040,12 +1046,13 @@ grow_memtuples(Tuplesortstate *state)
10401046gotonoalloc ;
10411047
10421048/*
1043- * On a 64-bit machine, allowedMem could be more than MaxAllocSize. Clamp
1044- * to ensure our request won't be rejected by palloc.
1049+ * On a 32-bit machine, allowedMem could exceed MaxAllocHugeSize. Clamp
1050+ * to ensure our request won't be rejected. Note that we can easily
1051+ * exhaust address space before facing this outcome.
10451052 */
1046- if ((Size )newmemtupsize >=MaxAllocSize /sizeof (SortTuple ))
1053+ if ((Size )newmemtupsize >=MaxAllocHugeSize /sizeof (SortTuple ))
10471054{
1048- newmemtupsize = (int ) (MaxAllocSize /sizeof (SortTuple ));
1055+ newmemtupsize = (int ) (MaxAllocHugeSize /sizeof (SortTuple ));
10491056state -> growmemtuples = false;/* can't grow any more */
10501057}
10511058
@@ -1060,15 +1067,15 @@ grow_memtuples(Tuplesortstate *state)
10601067 * palloc would be treating both old and new arrays as separate chunks.
10611068 * But we'll check LACKMEM explicitly below just in case.)
10621069 */
1063- if (state -> availMem < (long ) ((newmemtupsize - memtupsize )* sizeof (SortTuple )))
1070+ if (state -> availMem < (Size ) ((newmemtupsize - memtupsize )* sizeof (SortTuple )))
10641071gotonoalloc ;
10651072
10661073/* OK, do it */
10671074FREEMEM (state ,GetMemoryChunkSpace (state -> memtuples ));
10681075state -> memtupsize = newmemtupsize ;
10691076state -> memtuples = (SortTuple * )
1070- repalloc (state -> memtuples ,
1071- state -> memtupsize * sizeof (SortTuple ));
1077+ repalloc_huge (state -> memtuples ,
1078+ state -> memtupsize * sizeof (SortTuple ));
10721079USEMEM (state ,GetMemoryChunkSpace (state -> memtuples ));
10731080if (LACKMEM (state ))
10741081elog (ERROR ,"unexpected out-of-memory situation during sort" );
@@ -1715,7 +1722,7 @@ tuplesort_getdatum(Tuplesortstate *state, bool forward,
17151722 * This is exported for use by the planner. allowedMem is in bytes.
17161723 */
17171724int
1718- tuplesort_merge_order (long allowedMem )
1725+ tuplesort_merge_order (Size allowedMem )
17191726{
17201727int mOrder ;
17211728
@@ -1749,7 +1756,7 @@ inittapes(Tuplesortstate *state)
17491756int maxTapes ,
17501757ntuples ,
17511758j ;
1752- long tapeSpace ;
1759+ Size tapeSpace ;
17531760
17541761/* Compute number of tapes to use: merge order plus 1 */
17551762maxTapes = tuplesort_merge_order (state -> allowedMem )+ 1 ;
@@ -1798,7 +1805,7 @@ inittapes(Tuplesortstate *state)
17981805state -> mergenext = (int * )palloc0 (maxTapes * sizeof (int ));
17991806state -> mergelast = (int * )palloc0 (maxTapes * sizeof (int ));
18001807state -> mergeavailslots = (int * )palloc0 (maxTapes * sizeof (int ));
1801- state -> mergeavailmem = (long * )palloc0 (maxTapes * sizeof (long ));
1808+ state -> mergeavailmem = (Size * )palloc0 (maxTapes * sizeof (Size ));
18021809state -> tp_fib = (int * )palloc0 (maxTapes * sizeof (int ));
18031810state -> tp_runs = (int * )palloc0 (maxTapes * sizeof (int ));
18041811state -> tp_dummy = (int * )palloc0 (maxTapes * sizeof (int ));
@@ -2026,7 +2033,7 @@ mergeonerun(Tuplesortstate *state)
20262033int srcTape ;
20272034int tupIndex ;
20282035SortTuple * tup ;
2029- long priorAvail ,
2036+ Size priorAvail ,
20302037spaceFreed ;
20312038
20322039/*
@@ -2100,7 +2107,7 @@ beginmerge(Tuplesortstate *state)
21002107int tapenum ;
21012108int srcTape ;
21022109int slotsPerTape ;
2103- long spacePerTape ;
2110+ Size spacePerTape ;
21042111
21052112/* Heap should be empty here */
21062113Assert (state -> memtupcount == 0 );
@@ -2221,7 +2228,7 @@ mergeprereadone(Tuplesortstate *state, int srcTape)
22212228unsignedint tuplen ;
22222229SortTuple stup ;
22232230int tupIndex ;
2224- long priorAvail ,
2231+ Size priorAvail ,
22252232spaceUsed ;
22262233
22272234if (!state -> mergeactive [srcTape ])