From 6000b9cafe4b648ebc4906d4a552e41acde9348a Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 23 Oct 2026 07:36:30 -0400 Subject: [PATCH v1 2/2] Add debug_topn_quickselect GUC (for testing, not for commit) Setting it to off makes bounded sorts use the heap as before, so the two methods can be compared on one server without a rebuild. --- src/backend/utils/misc/guc_parameters.dat | 7 +++++++ src/backend/utils/sort/tuplesort.c | 3 ++- src/include/utils/guc.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat index 380679a76c0..756d19a6680 100644 --- a/src/backend/utils/misc/guc_parameters.dat +++ b/src/backend/utils/misc/guc_parameters.dat @@ -731,6 +731,13 @@ ifdef => 'DEBUG_NODE_TESTS_ENABLED', }, +{ name => 'debug_topn_quickselect', type => 'bool', context => 'PGC_USERSET', group => 'DEVELOPER_OPTIONS', + short_desc => 'Uses quickselect instead of a heap for large bounded (top-N) sorts.', + flags => 'GUC_NOT_IN_SAMPLE', + variable => 'debug_topn_quickselect', + boot_val => 'true', +}, + { name => 'debug_write_read_parse_plan_trees', type => 'bool', context => 'PGC_SUSET', group => 'DEVELOPER_OPTIONS', short_desc => 'Set this to force all parse and plan trees to be passed through outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in those modules.', flags => 'GUC_NOT_IN_SAMPLE', diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 80189302101..7f8d4643080 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -122,6 +122,7 @@ /* GUC variables */ bool trace_sort = false; +bool debug_topn_quickselect = true; #ifdef DEBUG_BOUNDED_SORT bool optimize_bounded_sort = true; @@ -1146,7 +1147,7 @@ tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, * Below a bound of 8 the buffer refills too often to pay for * itself, and the heap wins. */ - if (state->bound >= 8 && !LACKMEM(state)) + if (debug_topn_quickselect && state->bound >= 8 && !LACKMEM(state)) { if (trace_sort) elog(LOG, "switching to bounded quickselect at %d tuples: %s", diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 164efba6b51..13171f97c3c 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -327,6 +327,7 @@ extern PGDLLIMPORT int tcp_user_timeout; extern PGDLLIMPORT char *role_string; extern PGDLLIMPORT bool in_hot_standby_guc; extern PGDLLIMPORT bool trace_sort; +extern PGDLLIMPORT bool debug_topn_quickselect; #ifdef DEBUG_BOUNDED_SORT extern PGDLLIMPORT bool optimize_bounded_sort; -- 2.54.0