@@ -47,26 +47,36 @@ static void removeabbrev_datum(Tuplesortstate *state, SortTuple *stups,
4747int count );
4848static int comparetup_heap (const SortTuple * a ,const SortTuple * b ,
4949Tuplesortstate * state );
50+ static int comparetup_heap_tiebreak (const SortTuple * a ,const SortTuple * b ,
51+ Tuplesortstate * state );
5052static void writetup_heap (Tuplesortstate * state ,LogicalTape * tape ,
5153SortTuple * stup );
5254static void readtup_heap (Tuplesortstate * state ,SortTuple * stup ,
5355LogicalTape * tape ,unsignedint len );
5456static int comparetup_cluster (const SortTuple * a ,const SortTuple * b ,
5557Tuplesortstate * state );
58+ static int comparetup_cluster_tiebreak (const SortTuple * a ,const SortTuple * b ,
59+ Tuplesortstate * state );
5660static void writetup_cluster (Tuplesortstate * state ,LogicalTape * tape ,
5761SortTuple * stup );
5862static void readtup_cluster (Tuplesortstate * state ,SortTuple * stup ,
5963LogicalTape * tape ,unsignedint tuplen );
6064static int comparetup_index_btree (const SortTuple * a ,const SortTuple * b ,
6165Tuplesortstate * state );
66+ static int comparetup_index_btree_tiebreak (const SortTuple * a ,const SortTuple * b ,
67+ Tuplesortstate * state );
6268static int comparetup_index_hash (const SortTuple * a ,const SortTuple * b ,
6369Tuplesortstate * state );
70+ static int comparetup_index_hash_tiebreak (const SortTuple * a ,const SortTuple * b ,
71+ Tuplesortstate * state );
6472static void writetup_index (Tuplesortstate * state ,LogicalTape * tape ,
6573SortTuple * stup );
6674static void readtup_index (Tuplesortstate * state ,SortTuple * stup ,
6775LogicalTape * tape ,unsignedint len );
6876static int comparetup_datum (const SortTuple * a ,const SortTuple * b ,
6977Tuplesortstate * state );
78+ static int comparetup_datum_tiebreak (const SortTuple * a ,const SortTuple * b ,
79+ Tuplesortstate * state );
7080static void writetup_datum (Tuplesortstate * state ,LogicalTape * tape ,
7181SortTuple * stup );
7282static void readtup_datum (Tuplesortstate * state ,SortTuple * stup ,
@@ -165,6 +175,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
165175
166176base -> removeabbrev = removeabbrev_heap ;
167177base -> comparetup = comparetup_heap ;
178+ base -> comparetup_tiebreak = comparetup_heap_tiebreak ;
168179base -> writetup = writetup_heap ;
169180base -> readtup = readtup_heap ;
170181base -> haveDatum1 = true;
@@ -242,6 +253,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
242253
243254base -> removeabbrev = removeabbrev_cluster ;
244255base -> comparetup = comparetup_cluster ;
256+ base -> comparetup_tiebreak = comparetup_cluster_tiebreak ;
245257base -> writetup = writetup_cluster ;
246258base -> readtup = readtup_cluster ;
247259base -> freestate = freestate_cluster ;
@@ -351,6 +363,7 @@ tuplesort_begin_index_btree(Relation heapRel,
351363
352364base -> removeabbrev = removeabbrev_index ;
353365base -> comparetup = comparetup_index_btree ;
366+ base -> comparetup_tiebreak = comparetup_index_btree_tiebreak ;
354367base -> writetup = writetup_index ;
355368base -> readtup = readtup_index ;
356369base -> haveDatum1 = true;
@@ -431,6 +444,7 @@ tuplesort_begin_index_hash(Relation heapRel,
431444
432445base -> removeabbrev = removeabbrev_index ;
433446base -> comparetup = comparetup_index_hash ;
447+ base -> comparetup_tiebreak = comparetup_index_hash_tiebreak ;
434448base -> writetup = writetup_index ;
435449base -> readtup = readtup_index ;
436450base -> haveDatum1 = true;
@@ -476,6 +490,7 @@ tuplesort_begin_index_gist(Relation heapRel,
476490
477491base -> removeabbrev = removeabbrev_index ;
478492base -> comparetup = comparetup_index_btree ;
493+ base -> comparetup_tiebreak = comparetup_index_btree_tiebreak ;
479494base -> writetup = writetup_index ;
480495base -> readtup = readtup_index ;
481496base -> haveDatum1 = true;
@@ -546,6 +561,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
546561
547562base -> removeabbrev = removeabbrev_datum ;
548563base -> comparetup = comparetup_datum ;
564+ base -> comparetup_tiebreak = comparetup_datum_tiebreak ;
549565base -> writetup = writetup_datum ;
550566base -> readtup = readtup_datum ;
551567base -> haveDatum1 = true;
@@ -931,16 +947,7 @@ comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
931947{
932948TuplesortPublic * base = TuplesortstateGetPublic (state );
933949SortSupport sortKey = base -> sortKeys ;
934- HeapTupleData ltup ;
935- HeapTupleData rtup ;
936- TupleDesc tupDesc ;
937- int nkey ;
938950int32 compare ;
939- AttrNumber attno ;
940- Datum datum1 ,
941- datum2 ;
942- bool isnull1 ,
943- isnull2 ;
944951
945952
946953/* Compare the leading sort key */
@@ -951,6 +958,25 @@ comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
951958return compare ;
952959
953960/* Compare additional sort keys */
961+ return comparetup_heap_tiebreak (a ,b ,state );
962+ }
963+
964+ static int
965+ comparetup_heap_tiebreak (const SortTuple * a ,const SortTuple * b ,Tuplesortstate * state )
966+ {
967+ TuplesortPublic * base = TuplesortstateGetPublic (state );
968+ SortSupport sortKey = base -> sortKeys ;
969+ HeapTupleData ltup ;
970+ HeapTupleData rtup ;
971+ TupleDesc tupDesc ;
972+ int nkey ;
973+ int32 compare ;
974+ AttrNumber attno ;
975+ Datum datum1 ,
976+ datum2 ;
977+ bool isnull1 ,
978+ isnull2 ;
979+
954980ltup .t_len = ((MinimalTuple )a -> tuple )-> t_len + MINIMAL_TUPLE_OFFSET ;
955981ltup .t_data = (HeapTupleHeader ) ((char * )a -> tuple - MINIMAL_TUPLE_OFFSET );
956982rtup .t_len = ((MinimalTuple )b -> tuple )-> t_len + MINIMAL_TUPLE_OFFSET ;
@@ -1061,6 +1087,27 @@ removeabbrev_cluster(Tuplesortstate *state, SortTuple *stups, int count)
10611087static int
10621088comparetup_cluster (const SortTuple * a ,const SortTuple * b ,
10631089Tuplesortstate * state )
1090+ {
1091+ TuplesortPublic * base = TuplesortstateGetPublic (state );
1092+ SortSupport sortKey = base -> sortKeys ;
1093+ int32 compare ;
1094+
1095+ /* Compare the leading sort key, if it's simple */
1096+ if (base -> haveDatum1 )
1097+ {
1098+ compare = ApplySortComparator (a -> datum1 ,a -> isnull1 ,
1099+ b -> datum1 ,b -> isnull1 ,
1100+ sortKey );
1101+ if (compare != 0 )
1102+ return compare ;
1103+ }
1104+
1105+ return comparetup_cluster_tiebreak (a ,b ,state );
1106+ }
1107+
1108+ static int
1109+ comparetup_cluster_tiebreak (const SortTuple * a ,const SortTuple * b ,
1110+ Tuplesortstate * state )
10641111{
10651112TuplesortPublic * base = TuplesortstateGetPublic (state );
10661113TuplesortClusterArg * arg = (TuplesortClusterArg * )base -> arg ;
@@ -1069,26 +1116,19 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
10691116HeapTuple rtup ;
10701117TupleDesc tupDesc ;
10711118int nkey ;
1072- int32 compare ;
1119+ int32 compare = 0 ;
10731120Datum datum1 ,
10741121datum2 ;
10751122bool isnull1 ,
10761123isnull2 ;
10771124
1078- /* Be prepared to compare additional sort keys */
10791125ltup = (HeapTuple )a -> tuple ;
10801126rtup = (HeapTuple )b -> tuple ;
10811127tupDesc = arg -> tupDesc ;
10821128
10831129/* Compare the leading sort key, if it's simple */
10841130if (base -> haveDatum1 )
10851131{
1086- compare = ApplySortComparator (a -> datum1 ,a -> isnull1 ,
1087- b -> datum1 ,b -> isnull1 ,
1088- sortKey );
1089- if (compare != 0 )
1090- return compare ;
1091-
10921132if (sortKey -> abbrev_converter )
10931133{
10941134AttrNumber leading = arg -> indexInfo -> ii_IndexAttrNumbers [0 ];
@@ -1269,6 +1309,25 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b,
12691309 * treatment for equal keys at the end.
12701310 */
12711311TuplesortPublic * base = TuplesortstateGetPublic (state );
1312+ SortSupport sortKey = base -> sortKeys ;
1313+ int32 compare ;
1314+
1315+ /* Compare the leading sort key */
1316+ compare = ApplySortComparator (a -> datum1 ,a -> isnull1 ,
1317+ b -> datum1 ,b -> isnull1 ,
1318+ sortKey );
1319+ if (compare != 0 )
1320+ return compare ;
1321+
1322+ /* Compare additional sort keys */
1323+ return comparetup_index_btree_tiebreak (a ,b ,state );
1324+ }
1325+
1326+ static int
1327+ comparetup_index_btree_tiebreak (const SortTuple * a ,const SortTuple * b ,
1328+ Tuplesortstate * state )
1329+ {
1330+ TuplesortPublic * base = TuplesortstateGetPublic (state );
12721331TuplesortIndexBTreeArg * arg = (TuplesortIndexBTreeArg * )base -> arg ;
12731332SortSupport sortKey = base -> sortKeys ;
12741333IndexTuple tuple1 ;
@@ -1283,15 +1342,6 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b,
12831342bool isnull1 ,
12841343isnull2 ;
12851344
1286-
1287- /* Compare the leading sort key */
1288- compare = ApplySortComparator (a -> datum1 ,a -> isnull1 ,
1289- b -> datum1 ,b -> isnull1 ,
1290- sortKey );
1291- if (compare != 0 )
1292- return compare ;
1293-
1294- /* Compare additional sort keys */
12951345tuple1 = (IndexTuple )a -> tuple ;
12961346tuple2 = (IndexTuple )b -> tuple ;
12971347keysz = base -> nKeys ;
@@ -1467,6 +1517,19 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b,
14671517return 0 ;
14681518}
14691519
1520+ /*
1521+ * Sorting for hash indexes only uses one sort key, so this shouldn't ever be
1522+ * called. It's only here for consistency.
1523+ */
1524+ static int
1525+ comparetup_index_hash_tiebreak (const SortTuple * a ,const SortTuple * b ,
1526+ Tuplesortstate * state )
1527+ {
1528+ Assert (false);
1529+
1530+ return 0 ;
1531+ }
1532+
14701533static void
14711534writetup_index (Tuplesortstate * state ,LogicalTape * tape ,SortTuple * stup )
14721535{
@@ -1526,8 +1589,16 @@ comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
15261589if (compare != 0 )
15271590return compare ;
15281591
1529- /* if we have abbreviations, then "tuple" has the original value */
1592+ return comparetup_datum_tiebreak (a ,b ,state );
1593+ }
15301594
1595+ static int
1596+ comparetup_datum_tiebreak (const SortTuple * a ,const SortTuple * b ,Tuplesortstate * state )
1597+ {
1598+ TuplesortPublic * base = TuplesortstateGetPublic (state );
1599+ int32 compare = 0 ;
1600+
1601+ /* if we have abbreviations, then "tuple" has the original value */
15311602if (base -> sortKeys -> abbrev_converter )
15321603compare = ApplySortAbbrevFullComparator (PointerGetDatum (a -> tuple ),a -> isnull1 ,
15331604PointerGetDatum (b -> tuple ),b -> isnull1 ,