@@ -306,6 +306,12 @@ struct Tuplesortstate
306
306
void (* readtup ) (Tuplesortstate * state , SortTuple * stup ,
307
307
LogicalTape * tape , unsigned int len );
308
308
309
+ /*
310
+ * Whether SortTuple's datum1 and isnull1 members are maintained by the
311
+ * above routines. If not, some sort specializations are disabled.
312
+ */
313
+ bool haveDatum1 ;
314
+
309
315
/*
310
316
* This array holds the tuples now in sort memory. If we are in state
311
317
* INITIAL, the tuples are in no particular order; if we are in state
@@ -1016,6 +1022,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
1016
1022
state -> copytup = copytup_heap ;
1017
1023
state -> writetup = writetup_heap ;
1018
1024
state -> readtup = readtup_heap ;
1025
+ state -> haveDatum1 = true;
1019
1026
1020
1027
state -> tupDesc = tupDesc ; /* assume we need not copy tupDesc */
1021
1028
state -> abbrevNext = 10 ;
@@ -1095,6 +1102,15 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
1095
1102
1096
1103
state -> indexInfo = BuildIndexInfo (indexRel );
1097
1104
1105
+ /*
1106
+ * If we don't have a simple leading attribute, we don't currently
1107
+ * initialize datum1, so disable optimizations that require it.
1108
+ */
1109
+ if (state -> indexInfo -> ii_IndexAttrNumbers [0 ] == 0 )
1110
+ state -> haveDatum1 = false;
1111
+ else
1112
+ state -> haveDatum1 = true;
1113
+
1098
1114
state -> tupDesc = tupDesc ; /* assume we need not copy tupDesc */
1099
1115
1100
1116
indexScanKey = _bt_mkscankey (indexRel , NULL );
@@ -1188,6 +1204,7 @@ tuplesort_begin_index_btree(Relation heapRel,
1188
1204
state -> writetup = writetup_index ;
1189
1205
state -> readtup = readtup_index ;
1190
1206
state -> abbrevNext = 10 ;
1207
+ state -> haveDatum1 = true;
1191
1208
1192
1209
state -> heapRel = heapRel ;
1193
1210
state -> indexRel = indexRel ;
@@ -1262,6 +1279,7 @@ tuplesort_begin_index_hash(Relation heapRel,
1262
1279
state -> copytup = copytup_index ;
1263
1280
state -> writetup = writetup_index ;
1264
1281
state -> readtup = readtup_index ;
1282
+ state -> haveDatum1 = true;
1265
1283
1266
1284
state -> heapRel = heapRel ;
1267
1285
state -> indexRel = indexRel ;
@@ -1302,6 +1320,7 @@ tuplesort_begin_index_gist(Relation heapRel,
1302
1320
state -> copytup = copytup_index ;
1303
1321
state -> writetup = writetup_index ;
1304
1322
state -> readtup = readtup_index ;
1323
+ state -> haveDatum1 = true;
1305
1324
1306
1325
state -> heapRel = heapRel ;
1307
1326
state -> indexRel = indexRel ;
@@ -1366,6 +1385,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
1366
1385
state -> writetup = writetup_datum ;
1367
1386
state -> readtup = readtup_datum ;
1368
1387
state -> abbrevNext = 10 ;
1388
+ state -> haveDatum1 = true;
1369
1389
1370
1390
state -> datumType = datumType ;
1371
1391
@@ -3593,27 +3613,40 @@ tuplesort_sort_memtuples(Tuplesortstate *state)
3593
3613
3594
3614
if (state -> memtupcount > 1 )
3595
3615
{
3596
- /* Do we have a specialization for the leading column's comparator? */
3597
- if (state -> sortKeys &&
3598
- state -> sortKeys [0 ].comparator == ssup_datum_unsigned_cmp )
3599
- {
3600
- elog (DEBUG1 , "qsort_tuple_unsigned" );
3601
- qsort_tuple_unsigned (state -> memtuples , state -> memtupcount , state );
3602
- }
3603
- else if (state -> sortKeys &&
3604
- state -> sortKeys [0 ].comparator == ssup_datum_signed_cmp )
3605
- {
3606
- elog (DEBUG1 , "qsort_tuple_signed" );
3607
- qsort_tuple_signed (state -> memtuples , state -> memtupcount , state );
3608
- }
3609
- else if (state -> sortKeys &&
3610
- state -> sortKeys [0 ].comparator == ssup_datum_int32_cmp )
3616
+ /*
3617
+ * Do we have the leading column's value or abbreviation in datum1,
3618
+ * and is there a specialization for its comparator?
3619
+ */
3620
+ if (state -> haveDatum1 && state -> sortKeys )
3611
3621
{
3612
- elog (DEBUG1 , "qsort_tuple_int32" );
3613
- qsort_tuple_int32 (state -> memtuples , state -> memtupcount , state );
3622
+ if (state -> sortKeys [0 ].comparator == ssup_datum_unsigned_cmp )
3623
+ {
3624
+ elog (DEBUG1 , "qsort_tuple_unsigned" );
3625
+ qsort_tuple_unsigned (state -> memtuples ,
3626
+ state -> memtupcount ,
3627
+ state );
3628
+ return ;
3629
+ }
3630
+ else if (state -> sortKeys [0 ].comparator == ssup_datum_signed_cmp )
3631
+ {
3632
+ elog (DEBUG1 , "qsort_tuple_signed" );
3633
+ qsort_tuple_signed (state -> memtuples ,
3634
+ state -> memtupcount ,
3635
+ state );
3636
+ return ;
3637
+ }
3638
+ else if (state -> sortKeys [0 ].comparator == ssup_datum_int32_cmp )
3639
+ {
3640
+ elog (DEBUG1 , "qsort_tuple_int32" );
3641
+ qsort_tuple_int32 (state -> memtuples ,
3642
+ state -> memtupcount ,
3643
+ state );
3644
+ return ;
3645
+ }
3614
3646
}
3647
+
3615
3648
/* Can we use the single-key sort function? */
3616
- else if (state -> onlyKey != NULL )
3649
+ if (state -> onlyKey != NULL )
3617
3650
{
3618
3651
elog (DEBUG1 , "qsort_ssup" );
3619
3652
qsort_ssup (state -> memtuples , state -> memtupcount ,
@@ -4019,15 +4052,14 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
4019
4052
datum2 ;
4020
4053
bool isnull1 ,
4021
4054
isnull2 ;
4022
- AttrNumber leading = state -> indexInfo -> ii_IndexAttrNumbers [0 ];
4023
4055
4024
4056
/* Be prepared to compare additional sort keys */
4025
4057
ltup = (HeapTuple ) a -> tuple ;
4026
4058
rtup = (HeapTuple ) b -> tuple ;
4027
4059
tupDesc = state -> tupDesc ;
4028
4060
4029
4061
/* Compare the leading sort key, if it's simple */
4030
- if (leading != 0 )
4062
+ if (state -> haveDatum1 )
4031
4063
{
4032
4064
compare = ApplySortComparator (a -> datum1 , a -> isnull1 ,
4033
4065
b -> datum1 , b -> isnull1 ,
@@ -4037,6 +4069,8 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
4037
4069
4038
4070
if (sortKey -> abbrev_converter )
4039
4071
{
4072
+ AttrNumber leading = state -> indexInfo -> ii_IndexAttrNumbers [0 ];
4073
+
4040
4074
datum1 = heap_getattr (ltup , leading , tupDesc , & isnull1 );
4041
4075
datum2 = heap_getattr (rtup , leading , tupDesc , & isnull2 );
4042
4076
@@ -4134,7 +4168,7 @@ copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup)
4134
4168
* set up first-column key value, and potentially abbreviate, if it's a
4135
4169
* simple column
4136
4170
*/
4137
- if (state -> indexInfo -> ii_IndexAttrNumbers [ 0 ] == 0 )
4171
+ if (! state -> haveDatum1 )
4138
4172
return ;
4139
4173
4140
4174
original = heap_getattr (tuple ,
@@ -4229,7 +4263,7 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup,
4229
4263
LogicalTapeReadExact (tape , & tuplen , sizeof (tuplen ));
4230
4264
stup -> tuple = (void * ) tuple ;
4231
4265
/* set up first-column key value, if it's a simple column */
4232
- if (state -> indexInfo -> ii_IndexAttrNumbers [ 0 ] != 0 )
4266
+ if (state -> haveDatum1 )
4233
4267
stup -> datum1 = heap_getattr (tuple ,
4234
4268
state -> indexInfo -> ii_IndexAttrNumbers [0 ],
4235
4269
state -> tupDesc ,
0 commit comments