2828#include "rum.h" /* RumItem */
2929
3030#if PG_VERSION_NUM >= 160000
31- #include "tuplesort16.c"
32- #undef TRACE_SORT
31+ /*
32+ * After allocating a public interface for Tuplesortstate, no need to include
33+ * source code from pg-core.
34+ */
3335#elif PG_VERSION_NUM >= 150000
3436#include "tuplesort15.c"
3537#elif PG_VERSION_NUM >= 140000
4648#include "tuplesort96.c"
4749#endif
4850
51+ /*
52+ * In case of using custom compare function we should store function pointer in
53+ * sort stare in order to use it later.
54+ */
55+
56+ #if PG_VERSION_NUM >= 160000
57+ /*
58+ * After allocating a public interface for Tuplesortstate we may use
59+ * TuplesortPublic->arg filed to store pointer to the compare function.
60+ */
61+
62+ /* GUC variables */
63+ #ifdef TRACE_SORT
64+ extern PGDLLIMPORT bool trace_sort ;
65+ #endif
66+
67+ /* All memory management should be inside Tuplesortstate module. */
68+ #define USEMEM (state ,amt ) do {} while(0)
69+
70+ #else /* PG_VERSION_NUM >= 160000 */
4971/*
5072 * We need extra field in a state structure but we should not modify struct
5173 * RumTuplesortstate which is inherited from Tuplesortstate core function.
@@ -55,6 +77,7 @@ typedef struct RumTuplesortstateExt
5577 RumTuplesortstate ts ;
5678 FmgrInfo * cmp ;
5779} RumTuplesortstateExt ;
80+ #endif /* PG_VERSION_NUM < 160000 */
5881
5982static int comparetup_rum (const SortTuple * a , const SortTuple * b ,
6083 RumTuplesortstate * state , bool compareItemPointer );
@@ -70,12 +93,18 @@ static void copytup_rumitem(RumTuplesortstate *state, SortTuple *stup,
7093static void * rum_tuplesort_getrum_internal (RumTuplesortstate * state ,
7194 bool forward , bool * should_free );
7295
96+ /*
97+ * Tuplesortstate handling should be done through this macro.
98+ */
7399#if PG_VERSION_NUM >= 160000
74100# define TSS_GET (state ) TuplesortstateGetPublic((state))
75101#else
76102# define TSS_GET (state ) (state)
77103#endif
78104
105+ /*
106+ * Logical tape handling should be done through this macro.
107+ */
79108#if PG_VERSION_NUM >= 150000
80109#define LT_TYPE LogicalTape *
81110#define LT_ARG tape
@@ -86,6 +115,25 @@ static void *rum_tuplesort_getrum_internal(RumTuplesortstate *state,
86115#define TAPE (state , LT_ARG ) state->tapeset, LT_ARG
87116#endif
88117
118+ /*
119+ * Just for convenience and uniformity.
120+ */
121+ #if PG_VERSION_NUM >= 110000
122+ #define tuplesort_begin_common (x ,y ) tuplesort_begin_common((x), NULL, (y))
123+ #endif
124+
125+ /*
126+ * Trace log wrapper.
127+ */
128+ #ifdef TRACE_SORT
129+ # define LOG_SORT (...) \
130+ if (trace_sort) \
131+ ereport(LOG, errmsg_internal(__VA_ARGS__))
132+ #else
133+ # define LOG_SORT (...) \
134+ {}
135+ #endif
136+
89137static inline int
90138compare_rum_itempointer (ItemPointerData p1 , ItemPointerData p2 )
91139{
@@ -156,19 +204,29 @@ comparetup_rum_false(const SortTuple *a, const SortTuple *b,
156204 return comparetup_rum (a , b , state , false);
157205}
158206
207+ static inline FmgrInfo *
208+ comparetup_rumitem_custom_fun (RumTuplesortstate * state )
209+ {
210+ #if PG_VERSION_NUM >= 160000
211+ return (FmgrInfo * ) TSS_GET (state )-> arg ;
212+ #else
213+ return ((RumTuplesortstateExt * ) state )-> cmp ;
214+ #endif
215+ }
216+
159217static int
160218comparetup_rumitem (const SortTuple * a , const SortTuple * b ,
161219 RumTuplesortstate * state )
162220{
163- RumItem * i1 ,
164- * i2 ;
165- FmgrInfo * cmp ;
221+ RumItem * i1 ,
222+ * i2 ;
223+ FmgrInfo * cmp ;
166224
167225 /* Extract RumItem from RumScanItem */
168226 i1 = (RumItem * ) a -> tuple ;
169227 i2 = (RumItem * ) b -> tuple ;
170228
171- cmp = (( RumTuplesortstateExt * ) state )-> cmp ;
229+ cmp = comparetup_rumitem_custom_fun ( state );
172230 if (cmp != NULL )
173231 {
174232 if (i1 -> addInfoIsNull || i2 -> addInfoIsNull )
@@ -242,17 +300,21 @@ writetup_rum_internal(RumTuplesortstate *state, LT_TYPE LT_ARG,
242300 void * item = stup -> tuple ;
243301 size_t size = rum_item_size (state );
244302 unsigned int writtenlen = size + sizeof (unsigned int );
303+ bool randomAccess ;
245304
246305 LogicalTapeWrite (TAPE (state , LT_ARG ),
247306 (void * ) & writtenlen , sizeof (writtenlen ));
248307 LogicalTapeWrite (TAPE (state , LT_ARG ),
249308 (void * ) item , size );
250- #if PG_VERSION_NUM >= 150000
251- if (TSS_GET (state )-> sortopt & TUPLESORT_RANDOMACCESS ) /* need trailing
252- * length word? */
253- #else
254- if (TSS_GET (state )-> randomAccess ) /* need trailing length word? */
255- #endif
309+
310+ randomAccess =
311+ # if PG_VERSION_NUM >= 150000
312+ (TSS_GET (state )-> sortopt & TUPLESORT_RANDOMACCESS ) != 0 ;
313+ # else
314+ TSS_GET (state )-> randomAccess ;
315+ # endif
316+
317+ if (randomAccess )
256318 LogicalTapeWrite (TAPE (TSS_GET (state ), LT_ARG ), (void * ) & writtenlen ,
257319 sizeof (writtenlen ));
258320}
@@ -280,6 +342,7 @@ readtup_rum_internal(RumTuplesortstate *state, SortTuple *stup,
280342 Assert (tuplen == size );
281343
282344 USEMEM (state , GetMemoryChunkSpace (item ));
345+
283346#if PG_VERSION_NUM >= 150000
284347 LogicalTapeReadExact (LT_ARG , item , size );
285348#else
@@ -316,10 +379,6 @@ readtup_rumitem(RumTuplesortstate *state, SortTuple *stup, LT_TYPE LT_ARG,
316379 readtup_rum_internal (state , stup , LT_ARG , len , true);
317380}
318381
319- #if PG_VERSION_NUM >= 110000
320- #define tuplesort_begin_common (x ,y ) tuplesort_begin_common((x), NULL, (y))
321- #endif
322-
323382RumTuplesortstate *
324383rum_tuplesort_begin_rum (int workMem , int nKeys , bool randomAccess ,
325384 bool compareItemPointer )
@@ -336,12 +395,8 @@ rum_tuplesort_begin_rum(int workMem, int nKeys, bool randomAccess,
336395
337396 oldcontext = MemoryContextSwitchTo (TSS_GET (state )-> sortcontext );
338397
339- #ifdef TRACE_SORT
340- if (trace_sort )
341- elog (LOG ,
342- "begin rum sort: nKeys = %d, workMem = %d, randomAccess = %c" ,
398+ LOG_SORT ("begin rum sort: nKeys = %d, workMem = %d, randomAccess = %c" ,
343399 nKeys , workMem , randomAccess ? 't' : 'f' );
344- #endif
345400
346401 TSS_GET (state )-> nKeys = nKeys ;
347402 TSS_GET (state )-> comparetup = compareItemPointer ? comparetup_rum_true :
@@ -357,6 +412,23 @@ rum_tuplesort_begin_rum(int workMem, int nKeys, bool randomAccess,
357412RumTuplesortstate *
358413rum_tuplesort_begin_rumitem (int workMem , FmgrInfo * cmp )
359414{
415+ #if PG_VERSION_NUM >= 160000
416+ RumTuplesortstate * state = tuplesort_begin_common (workMem , false);
417+ MemoryContext oldcontext ;
418+
419+ oldcontext = MemoryContextSwitchTo (TSS_GET (state )-> sortcontext );
420+
421+ LOG_SORT ("begin rumitem sort: workMem = %d" , workMem );
422+
423+ TSS_GET (state )-> comparetup = comparetup_rumitem ;
424+ TSS_GET (state )-> writetup = writetup_rumitem ;
425+ TSS_GET (state )-> readtup = readtup_rumitem ;
426+ TSS_GET (state )-> arg = cmp ;
427+
428+ MemoryContextSwitchTo (oldcontext );
429+
430+ return state ;
431+ #else
360432 RumTuplesortstate * state = tuplesort_begin_common (workMem , false);
361433 RumTuplesortstateExt * rs ;
362434 MemoryContext oldcontext ;
@@ -366,11 +438,7 @@ rum_tuplesort_begin_rumitem(int workMem, FmgrInfo *cmp)
366438 /* Allocate extended state in the same context as state */
367439 rs = palloc (sizeof (* rs ));
368440
369- #ifdef TRACE_SORT
370- if (trace_sort )
371- elog (LOG ,
372- "begin rumitem sort: workMem = %d" , workMem );
373- #endif
441+ LOG_SORT ("begin rumitem sort: workMem = %d" , workMem );
374442
375443 rs -> cmp = cmp ;
376444 TSS_GET (state )-> comparetup = comparetup_rumitem ;
@@ -383,6 +451,7 @@ rum_tuplesort_begin_rumitem(int workMem, FmgrInfo *cmp)
383451 MemoryContextSwitchTo (oldcontext );
384452
385453 return (RumTuplesortstate * ) rs ;
454+ #endif
386455}
387456
388457/*
@@ -397,7 +466,7 @@ rum_tuplesort_begin_rumitem(int workMem, FmgrInfo *cmp)
397466void
398467rum_tuplesort_end (RumTuplesortstate * state )
399468{
400- #if PG_VERSION_NUM >= 130000
469+ #if PG_VERSION_NUM < 160000 && PG_VERSION_NUM >= 130000
401470 tuplesort_free (state );
402471#else
403472 tuplesort_end (state );
0 commit comments