From a8a7c9ec4f0b96ed9d889d008731864f3d4e87d1 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Sun, 3 Apr 2022 09:41:04 +1200 Subject: [PATCH] WIP: Fix tuplesort optimizations for expression-based CLUSTER. --- src/backend/utils/sort/tuplesort.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 361527098f..34714d9baf 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -268,6 +268,8 @@ struct Tuplesortstate MemoryContext tuplecontext; /* sub-context of sortcontext for tuple data */ LogicalTapeSet *tapeset; /* logtape.c object for tapes in a temp file */ + bool disable_datum1; /* disable leading value-based optimizations */ + /* * 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. @@ -1095,6 +1097,13 @@ tuplesort_begin_cluster(TupleDesc tupDesc, state->indexInfo = BuildIndexInfo(indexRel); + /* + * If we don't have a simple attribute, disable the use of datum1/isnull1. + * copytup_cluster() doesn't know how to compute expressions. + */ + if (state->indexInfo->ii_IndexAttrNumbers[0] == 0) + state->disable_datum1 = true; + state->tupDesc = tupDesc; /* assume we need not copy tupDesc */ indexScanKey = _bt_mkscankey(indexRel, NULL); @@ -3593,20 +3602,27 @@ tuplesort_sort_memtuples(Tuplesortstate *state) if (state->memtupcount > 1) { - /* Do we have a specialization for the leading column's comparator? */ + /* + * Do we have a specialization for the leading column's comparator, + * and has the leading column's value or abbreviation been stored in + * datum1/isnull1? + */ if (state->sortKeys && + !state->disable_datum1 && state->sortKeys[0].comparator == ssup_datum_unsigned_cmp) { elog(DEBUG1, "qsort_tuple_unsigned"); qsort_tuple_unsigned(state->memtuples, state->memtupcount, state); } else if (state->sortKeys && + !state->disable_datum1 && state->sortKeys[0].comparator == ssup_datum_signed_cmp) { elog(DEBUG1, "qsort_tuple_signed"); qsort_tuple_signed(state->memtuples, state->memtupcount, state); } else if (state->sortKeys && + !state->disable_datum1 && state->sortKeys[0].comparator == ssup_datum_int32_cmp) { elog(DEBUG1, "qsort_tuple_int32"); @@ -4134,7 +4150,7 @@ copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup) * set up first-column key value, and potentially abbreviate, if it's a * simple column */ - if (state->indexInfo->ii_IndexAttrNumbers[0] == 0) + if (state->disable_datum1) return; original = heap_getattr(tuple, -- 2.35.1