aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/config.sgml23
-rw-r--r--src/backend/optimizer/path/costsize.c1
-rw-r--r--src/backend/optimizer/plan/planner.c3
-rw-r--r--src/backend/utils/misc/guc_tables.c15
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample1
-rw-r--r--src/include/optimizer/cost.h1
-rw-r--r--src/test/regress/expected/aggregates.out11
-rw-r--r--src/test/regress/expected/sysviews.out3
-rw-r--r--src/test/regress/sql/aggregates.sql6
9 files changed, 62 insertions, 2 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 8e4145979dc..9eedab652df 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -5311,6 +5311,29 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
</listitem>
</varlistentry>
+ <varlistentry id="guc-enable-presorted-aggregate" xreflabel="enable_presorted_aggregate">
+ <term><varname>enable_presorted_aggregate</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_presorted_aggregate</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls if the query planner will produce a plan which will provide
+ rows which are presorted in the order required for the query's
+ <literal>ORDER BY</literal> / <literal>DISTINCT</literal> aggregate
+ functions. When disabled, the query planner will produce a plan which
+ will always require the executor to perform a sort before performing
+ aggregation of each aggregate function containing an
+ <literal>ORDER BY</literal> or <literal>DISTINCT</literal> clause.
+ When enabled, the planner will try to produce a more efficient plan
+ which provides input to the aggregate functions which is presorted in
+ the order they require for aggregation. The default value is
+ <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-enable-seqscan" xreflabel="enable_seqscan">
<term><varname>enable_seqscan</varname> (<type>boolean</type>)
<indexterm>
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 0f0bcfb7e50..89d3c4352ce 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -151,6 +151,7 @@ bool enable_partitionwise_aggregate = false;
bool enable_parallel_append = true;
bool enable_parallel_hash = true;
bool enable_partition_pruning = true;
+bool enable_presorted_aggregate = true;
bool enable_async_append = true;
typedef struct
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index dfda251d956..e21e72eb870 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -3191,7 +3191,8 @@ make_pathkeys_for_groupagg(PlannerInfo *root, List *groupClause, List *tlist,
* sets. All handling specific to ordered aggregates must be done by the
* executor in that case.
*/
- if (root->numOrderedAggs == 0 || root->parse->groupingSets != NIL)
+ if (root->numOrderedAggs == 0 || root->parse->groupingSets != NIL ||
+ !enable_presorted_aggregate)
return grouppathkeys;
/*
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 1bf14eec661..436afe1d215 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -972,6 +972,21 @@ struct config_bool ConfigureNamesBool[] =
NULL, NULL, NULL
},
{
+ {"enable_presorted_aggregate", PGC_USERSET, QUERY_TUNING_METHOD,
+ gettext_noop("Enables the planner's ability to produce plans which "
+ "provide presorted input for ORDER BY / DISTINCT aggregate "
+ "functions."),
+ gettext_noop("Allows the query planner to build plans which provide "
+ "presorted input for aggregate functions with an ORDER BY / "
+ "DISTINCT clause. When disabled, implicit sorts are always "
+ "performed during execution."),
+ GUC_EXPLAIN
+ },
+ &enable_presorted_aggregate,
+ true,
+ NULL, NULL, NULL
+ },
+ {
{"enable_async_append", PGC_USERSET, QUERY_TUNING_METHOD,
gettext_noop("Enables the planner's use of async append plans."),
NULL,
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 043864597f8..5afdeb04de8 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -384,6 +384,7 @@
#enable_partition_pruning = on
#enable_partitionwise_join = off
#enable_partitionwise_aggregate = off
+#enable_presorted_aggregate = on
#enable_seqscan = on
#enable_sort = on
#enable_tidscan = on
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 204e94b6d10..b6cc2c9cd60 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -68,6 +68,7 @@ extern PGDLLIMPORT bool enable_partitionwise_aggregate;
extern PGDLLIMPORT bool enable_parallel_append;
extern PGDLLIMPORT bool enable_parallel_hash;
extern PGDLLIMPORT bool enable_partition_pruning;
+extern PGDLLIMPORT bool enable_presorted_aggregate;
extern PGDLLIMPORT bool enable_async_append;
extern PGDLLIMPORT int constraint_exclusion;
diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out
index fc2bd40be2d..309c2dc8654 100644
--- a/src/test/regress/expected/aggregates.out
+++ b/src/test/regress/expected/aggregates.out
@@ -1471,6 +1471,17 @@ group by ten;
-> Seq Scan on tenk1
(5 rows)
+-- Ensure no ordering is requested when enable_presorted_aggregate is off
+set enable_presorted_aggregate to off;
+explain (costs off)
+select sum(two order by two) from tenk1;
+ QUERY PLAN
+-------------------------
+ Aggregate
+ -> Seq Scan on tenk1
+(2 rows)
+
+reset enable_presorted_aggregate;
--
-- Test combinations of DISTINCT and/or ORDER BY
--
diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out
index 579b861d84f..001c6e7eb9d 100644
--- a/src/test/regress/expected/sysviews.out
+++ b/src/test/regress/expected/sysviews.out
@@ -128,10 +128,11 @@ select name, setting from pg_settings where name like 'enable%';
enable_partition_pruning | on
enable_partitionwise_aggregate | off
enable_partitionwise_join | off
+ enable_presorted_aggregate | on
enable_seqscan | on
enable_sort | on
enable_tidscan | on
-(20 rows)
+(21 rows)
-- Test that the pg_timezone_names and pg_timezone_abbrevs views are
-- more-or-less working. We can't test their contents in any great detail
diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql
index a4c00ff7a9d..15f6be8e15a 100644
--- a/src/test/regress/sql/aggregates.sql
+++ b/src/test/regress/sql/aggregates.sql
@@ -546,6 +546,12 @@ select
from tenk1
group by ten;
+-- Ensure no ordering is requested when enable_presorted_aggregate is off
+set enable_presorted_aggregate to off;
+explain (costs off)
+select sum(two order by two) from tenk1;
+reset enable_presorted_aggregate;
+
--
-- Test combinations of DISTINCT and/or ORDER BY
--