9191 * Portions Copyright (c) 1994, Regents of the University of California
9292 *
9393 * IDENTIFICATION
94- * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.68 2006/07/14 14:52:25 momjian Exp $
94+ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.69 2006/10/03 22:18:23 tgl Exp $
9595 *
9696 *-------------------------------------------------------------------------
9797 */
@@ -201,11 +201,11 @@ struct Tuplesortstate
201201 * They are set up by the tuplesort_begin_xxx routines.
202202 *
203203 * Function to compare two tuples; result is per qsort() convention, ie:
204- *
205- *<0, 0, >0 according as a<b, a=b, a>b .
204+ * <0, 0, >0 according as a<b, a=b, a>b. The API must match
205+ *qsort_arg_comparator .
206206 */
207- int (* comparetup ) (Tuplesortstate * state ,
208- const SortTuple * a , const SortTuple * b );
207+ int (* comparetup ) (const SortTuple * a , const SortTuple * b ,
208+ Tuplesortstate * state );
209209
210210/*
211211 * Function to copy a supplied input tuple into palloc'd space and set up
@@ -345,7 +345,7 @@ struct Tuplesortstate
345345#endif
346346};
347347
348- #define COMPARETUP (state ,a ,b )((*(state)->comparetup) (state, a, b))
348+ #define COMPARETUP (state ,a ,b )((*(state)->comparetup) (a, b, state ))
349349#define COPYTUP (state ,stup ,tup )((*(state)->copytup) (state, stup, tup))
350350#define WRITETUP (state ,tape ,stup )((*(state)->writetup) (state, tape, stup))
351351#define READTUP (state ,stup ,tape ,len ) ((*(state)->readtup) (state, stup, tape, len))
@@ -410,37 +410,28 @@ static void tuplesort_heap_insert(Tuplesortstate *state, SortTuple *tuple,
410410static void tuplesort_heap_siftup (Tuplesortstate * state ,bool checkIndex );
411411static unsignedint getlen (Tuplesortstate * state ,int tapenum ,bool eofOK );
412412static void markrunend (Tuplesortstate * state ,int tapenum );
413- static int qsort_comparetup (const void * a ,const void * b );
414- static int comparetup_heap (Tuplesortstate * state ,
415- const SortTuple * a ,const SortTuple * b );
413+ static int comparetup_heap (const SortTuple * a ,const SortTuple * b ,
414+ Tuplesortstate * state );
416415static void copytup_heap (Tuplesortstate * state ,SortTuple * stup ,void * tup );
417416static void writetup_heap (Tuplesortstate * state ,int tapenum ,
418417SortTuple * stup );
419418static void readtup_heap (Tuplesortstate * state ,SortTuple * stup ,
420419int tapenum ,unsignedint len );
421- static int comparetup_index (Tuplesortstate * state ,
422- const SortTuple * a , const SortTuple * b );
420+ static int comparetup_index (const SortTuple * a , const SortTuple * b ,
421+ Tuplesortstate * state );
423422static void copytup_index (Tuplesortstate * state ,SortTuple * stup ,void * tup );
424423static void writetup_index (Tuplesortstate * state ,int tapenum ,
425424SortTuple * stup );
426425static void readtup_index (Tuplesortstate * state ,SortTuple * stup ,
427426int tapenum ,unsignedint len );
428- static int comparetup_datum (Tuplesortstate * state ,
429- const SortTuple * a , const SortTuple * b );
427+ static int comparetup_datum (const SortTuple * a , const SortTuple * b ,
428+ Tuplesortstate * state );
430429static void copytup_datum (Tuplesortstate * state ,SortTuple * stup ,void * tup );
431430static void writetup_datum (Tuplesortstate * state ,int tapenum ,
432431SortTuple * stup );
433432static void readtup_datum (Tuplesortstate * state ,SortTuple * stup ,
434433int tapenum ,unsignedint len );
435434
436- /*
437- * Since qsort(3) will not pass any context info to qsort_comparetup(),
438- * we have to use this ugly static variable. It is set to point to the
439- * active Tuplesortstate object just before calling qsort.It should
440- * not be used directly by anything except qsort_comparetup().
441- */
442- static Tuplesortstate * qsort_tuplesortstate ;
443-
444435
445436/*
446437 *tuplesort_begin_xxx
@@ -930,11 +921,11 @@ tuplesort_performsort(Tuplesortstate *state)
930921 * amount of memory. Just qsort 'em and we're done.
931922 */
932923if (state -> memtupcount > 1 )
933- {
934- qsort_tuplesortstate = state ;
935- qsort (( void * ) state -> memtuples , state -> memtupcount ,
936- sizeof ( SortTuple ), qsort_comparetup );
937- }
924+ qsort_arg (( void * ) state -> memtuples ,
925+ state -> memtupcount ,
926+ sizeof ( SortTuple ) ,
927+ ( qsort_arg_comparator ) state -> comparetup ,
928+ ( void * ) state );
938929state -> current = 0 ;
939930state -> eof_reached = false;
940931state -> markpos_offset = 0 ;
@@ -1587,7 +1578,6 @@ mergeonerun(Tuplesortstate *state)
15871578 */
15881579while (state -> memtupcount > 0 )
15891580{
1590- CHECK_FOR_INTERRUPTS ();
15911581/* write the tuple to destTape */
15921582priorAvail = state -> availMem ;
15931583srcTape = state -> memtuples [0 ].tupindex ;
@@ -2091,20 +2081,6 @@ markrunend(Tuplesortstate *state, int tapenum)
20912081}
20922082
20932083
2094- /*
2095- * qsort interface
2096- */
2097-
2098- static int
2099- qsort_comparetup (const void * a ,const void * b )
2100- {
2101- /* The passed pointers are pointers to SortTuple ... */
2102- return COMPARETUP (qsort_tuplesortstate ,
2103- (const SortTuple * )a ,
2104- (const SortTuple * )b );
2105- }
2106-
2107-
21082084/*
21092085 * This routine selects an appropriate sorting function to implement
21102086 * a sort operator as efficiently as possible.The straightforward
@@ -2319,7 +2295,7 @@ ApplySortFunction(FmgrInfo *sortFunction, SortFunctionKind kind,
23192295 */
23202296
23212297static int
2322- comparetup_heap (Tuplesortstate * state , const SortTuple * a ,const SortTuple * b )
2298+ comparetup_heap (const SortTuple * a ,const SortTuple * b , Tuplesortstate * state )
23232299{
23242300ScanKey scanKey = state -> scanKeys ;
23252301HeapTupleData ltup ;
@@ -2328,6 +2304,9 @@ comparetup_heap(Tuplesortstate *state, const SortTuple *a, const SortTuple *b)
23282304int nkey ;
23292305int32 compare ;
23302306
2307+ /* Allow interrupting long sorts */
2308+ CHECK_FOR_INTERRUPTS ();
2309+
23312310/* Compare the leading sort key */
23322311compare = inlineApplySortFunction (& scanKey -> sk_func ,
23332312state -> sortFnKinds [0 ],
@@ -2449,7 +2428,7 @@ readtup_heap(Tuplesortstate *state, SortTuple *stup,
24492428 */
24502429
24512430static int
2452- comparetup_index (Tuplesortstate * state , const SortTuple * a ,const SortTuple * b )
2431+ comparetup_index (const SortTuple * a ,const SortTuple * b , Tuplesortstate * state )
24532432{
24542433/*
24552434 * This is similar to _bt_tuplecompare(), but we have already done the
@@ -2466,6 +2445,9 @@ comparetup_index(Tuplesortstate *state, const SortTuple *a, const SortTuple *b)
24662445int nkey ;
24672446int32 compare ;
24682447
2448+ /* Allow interrupting long sorts */
2449+ CHECK_FOR_INTERRUPTS ();
2450+
24692451/* Compare the leading sort key */
24702452compare = inlineApplySortFunction (& scanKey -> sk_func ,
24712453SORTFUNC_CMP ,
@@ -2622,8 +2604,11 @@ readtup_index(Tuplesortstate *state, SortTuple *stup,
26222604 */
26232605
26242606static int
2625- comparetup_datum (Tuplesortstate * state , const SortTuple * a ,const SortTuple * b )
2607+ comparetup_datum (const SortTuple * a ,const SortTuple * b , Tuplesortstate * state )
26262608{
2609+ /* Allow interrupting long sorts */
2610+ CHECK_FOR_INTERRUPTS ();
2611+
26272612return inlineApplySortFunction (& state -> sortOpFn ,state -> sortFnKind ,
26282613a -> datum1 ,a -> isnull1 ,
26292614b -> datum1 ,b -> isnull1 );