diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 8340a66052..cc7c996718 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -182,8 +182,8 @@ 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 */ + bool isnull1; /* is first key column NULL? */ } SortTuple; /* @@ -695,7 +695,7 @@ static void tuplesort_updatemax(Tuplesortstate *state); /* Used if first key's comparator is ssup_datum_unsigned_compare */ static pg_attribute_always_inline int -qsort_tuple_unsigned_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state) +qsort_tuple_unsigned_compare(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) { int compare; @@ -718,7 +718,7 @@ qsort_tuple_unsigned_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state) #if SIZEOF_DATUM >= 8 /* Used if first key's comparator is ssup_datum_signed_compare */ static pg_attribute_always_inline int -qsort_tuple_signed_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state) +qsort_tuple_signed_compare(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) { int compare; @@ -742,7 +742,7 @@ qsort_tuple_signed_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state) /* Used if first key's comparator is ssup_datum_int32_compare */ static pg_attribute_always_inline int -qsort_tuple_int32_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state) +qsort_tuple_int32_compare(const SortTuple *a, const SortTuple *b, Tuplesortstate *state) { int compare; @@ -972,10 +972,13 @@ tuplesort_begin_batch(Tuplesortstate *state) * generation.c context as this keeps allocations more compact with less * wastage. Allocations are also slightly more CPU efficient. */ - if (state->sortopt & TUPLESORT_ALLOWBOUNDED) + if (state->sortopt & TUPLESORT_ALLOWBOUNDED || + (state->memtupsize & (state->memtupsize - 1)) == 0) + { state->tuplecontext = AllocSetContextCreate(state->sortcontext, "Caller tuples", ALLOCSET_DEFAULT_SIZES); + } else state->tuplecontext = GenerationContextCreate(state->sortcontext, "Caller tuples", @@ -4360,7 +4363,6 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b, /* Compare additional sort keys */ tuple1 = (IndexTuple) a->tuple; tuple2 = (IndexTuple) b->tuple; - keysz = state->nKeys; tupDes = RelationGetDescr(state->indexRel); if (sortKey->abbrev_converter) @@ -4380,6 +4382,7 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b, equal_hasnull = true; sortKey++; + keysz = state->nKeys; for (nkey = 2; nkey <= keysz; nkey++, sortKey++) { datum1 = index_getattr(tuple1, nkey, tupDes, &isnull1); @@ -4444,15 +4447,19 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b, BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid); BlockNumber blk2 = ItemPointerGetBlockNumber(&tuple2->t_tid); - if (blk1 != blk2) - return (blk1 < blk2) ? -1 : 1; + if (blk1 < blk2) + return -1; + else if (blk1 > blk2) + return 1; } { OffsetNumber pos1 = ItemPointerGetOffsetNumber(&tuple1->t_tid); OffsetNumber pos2 = ItemPointerGetOffsetNumber(&tuple2->t_tid); - if (pos1 != pos2) - return (pos1 < pos2) ? -1 : 1; + if (pos1 < pos2) + return -1; + else if (pos1 > pos2) + return 1; } /* ItemPointer values should never be equal */ @@ -4499,15 +4506,19 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b, BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid); BlockNumber blk2 = ItemPointerGetBlockNumber(&tuple2->t_tid); - if (blk1 != blk2) - return (blk1 < blk2) ? -1 : 1; + if (blk1 < blk2) + return -1; + else if (blk1 > blk2) + return 1; } { OffsetNumber pos1 = ItemPointerGetOffsetNumber(&tuple1->t_tid); OffsetNumber pos2 = ItemPointerGetOffsetNumber(&tuple2->t_tid); - if (pos1 != pos2) - return (pos1 < pos2) ? -1 : 1; + if (pos1 < pos2) + return -1; + else if (pos1 > pos2) + return 1; } /* ItemPointer values should never be equal */ @@ -4642,25 +4653,25 @@ readtup_datum(Tuplesortstate *state, SortTuple *stup, if (tuplen == 0) { /* it's NULL */ + stup->tuple = NULL; stup->datum1 = (Datum) 0; stup->isnull1 = true; - stup->tuple = NULL; } else if (!state->tuples) { Assert(tuplen == sizeof(Datum)); + stup->tuple = NULL; LogicalTapeReadExact(tape, &stup->datum1, tuplen); stup->isnull1 = false; - stup->tuple = NULL; } else { void *raddr = readtup_alloc(state, tuplen); LogicalTapeReadExact(tape, raddr, tuplen); + stup->tuple = raddr; stup->datum1 = PointerGetDatum(raddr); stup->isnull1 = false; - stup->tuple = raddr; } if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length diff --git a/src/include/lib/sort_template.h b/src/include/lib/sort_template.h index 3122a93009..86ac216172 100644 --- a/src/include/lib/sort_template.h +++ b/src/include/lib/sort_template.h @@ -309,12 +309,12 @@ loop: for (pm = a + ST_POINTER_STEP; pm < a + n * ST_POINTER_STEP; pm += ST_POINTER_STEP) { - DO_CHECK_FOR_INTERRUPTS(); if (DO_COMPARE(pm - ST_POINTER_STEP, pm) > 0) { presorted = 0; break; } + DO_CHECK_FOR_INTERRUPTS(); } if (presorted) return;