@ -24,7 +24,9 @@
# include "access/itup.h"
# include "executor/tuptable.h"
# include "storage/dsm.h"
# include "utils/logtape.h"
# include "utils/relcache.h"
# include "utils/sortsupport.h"
/*
@ -102,6 +104,148 @@ typedef struct TuplesortInstrumentation
int64 spaceUsed ; /* space consumption, in kB */
} TuplesortInstrumentation ;
/*
* The objects we actually sort are SortTuple structs . These contain
* a pointer to the tuple proper ( might be a MinimalTuple or IndexTuple ) ,
* which is a separate palloc chunk - - - we assume it is just one chunk and
* can be freed by a simple pfree ( ) ( except during merge , when we use a
* simple slab allocator ) . SortTuples also contain the tuple ' s first key
* column in Datum / nullflag format , and a source / input tape number that
* tracks which tape each heap element / slot belongs to during merging .
*
* Storing the first key column lets us save heap_getattr or index_getattr
* calls during tuple comparisons . We could extract and save all the key
* columns not just the first , but this would increase code complexity and
* overhead , and wouldn ' t actually save any comparison cycles in the common
* case where the first key determines the comparison result . Note that
* for a pass - by - reference datatype , datum1 points into the " tuple " storage .
*
* There is one special case : when the sort support infrastructure provides an
* " abbreviated key " representation , where the key is ( typically ) a pass by
* value proxy for a pass by reference type . In this case , the abbreviated key
* is stored in datum1 in place of the actual first key column .
*
* When sorting single Datums , the data value is represented directly by
* datum1 / isnull1 for pass by value types ( or null values ) . If the datatype is
* pass - by - reference and isnull1 is false , then " tuple " points to a separately
* palloc ' d data value , otherwise " tuple " is NULL . The value of datum1 is then
* either the same pointer as " tuple " , or is an abbreviated key value as
* described above . Accordingly , " tuple " is always used in preference to
* datum1 as the authoritative value for pass - by - reference cases .
*/
typedef struct
{
void * tuple ; /* the tuple itself */
Datum datum1 ; /* value of first key column */
bool isnull1 ; /* is first key column NULL? */
int srctape ; /* source tape number */
} SortTuple ;
typedef int ( * SortTupleComparator ) ( const SortTuple * a , const SortTuple * b ,
Tuplesortstate * state ) ;
/*
* The public part of a Tuple sort operation state . This data structure
* containsthe definition of sort - variant - specific interface methods and
* the part of Tuple sort operation state required by their implementations .
*/
typedef struct
{
/*
* These function pointers decouple the routines that must know what kind
* of tuple we are sorting from the routines that don ' t need to know it .
* They are set up by the tuplesort_begin_xxx routines .
*
* Function to compare two tuples ; result is per qsort ( ) convention , ie :
* < 0 , 0 , > 0 according as a < b , a = b , a > b . The API must match
* qsort_arg_comparator .
*/
SortTupleComparator comparetup ;
/*
* Alter datum1 representation in the SortTuple ' s array back from the
* abbreviated key to the first column value .
*/
void ( * removeabbrev ) ( Tuplesortstate * state , SortTuple * stups ,
int count ) ;
/*
* Function to write a stored tuple onto tape . The representation of the
* tuple on tape need not be the same as it is in memory .
*/
void ( * writetup ) ( Tuplesortstate * state , LogicalTape * tape ,
SortTuple * stup ) ;
/*
* Function to read a stored tuple from tape back into memory . ' len ' is
* the already - read length of the stored tuple . The tuple is allocated
* from the slab memory arena , or is palloc ' d , see
* tuplesort_readtup_alloc ( ) .
*/
void ( * readtup ) ( Tuplesortstate * state , SortTuple * stup ,
LogicalTape * tape , unsigned int len ) ;
/*
* Function to do some specific release of resources for the sort variant .
* In particular , this function should free everything stored in the " arg "
* field , which wouldn ' t be cleared on reset of the Tuple sort memory
* contextes . This can be NULL if nothing specific needs to be done .
*/
void ( * freestate ) ( Tuplesortstate * state ) ;
/*
* The subsequent fields are used in the implementations of the functions
* above .
*/
MemoryContext maincontext ; /* memory context for tuple sort metadata that
* persists across multiple batches */
MemoryContext sortcontext ; /* memory context holding most sort data */
MemoryContext tuplecontext ; /* sub-context of sortcontext for tuple data */
/*
* Whether SortTuple ' s datum1 and isnull1 members are maintained by the
* above routines . If not , some sort specializations are disabled .
*/
bool haveDatum1 ;
/*
* The sortKeys variable is used by every case other than the hash index
* case ; it is set by tuplesort_begin_xxx . tupDesc is only used by the
* MinimalTuple and CLUSTER routines , though .
*/
int nKeys ; /* number of columns in sort key */
SortSupport sortKeys ; /* array of length nKeys */
/*
* This variable is shared by the single - key MinimalTuple case and the
* Datum case ( which both use qsort_ssup ( ) ) . Otherwise , it ' s NULL . The
* presence of a value in this field is also checked by various sort
* specialization functions as an optimization when comparing the leading
* key in a tiebreak situation to determine if there are any subsequent
* keys to sort on .
*/
SortSupport onlyKey ;
int sortopt ; /* Bitmask of flags used to setup sort */
bool tuples ; /* Can SortTuple.tuple ever be set? */
void * arg ; /* Specific information for the sort variant */
} TuplesortPublic ;
/* Sort parallel code from state for sort__start probes */
# define PARALLEL_SORT(coordinate) (coordinate == NULL || \
( coordinate ) - > sharedsort = = NULL ? 0 : \
( coordinate ) - > isWorker ? 1 : 2 )
# define TuplesortstateGetPublic(state) ((TuplesortPublic *) state)
/* When using this macro, beware of double evaluation of len */
# define LogicalTapeReadExact(tape, ptr, len) \
do { \
if ( LogicalTapeRead ( tape , ptr , len ) ! = ( size_t ) ( len ) ) \
elog ( ERROR , " unexpected end of data " ) ; \
} while ( 0 )
/*
* We provide multiple interfaces to what is essentially the same code ,
@ -205,6 +349,50 @@ typedef struct TuplesortInstrumentation
* generated ( typically , caller uses a parallel heap scan ) .
*/
extern Tuplesortstate * tuplesort_begin_common ( int workMem ,
SortCoordinate coordinate ,
int sortopt ) ;
extern void tuplesort_set_bound ( Tuplesortstate * state , int64 bound ) ;
extern bool tuplesort_used_bound ( Tuplesortstate * state ) ;
extern void tuplesort_puttuple_common ( Tuplesortstate * state ,
SortTuple * tuple , bool useAbbrev ) ;
extern void tuplesort_performsort ( Tuplesortstate * state ) ;
extern bool tuplesort_gettuple_common ( Tuplesortstate * state , bool forward ,
SortTuple * stup ) ;
extern bool tuplesort_skiptuples ( Tuplesortstate * state , int64 ntuples ,
bool forward ) ;
extern void tuplesort_end ( Tuplesortstate * state ) ;
extern void tuplesort_reset ( Tuplesortstate * state ) ;
extern void tuplesort_get_stats ( Tuplesortstate * state ,
TuplesortInstrumentation * stats ) ;
extern const char * tuplesort_method_name ( TuplesortMethod m ) ;
extern const char * tuplesort_space_type_name ( TuplesortSpaceType t ) ;
extern int tuplesort_merge_order ( int64 allowedMem ) ;
extern Size tuplesort_estimate_shared ( int nworkers ) ;
extern void tuplesort_initialize_shared ( Sharedsort * shared , int nWorkers ,
dsm_segment * seg ) ;
extern void tuplesort_attach_shared ( Sharedsort * shared , dsm_segment * seg ) ;
/*
* These routines may only be called if randomAccess was specified ' true ' .
* Likewise , backwards scan in gettuple / getdatum is only allowed if
* randomAccess was specified . Note that parallel sorts do not support
* randomAccess .
*/
extern void tuplesort_rescan ( Tuplesortstate * state ) ;
extern void tuplesort_markpos ( Tuplesortstate * state ) ;
extern void tuplesort_restorepos ( Tuplesortstate * state ) ;
extern void * tuplesort_readtup_alloc ( Tuplesortstate * state , Size tuplen ) ;
/* tuplesortvariants.c */
extern Tuplesortstate * tuplesort_begin_heap ( TupleDesc tupDesc ,
int nkeys , AttrNumber * attNums ,
Oid * sortOperators , Oid * sortCollations ,
@ -238,9 +426,6 @@ extern Tuplesortstate *tuplesort_begin_datum(Oid datumType,
int workMem , SortCoordinate coordinate ,
int sortopt ) ;
extern void tuplesort_set_bound ( Tuplesortstate * state , int64 bound ) ;
extern bool tuplesort_used_bound ( Tuplesortstate * state ) ;
extern void tuplesort_puttupleslot ( Tuplesortstate * state ,
TupleTableSlot * slot ) ;
extern void tuplesort_putheaptuple ( Tuplesortstate * state , HeapTuple tup ) ;
@ -250,8 +435,6 @@ extern void tuplesort_putindextuplevalues(Tuplesortstate *state,
extern void tuplesort_putdatum ( Tuplesortstate * state , Datum val ,
bool isNull ) ;
extern void tuplesort_performsort ( Tuplesortstate * state ) ;
extern bool tuplesort_gettupleslot ( Tuplesortstate * state , bool forward ,
bool copy , TupleTableSlot * slot , Datum * abbrev ) ;
extern HeapTuple tuplesort_getheaptuple ( Tuplesortstate * state , bool forward ) ;
@ -259,34 +442,5 @@ extern IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward);
extern bool tuplesort_getdatum ( Tuplesortstate * state , bool forward ,
Datum * val , bool * isNull , Datum * abbrev ) ;
extern bool tuplesort_skiptuples ( Tuplesortstate * state , int64 ntuples ,
bool forward ) ;
extern void tuplesort_end ( Tuplesortstate * state ) ;
extern void tuplesort_reset ( Tuplesortstate * state ) ;
extern void tuplesort_get_stats ( Tuplesortstate * state ,
TuplesortInstrumentation * stats ) ;
extern const char * tuplesort_method_name ( TuplesortMethod m ) ;
extern const char * tuplesort_space_type_name ( TuplesortSpaceType t ) ;
extern int tuplesort_merge_order ( int64 allowedMem ) ;
extern Size tuplesort_estimate_shared ( int nworkers ) ;
extern void tuplesort_initialize_shared ( Sharedsort * shared , int nWorkers ,
dsm_segment * seg ) ;
extern void tuplesort_attach_shared ( Sharedsort * shared , dsm_segment * seg ) ;
/*
* These routines may only be called if randomAccess was specified ' true ' .
* Likewise , backwards scan in gettuple / getdatum is only allowed if
* randomAccess was specified . Note that parallel sorts do not support
* randomAccess .
*/
extern void tuplesort_rescan ( Tuplesortstate * state ) ;
extern void tuplesort_markpos ( Tuplesortstate * state ) ;
extern void tuplesort_restorepos ( Tuplesortstate * state ) ;
# endif /* TUPLESORT_H */