@@ -47,26 +47,36 @@ static void removeabbrev_datum(Tuplesortstate *state, SortTuple *stups,
47
47
int count );
48
48
static int comparetup_heap (const SortTuple * a ,const SortTuple * b ,
49
49
Tuplesortstate * state );
50
+ static int comparetup_heap_tiebreak (const SortTuple * a ,const SortTuple * b ,
51
+ Tuplesortstate * state );
50
52
static void writetup_heap (Tuplesortstate * state ,LogicalTape * tape ,
51
53
SortTuple * stup );
52
54
static void readtup_heap (Tuplesortstate * state ,SortTuple * stup ,
53
55
LogicalTape * tape ,unsignedint len );
54
56
static int comparetup_cluster (const SortTuple * a ,const SortTuple * b ,
55
57
Tuplesortstate * state );
58
+ static int comparetup_cluster_tiebreak (const SortTuple * a ,const SortTuple * b ,
59
+ Tuplesortstate * state );
56
60
static void writetup_cluster (Tuplesortstate * state ,LogicalTape * tape ,
57
61
SortTuple * stup );
58
62
static void readtup_cluster (Tuplesortstate * state ,SortTuple * stup ,
59
63
LogicalTape * tape ,unsignedint tuplen );
60
64
static int comparetup_index_btree (const SortTuple * a ,const SortTuple * b ,
61
65
Tuplesortstate * state );
66
+ static int comparetup_index_btree_tiebreak (const SortTuple * a ,const SortTuple * b ,
67
+ Tuplesortstate * state );
62
68
static int comparetup_index_hash (const SortTuple * a ,const SortTuple * b ,
63
69
Tuplesortstate * state );
70
+ static int comparetup_index_hash_tiebreak (const SortTuple * a ,const SortTuple * b ,
71
+ Tuplesortstate * state );
64
72
static void writetup_index (Tuplesortstate * state ,LogicalTape * tape ,
65
73
SortTuple * stup );
66
74
static void readtup_index (Tuplesortstate * state ,SortTuple * stup ,
67
75
LogicalTape * tape ,unsignedint len );
68
76
static int comparetup_datum (const SortTuple * a ,const SortTuple * b ,
69
77
Tuplesortstate * state );
78
+ static int comparetup_datum_tiebreak (const SortTuple * a ,const SortTuple * b ,
79
+ Tuplesortstate * state );
70
80
static void writetup_datum (Tuplesortstate * state ,LogicalTape * tape ,
71
81
SortTuple * stup );
72
82
static void readtup_datum (Tuplesortstate * state ,SortTuple * stup ,
@@ -165,6 +175,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
165
175
166
176
base -> removeabbrev = removeabbrev_heap ;
167
177
base -> comparetup = comparetup_heap ;
178
+ base -> comparetup_tiebreak = comparetup_heap_tiebreak ;
168
179
base -> writetup = writetup_heap ;
169
180
base -> readtup = readtup_heap ;
170
181
base -> haveDatum1 = true;
@@ -242,6 +253,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
242
253
243
254
base -> removeabbrev = removeabbrev_cluster ;
244
255
base -> comparetup = comparetup_cluster ;
256
+ base -> comparetup_tiebreak = comparetup_cluster_tiebreak ;
245
257
base -> writetup = writetup_cluster ;
246
258
base -> readtup = readtup_cluster ;
247
259
base -> freestate = freestate_cluster ;
@@ -351,6 +363,7 @@ tuplesort_begin_index_btree(Relation heapRel,
351
363
352
364
base -> removeabbrev = removeabbrev_index ;
353
365
base -> comparetup = comparetup_index_btree ;
366
+ base -> comparetup_tiebreak = comparetup_index_btree_tiebreak ;
354
367
base -> writetup = writetup_index ;
355
368
base -> readtup = readtup_index ;
356
369
base -> haveDatum1 = true;
@@ -431,6 +444,7 @@ tuplesort_begin_index_hash(Relation heapRel,
431
444
432
445
base -> removeabbrev = removeabbrev_index ;
433
446
base -> comparetup = comparetup_index_hash ;
447
+ base -> comparetup_tiebreak = comparetup_index_hash_tiebreak ;
434
448
base -> writetup = writetup_index ;
435
449
base -> readtup = readtup_index ;
436
450
base -> haveDatum1 = true;
@@ -476,6 +490,7 @@ tuplesort_begin_index_gist(Relation heapRel,
476
490
477
491
base -> removeabbrev = removeabbrev_index ;
478
492
base -> comparetup = comparetup_index_btree ;
493
+ base -> comparetup_tiebreak = comparetup_index_btree_tiebreak ;
479
494
base -> writetup = writetup_index ;
480
495
base -> readtup = readtup_index ;
481
496
base -> haveDatum1 = true;
@@ -546,6 +561,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
546
561
547
562
base -> removeabbrev = removeabbrev_datum ;
548
563
base -> comparetup = comparetup_datum ;
564
+ base -> comparetup_tiebreak = comparetup_datum_tiebreak ;
549
565
base -> writetup = writetup_datum ;
550
566
base -> readtup = readtup_datum ;
551
567
base -> haveDatum1 = true;
@@ -931,16 +947,7 @@ comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
931
947
{
932
948
TuplesortPublic * base = TuplesortstateGetPublic (state );
933
949
SortSupport sortKey = base -> sortKeys ;
934
- HeapTupleData ltup ;
935
- HeapTupleData rtup ;
936
- TupleDesc tupDesc ;
937
- int nkey ;
938
950
int32 compare ;
939
- AttrNumber attno ;
940
- Datum datum1 ,
941
- datum2 ;
942
- bool isnull1 ,
943
- isnull2 ;
944
951
945
952
946
953
/* Compare the leading sort key */
@@ -951,6 +958,25 @@ comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
951
958
return compare ;
952
959
953
960
/* 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
+
954
980
ltup .t_len = ((MinimalTuple )a -> tuple )-> t_len + MINIMAL_TUPLE_OFFSET ;
955
981
ltup .t_data = (HeapTupleHeader ) ((char * )a -> tuple - MINIMAL_TUPLE_OFFSET );
956
982
rtup .t_len = ((MinimalTuple )b -> tuple )-> t_len + MINIMAL_TUPLE_OFFSET ;
@@ -1061,6 +1087,27 @@ removeabbrev_cluster(Tuplesortstate *state, SortTuple *stups, int count)
1061
1087
static int
1062
1088
comparetup_cluster (const SortTuple * a ,const SortTuple * b ,
1063
1089
Tuplesortstate * 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 )
1064
1111
{
1065
1112
TuplesortPublic * base = TuplesortstateGetPublic (state );
1066
1113
TuplesortClusterArg * arg = (TuplesortClusterArg * )base -> arg ;
@@ -1069,26 +1116,19 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
1069
1116
HeapTuple rtup ;
1070
1117
TupleDesc tupDesc ;
1071
1118
int nkey ;
1072
- int32 compare ;
1119
+ int32 compare = 0 ;
1073
1120
Datum datum1 ,
1074
1121
datum2 ;
1075
1122
bool isnull1 ,
1076
1123
isnull2 ;
1077
1124
1078
- /* Be prepared to compare additional sort keys */
1079
1125
ltup = (HeapTuple )a -> tuple ;
1080
1126
rtup = (HeapTuple )b -> tuple ;
1081
1127
tupDesc = arg -> tupDesc ;
1082
1128
1083
1129
/* Compare the leading sort key, if it's simple */
1084
1130
if (base -> haveDatum1 )
1085
1131
{
1086
- compare = ApplySortComparator (a -> datum1 ,a -> isnull1 ,
1087
- b -> datum1 ,b -> isnull1 ,
1088
- sortKey );
1089
- if (compare != 0 )
1090
- return compare ;
1091
-
1092
1132
if (sortKey -> abbrev_converter )
1093
1133
{
1094
1134
AttrNumber leading = arg -> indexInfo -> ii_IndexAttrNumbers [0 ];
@@ -1269,6 +1309,25 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b,
1269
1309
* treatment for equal keys at the end.
1270
1310
*/
1271
1311
TuplesortPublic * 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 );
1272
1331
TuplesortIndexBTreeArg * arg = (TuplesortIndexBTreeArg * )base -> arg ;
1273
1332
SortSupport sortKey = base -> sortKeys ;
1274
1333
IndexTuple tuple1 ;
@@ -1283,15 +1342,6 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b,
1283
1342
bool isnull1 ,
1284
1343
isnull2 ;
1285
1344
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 */
1295
1345
tuple1 = (IndexTuple )a -> tuple ;
1296
1346
tuple2 = (IndexTuple )b -> tuple ;
1297
1347
keysz = base -> nKeys ;
@@ -1467,6 +1517,19 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b,
1467
1517
return 0 ;
1468
1518
}
1469
1519
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
+
1470
1533
static void
1471
1534
writetup_index (Tuplesortstate * state ,LogicalTape * tape ,SortTuple * stup )
1472
1535
{
@@ -1526,8 +1589,16 @@ comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
1526
1589
if (compare != 0 )
1527
1590
return compare ;
1528
1591
1529
- /* if we have abbreviations, then "tuple" has the original value */
1592
+ return comparetup_datum_tiebreak (a ,b ,state );
1593
+ }
1530
1594
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 */
1531
1602
if (base -> sortKeys -> abbrev_converter )
1532
1603
compare = ApplySortAbbrevFullComparator (PointerGetDatum (a -> tuple ),a -> isnull1 ,
1533
1604
PointerGetDatum (b -> tuple ),b -> isnull1 ,