diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 466d53d..4d4f9ec 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -695,6 +695,38 @@ repalloc(void *pointer, Size size)
 												 pointer, size);
 }
 
+/* repallocJJ -- like repalloc only lets you exceed MaxAllocSize
+ *   By using this function, you solemnly plege that you will not
+ *   pass the returned pointer to aset.c code or varlena objects.
+ *   see src/include/utils/memutils.h MaxAllocSize comments.
+void *
+repallocJJ(void *pointer, Size size)
+{
+	StandardChunkHeader *header;
+
+	/*
+	 * Try to detect bogus pointers handed to us, poorly though we can.
+	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+	 * allocated chunk.
+	 */
+	Assert(pointer != NULL);
+	Assert(pointer == (void *) MAXALIGN(pointer));
+
+	/*
+	 * OK, it's probably safe to look at the chunk header.
+	 */
+	header = (StandardChunkHeader *)
+		((char *) pointer - STANDARDCHUNKHEADERSIZE);
+
+	AssertArg(MemoryContextIsValid(header->context));
+
+	/* isReset must be false already */
+	Assert(!header->context->isReset);
+
+	return (*header->context->methods->realloc) (header->context,
+												 pointer, size);
+}
+
 /*
  * MemoryContextSwitchTo
  *		Returns the current context; installs the given context.
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 1452e8c..8d28548 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -960,14 +960,13 @@ grow_memtuples(Tuplesortstate *state)
 	/*
 	 * On a 64-bit machine, allowedMem could be high enough to get us into
 	 * trouble with MaxAllocSize, too.
+         * Get around this by using our own repalloc version
 	 */
-	if ((Size) (state->memtupsize * 2) >= MaxAllocSize / sizeof(SortTuple))
-		return false;
 
 	FREEMEM(state, GetMemoryChunkSpace(state->memtuples));
 	state->memtupsize *= 2;
 	state->memtuples = (SortTuple *)
-		repalloc(state->memtuples,
+		repallocJJ(state->memtuples,
 				 state->memtupsize * sizeof(SortTuple));
 	USEMEM(state, GetMemoryChunkSpace(state->memtuples));
 	if (LACKMEM(state))
@@ -1653,9 +1652,9 @@ inittapes(Tuplesortstate *state)
 	state->tapeRange = maxTapes - 1;
 
 #ifdef TRACE_SORT
-	if (trace_sort)
-		elog(LOG, "switching to external sort with %d tapes: %s",
-			 maxTapes, pg_rusage_show(&state->ru_start));
+      if (trace_sort)
+              elog(LOG, "switching to external sort at %d/%d tuples with %d tapes: %s",
+                       state->memtupcount, state->memtupsize, maxTapes, pg_rusage_show(&state->ru_start));
 #endif
 
 	/*
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 973f306..50cc864 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -69,6 +69,7 @@ extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
 extern void pfree(void *pointer);
 
 extern void *repalloc(void *pointer, Size size);
+extern void *repallocJJ(void *pointer, Size size);
 
 /*
  * MemoryContextSwitchTo can't be a macro in standard C compilers.
