]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Add an enable_groupagg GUC parameter
authorRichard Guo <rguo@postgresql.org>
Thu, 9 Jul 2026 00:44:56 +0000 (09:44 +0900)
committerRichard Guo <rguo@postgresql.org>
Thu, 9 Jul 2026 00:44:56 +0000 (09:44 +0900)
We've long had enable_hashagg to discourage hashed aggregation, but
there was no equivalent for grouping that works by reading presorted
input.  That's handy when investigating planner cost misestimates, and
as an escape hatch when a sorted grouping plan is chosen over a much
cheaper hashed one.

enable_groupagg (on by default) covers the GroupAggregate and Group
nodes, the sort-based Unique step used for DISTINCT and semijoin
unique-ification, and the sorted mode of SetOp.  It isn't a hard
switch; it only bumps disabled_nodes, so plans with no other choice
are still produced.

Several regression and module tests had been setting enable_sort off,
and one enable_indexscan off, only to force a hashed plan.  Use
enable_groupagg there instead, where that was the real intent.  In
union.sql this also lets us test the hashed UNION path, which we had
no way to reach before.

Author: Tatsuro Yamada <yamatattsu@gmail.com>
Co-authored-by: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/CAOKkKFvYHSEsFazkrf9bRH14p-H27XMaqbZfRYjS6EHBruvZMQ@mail.gmail.com

29 files changed:
contrib/hstore/expected/hstore.out
contrib/hstore/sql/hstore.sql
contrib/ltree/expected/ltree.out
contrib/ltree/sql/ltree.sql
doc/src/sgml/config.sgml
src/backend/optimizer/path/costsize.c
src/backend/optimizer/util/pathnode.c
src/backend/utils/misc/guc_parameters.dat
src/backend/utils/misc/postgresql.conf.sample
src/include/optimizer/cost.h
src/test/modules/injection_points/expected/hashagg.out
src/test/modules/injection_points/sql/hashagg.sql
src/test/regress/expected/aggregates.out
src/test/regress/expected/groupingsets.out
src/test/regress/expected/jsonb.out
src/test/regress/expected/multirangetypes.out
src/test/regress/expected/rangetypes.out
src/test/regress/expected/select_distinct.out
src/test/regress/expected/subselect.out
src/test/regress/expected/sysviews.out
src/test/regress/expected/union.out
src/test/regress/sql/aggregates.sql
src/test/regress/sql/groupingsets.sql
src/test/regress/sql/jsonb.sql
src/test/regress/sql/multirangetypes.sql
src/test/regress/sql/rangetypes.sql
src/test/regress/sql/select_distinct.sql
src/test/regress/sql/subselect.sql
src/test/regress/sql/union.sql

index acea8806ba47e986ad23d9772345cab14c793297..9713372b7a4930b88959e8014457c9c45dd3495d 100644 (file)
@@ -1509,7 +1509,7 @@ select count(*) from (select h from (select * from testhstore union all select *
 (1 row)
 
 set enable_hashagg = true;
-set enable_sort = false;
+set enable_groupagg = false;
 select count(*) from (select h from (select * from testhstore union all select * from testhstore) hs group by h) hs2;
  count 
 -------
@@ -1522,7 +1522,7 @@ select distinct * from (values (hstore '' || ''),('')) v(h);
  
 (1 row)
 
-set enable_sort = true;
+set enable_groupagg = true;
 -- btree
 drop index hidx;
 create index hidx on testhstore using btree (h);
index 8ae95e8a510549d06e4e11079b4d97e0695374e2..ac929e075098e1c32dc51641348d705fb89fa599 100644 (file)
@@ -345,10 +345,10 @@ select count(distinct h) from testhstore;
 set enable_hashagg = false;
 select count(*) from (select h from (select * from testhstore union all select * from testhstore) hs group by h) hs2;
 set enable_hashagg = true;
-set enable_sort = false;
+set enable_groupagg = false;
 select count(*) from (select h from (select * from testhstore union all select * from testhstore) hs group by h) hs2;
 select distinct * from (values (hstore '' || ''),('')) v(h);
-set enable_sort = true;
+set enable_groupagg = true;
 
 -- btree
 drop index hidx;
index f1d0eb37b81945b1c01255067a7e072c9ca06135..0ab623cc204a818207361d234fea0fd9105b5cc8 100644 (file)
@@ -7891,7 +7891,7 @@ reset enable_seqscan;
 reset enable_bitmapscan;
 -- test hash aggregate
 set enable_hashagg=on;
-set enable_sort=off;
+set enable_groupagg=off;
 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM (
 SELECT t FROM (SELECT * FROM ltreetest UNION ALL SELECT * FROM ltreetest) t1 GROUP BY t
@@ -7915,7 +7915,7 @@ SELECT t FROM (SELECT * FROM ltreetest UNION ALL SELECT * FROM ltreetest) t1 GRO
 (1 row)
 
 reset enable_hashagg;
-reset enable_sort;
+reset enable_groupagg;
 drop index tstidx;
 -- test gist index
 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=0));
index 833091dc6bbf78dcf176c83c6e5159dd7d0e2d7e..5c324160afd14ee66b44fa16b73917b8b446687e 100644 (file)
@@ -372,7 +372,7 @@ reset enable_bitmapscan;
 -- test hash aggregate
 
 set enable_hashagg=on;
-set enable_sort=off;
+set enable_groupagg=off;
 
 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM (
@@ -384,7 +384,7 @@ SELECT t FROM (SELECT * FROM ltreetest UNION ALL SELECT * FROM ltreetest) t1 GRO
 ) t2;
 
 reset enable_hashagg;
-reset enable_sort;
+reset enable_groupagg;
 
 drop index tstidx;
 
index 9172a4c5c95b0a571dc9b9f7be1cd9d35e4e09ea..c67130c620e1a7ac3dbf1d2103beb0e2d3619905 100644 (file)
@@ -5863,6 +5863,20 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-enable-groupagg" xreflabel="enable_groupagg">
+      <term><varname>enable_groupagg</varname> (<type>boolean</type>)
+      <indexterm>
+       <primary><varname>enable_groupagg</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Enables or disables the query planner's use of sort-based grouping
+        and aggregation plan types. The default is <literal>on</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-enable-hashagg" xreflabel="enable_hashagg">
       <term><varname>enable_hashagg</varname> (<type>boolean</type>)
       <indexterm>
index 1c575e56ff6074ee46d41368ab58beedee39384a..ac523ecf9a8451956dc4e6bdfb4f83a2d205c67f 100644 (file)
@@ -151,6 +151,7 @@ bool                enable_tidscan = true;
 bool           enable_sort = true;
 bool           enable_incremental_sort = true;
 bool           enable_hashagg = true;
+bool           enable_groupagg = true;
 bool           enable_nestloop = true;
 bool           enable_material = true;
 bool           enable_memoize = true;
@@ -2837,14 +2838,14 @@ cost_agg(Path *path, PlannerInfo *root,
                /* we aren't grouping */
                total_cost = startup_cost + cpu_tuple_cost;
                output_tuples = 1;
+
+               /* AGG_PLAIN neither hashes nor sorts, so neither switch disables it */
        }
        else if (aggstrategy == AGG_SORTED || aggstrategy == AGG_MIXED)
        {
                /* Here we are able to deliver output on-the-fly */
                startup_cost = input_startup_cost;
                total_cost = input_total_cost;
-               if (aggstrategy == AGG_MIXED && !enable_hashagg)
-                       ++disabled_nodes;
                /* calcs phrased this way to match HASHED case, see note above */
                total_cost += aggcosts->transCost.startup;
                total_cost += aggcosts->transCost.per_tuple * input_tuples;
@@ -2853,13 +2854,31 @@ cost_agg(Path *path, PlannerInfo *root,
                total_cost += aggcosts->finalCost.per_tuple * numGroups;
                total_cost += cpu_tuple_cost * numGroups;
                output_tuples = numGroups;
+
+               /*
+                * AGG_MIXED hashes at least one grouping set, so it is disabled when
+                * enable_hashagg is off.  Any sorted grouping it also performs is
+                * costed separately, since create_groupingsets_path() calls
+                * cost_agg() once per rollup and the non-hashed rollups come through
+                * as AGG_SORTED.
+                *
+                * AGG_SORTED is disabled when enable_groupagg is off, but only when
+                * there are grouping columns.  The empty grouping set arrives with
+                * numGroupCols == 0 and is computed like AGG_PLAIN, with no hashing
+                * or sorting, so it isn't disabled.
+                */
+               if (aggstrategy == AGG_MIXED)
+               {
+                       if (!enable_hashagg)
+                               ++disabled_nodes;
+               }
+               else if (numGroupCols > 0 && !enable_groupagg)  /* AGG_SORTED */
+                       ++disabled_nodes;
        }
        else
        {
                /* must be AGG_HASHED */
                startup_cost = input_total_cost;
-               if (!enable_hashagg)
-                       ++disabled_nodes;
                startup_cost += aggcosts->transCost.startup;
                startup_cost += aggcosts->transCost.per_tuple * input_tuples;
                /* cost of computing hash value */
@@ -2871,6 +2890,10 @@ cost_agg(Path *path, PlannerInfo *root,
                /* cost of retrieving from hash table */
                total_cost += cpu_tuple_cost * numGroups;
                output_tuples = numGroups;
+
+               /* AGG_HASHED is disabled when enable_hashagg is off */
+               if (!enable_hashagg)
+                       ++disabled_nodes;
        }
 
        /*
@@ -3340,7 +3363,7 @@ cost_group(Path *path, PlannerInfo *root,
        }
 
        path->rows = output_tuples;
-       path->disabled_nodes = input_disabled_nodes;
+       path->disabled_nodes = input_disabled_nodes + (enable_groupagg ? 0 : 1);
        path->startup_cost = startup_cost;
        path->total_cost = total_cost;
 }
index 73518c8f8701835c7630ea483d0fab4dca5a18aa..3875e3dd571a0a929add3049213225af34d6468e 100644 (file)
@@ -3036,6 +3036,16 @@ create_unique_path(PlannerInfo *root,
                cpu_operator_cost * subpath->rows * numCols;
        pathnode->path.rows = numGroups;
 
+       /*
+        * Mark the path as disabled if enable_groupagg is off.  While this isn't
+        * a grouping Agg node, it is the sort-based way of removing duplicates
+        * and so is the natural counterpart to the AGG_HASHED path that
+        * enable_hashagg controls; it seems close enough to justify letting that
+        * switch control it.
+        */
+       if (!enable_groupagg)
+               pathnode->path.disabled_nodes++;
+
        return pathnode;
 }
 
@@ -3522,6 +3532,16 @@ create_setop_path(PlannerInfo *root,
                 * qual-checking or projection.
                 */
                pathnode->path.total_cost += cpu_operator_cost * outputRows;
+
+               /*
+                * Mark the path as disabled if enable_groupagg is off.  While this
+                * isn't a grouping Agg node, it is the sort-based implementation and
+                * so is the natural counterpart to the SETOP_HASHED path that
+                * enable_hashagg controls; it seems close enough to justify letting
+                * that switch control it.
+                */
+               if (!enable_groupagg)
+                       pathnode->path.disabled_nodes++;
        }
        else
        {
index c9118e7198836d47098ddf68dd7fe1841ef5d64c..dd799a5e70f98e90a41372f0308695fe543ccbbe 100644 (file)
   boot_val => 'true',
 },
 
+{ name => 'enable_groupagg', type => 'bool', context => 'PGC_USERSET', group => 'QUERY_TUNING_METHOD',
+  short_desc => 'Enables the planner\'s use of sort-based grouping and aggregation plans.',
+  flags => 'GUC_EXPLAIN',
+  variable => 'enable_groupagg',
+  boot_val => 'true',
+},
+
 { name => 'enable_hashagg', type => 'bool', context => 'PGC_USERSET', group => 'QUERY_TUNING_METHOD',
   short_desc => 'Enables the planner\'s use of hashed aggregation plans.',
   flags => 'GUC_EXPLAIN',
index d7942f50a70250e1ecec4f5f6198c7adcaded566..47e1221f3c3bafb9ad36d15db089ddd9fdd980ca 100644 (file)
 #enable_async_append = on
 #enable_bitmapscan = on
 #enable_gathermerge = on
+#enable_groupagg = on
 #enable_hashagg = on
 #enable_hashjoin = on
 #enable_incremental_sort = on
index f2fd5d315078daa1231c653870d22af20b465db6..bda3f1690c04244c05062d1a13c575aebff5ae0e 100644 (file)
@@ -57,6 +57,7 @@ extern PGDLLIMPORT bool enable_tidscan;
 extern PGDLLIMPORT bool enable_sort;
 extern PGDLLIMPORT bool enable_incremental_sort;
 extern PGDLLIMPORT bool enable_hashagg;
+extern PGDLLIMPORT bool enable_groupagg;
 extern PGDLLIMPORT bool enable_nestloop;
 extern PGDLLIMPORT bool enable_material;
 extern PGDLLIMPORT bool enable_memoize;
index cc4247af97d085c02a2b56fe2e33852dde807ddb..2f75e9be8b72bff741790d78e0d7a896513f5e21 100644 (file)
@@ -36,7 +36,7 @@ CREATE TABLE hashagg_ij(x INTEGER);
 INSERT INTO hashagg_ij SELECT g FROM generate_series(1,5100) g;
 SET max_parallel_workers=0;
 SET max_parallel_workers_per_gather=0;
-SET enable_sort=FALSE;
+SET enable_groupagg=FALSE;
 SET work_mem='4MB';
 SELECT COUNT(*) FROM (SELECT DISTINCT x FROM hashagg_ij) s;
 NOTICE:  notice triggered for injection point hash-aggregate-spill-1000
index 51d814623fcb38bca186e897e7bb74e12a6d4fe6..5d580f8e425dfa1519971db9bc1671c58c19867a 100644 (file)
@@ -17,7 +17,7 @@ INSERT INTO hashagg_ij SELECT g FROM generate_series(1,5100) g;
 
 SET max_parallel_workers=0;
 SET max_parallel_workers_per_gather=0;
-SET enable_sort=FALSE;
+SET enable_groupagg=FALSE;
 SET work_mem='4MB';
 
 SELECT COUNT(*) FROM (SELECT DISTINCT x FROM hashagg_ij) s;
index 728a3ecd03f89714666bed472f66a74ec2b19944..f21f4e225da7875fb3c4e85176970bc1033c9158 100644 (file)
@@ -1459,7 +1459,7 @@ drop cascades to table minmaxtest2
 drop cascades to table minmaxtest3
 -- DISTINCT can also trigger wrong answers with hash aggregation (bug #18465)
 begin;
-set local enable_sort = off;
+set local enable_groupagg = off;
 explain (costs off)
   select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1)
   from int4_tbl t0;
@@ -3866,7 +3866,7 @@ select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*)
 --
 -- Hash Aggregation Spill tests
 --
-set enable_sort=false;
+set enable_groupagg=false;
 set work_mem='64kB';
 select unique1, count(*), sum(twothousand) from tenk1
 group by unique1
@@ -3925,7 +3925,7 @@ order by sum(twothousand);
 (48 rows)
 
 set work_mem to default;
-set enable_sort to default;
+set enable_groupagg to default;
 --
 -- Compare results between plans using sorting and plans using hash
 -- aggregation. Force spilling in both cases by setting work_mem low.
@@ -3974,7 +3974,7 @@ select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3
   from agg_data_2k group by g/2;
 -- Produce results with hash aggregation
 set enable_hashagg = true;
-set enable_sort = false;
+set enable_groupagg = false;
 set jit_above_cost = 0;
 explain (costs off)
 select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3
@@ -4006,7 +4006,7 @@ select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3
 create table agg_hash_4 as
 select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3
   from agg_data_2k group by g/2;
-set enable_sort = true;
+set enable_groupagg = true;
 set work_mem to default;
 -- Compare group aggregation results to hash aggregation results
 (select * from agg_hash_1 except select * from agg_group_1)
index b08083ec54ce2d1cb893a98844960a03063ec973..c3f00771f6e28b7b898879683cc1c1c596e1e28f 100644 (file)
@@ -2010,7 +2010,7 @@ alter table bug_16784 set (autovacuum_enabled = 'false');
 update pg_class set reltuples = 10 where relname='bug_16784';
 insert into bug_16784 select g/10, g from generate_series(1,40) g;
 set work_mem='64kB';
-set enable_sort = false;
+set enable_groupagg = false;
 select * from
   (values (1),(2)) v(a),
   lateral (select a, i, j, count(*) from
@@ -2205,7 +2205,7 @@ alter table gs_data_1 set (autovacuum_enabled = 'false');
 update pg_class set reltuples = 10 where relname='gs_data_1';
 set work_mem='64kB';
 -- Produce results with sorting.
-set enable_sort = true;
+set enable_groupagg = true;
 set enable_hashagg = false;
 set jit_above_cost = 0;
 explain (costs off)
@@ -2234,7 +2234,7 @@ select g100, g10, sum(g::numeric), count(*), max(g::text)
 from gs_data_1 group by cube (g1000, g100,g10);
 -- Produce results with hash aggregation.
 set enable_hashagg = true;
-set enable_sort = false;
+set enable_groupagg = false;
 explain (costs off)
 select g100, g10, sum(g::numeric), count(*), max(g::text)
 from gs_data_1 group by cube (g1000, g100,g10);
@@ -2255,7 +2255,7 @@ from gs_data_1 group by cube (g1000, g100,g10);
 create table gs_hash_1 as
 select g100, g10, sum(g::numeric), count(*), max(g::text)
 from gs_data_1 group by cube (g1000, g100,g10);
-set enable_sort = true;
+set enable_groupagg = true;
 set work_mem to default;
 set hash_mem_multiplier to default;
 -- Compare results
index 4e2467852db13bbb21334bd3fb2b0fbe8e108fbb..b1d2ce5f03aa46807ecc8a13c89676791bd810a8 100644 (file)
@@ -3473,7 +3473,7 @@ SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT *
 (1 row)
 
 SET enable_hashagg = on;
-SET enable_sort = off;
+SET enable_groupagg = off;
 SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2;
  count 
 -------
@@ -3486,9 +3486,9 @@ SELECT distinct * FROM (values (jsonb '{}' || ''::text),('{}')) v(j);
  {}
 (1 row)
 
-SET enable_sort = on;
+SET enable_groupagg = on;
 RESET enable_hashagg;
-RESET enable_sort;
+RESET enable_groupagg;
 DROP INDEX jidx;
 DROP INDEX jidx_array;
 -- btree
index 6006aede31d9fab014fdaa9a9f7c791131584b26..d47ce4b6d6ad9f8f6d1bfe9747b8662fb0be7b19 100644 (file)
@@ -3442,14 +3442,14 @@ NOTICE:  drop cascades to type two_ints_range
 --
 -- Check behavior when subtype lacks a hash function
 --
-set enable_sort = off;  -- try to make it pick a hash setop implementation
+set enable_groupagg = off;  -- try to make it pick a hash setop implementation
 select '{(01,10)}'::varbitmultirange except select '{(10,11)}'::varbitmultirange;
  varbitmultirange 
 ------------------
  {(01,10)}
 (1 row)
 
-reset enable_sort;
+reset enable_groupagg;
 --
 -- OUT/INOUT/TABLE functions
 --
index 98ba738fb1d01ec117e3a6c68a2e7f1d7905c6f8..083e948bc41e8eba84456e2eded08ecc1489ff70 100644 (file)
@@ -1819,14 +1819,14 @@ NOTICE:  drop cascades to type two_ints_range
 -- Check behavior when subtype lacks a hash function
 --
 create type varbitrange as range (subtype = varbit);
-set enable_sort = off;  -- try to make it pick a hash setop implementation
+set enable_groupagg = off;  -- try to make it pick a hash setop implementation
 select '(01,10)'::varbitrange except select '(10,11)'::varbitrange;
  varbitrange 
 -------------
  (01,10)
 (1 row)
 
-reset enable_sort;
+reset enable_groupagg;
 --
 -- OUT/INOUT/TABLE functions
 --
index 379ba0bc9fa5af34d8c8f92d6350a1daad576a4e..741f72387423e748ea0ebdd6c8cf4617917de173 100644 (file)
@@ -187,7 +187,7 @@ SELECT DISTINCT hundred, two FROM tenk1;
 RESET enable_seqscan;
 SET enable_hashagg=TRUE;
 -- Produce results with hash aggregation.
-SET enable_sort=FALSE;
+SET enable_groupagg=FALSE;
 SET jit_above_cost=0;
 EXPLAIN (costs off)
 SELECT DISTINCT g%1000 FROM generate_series(0,9999) g;
@@ -203,7 +203,7 @@ SELECT DISTINCT g%1000 FROM generate_series(0,9999) g;
 SET jit_above_cost TO DEFAULT;
 CREATE TABLE distinct_hash_2 AS
 SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g;
-SET enable_sort=TRUE;
+SET enable_groupagg=TRUE;
 SET work_mem TO DEFAULT;
 -- Compare results
 (SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1)
index 20140f171af2fa8703ac614841e5148d37ac61ff..e7ff719108245d010073c3af688f09b373b41943 100644 (file)
@@ -1454,7 +1454,7 @@ where o.ten = 0;
 -- Test rescan of a hashed SetOp node
 --
 begin;
-set local enable_sort = off;
+set local enable_groupagg = off;
 explain (costs off)
 select count(*) from
   onek o cross join lateral (
index 132b56a5864ca62c86b8adb2aa97425fac9c0178..1e327c2afa46724ba1cf2c46e527efefc04b9ced 100644 (file)
@@ -161,6 +161,7 @@ select name, setting from pg_settings where name like 'enable%';
  enable_eager_aggregate         | on
  enable_gathermerge             | on
  enable_group_by_reordering     | on
+ enable_groupagg                | on
  enable_hashagg                 | on
  enable_hashjoin                | on
  enable_incremental_sort        | on
@@ -180,7 +181,7 @@ select name, setting from pg_settings where name like 'enable%';
  enable_seqscan                 | on
  enable_sort                    | on
  enable_tidscan                 | on
-(25 rows)
+(26 rows)
 
 -- There are always wait event descriptions for various types.  InjectionPoint
 -- may be present or absent, depending on history since last postmaster start.
index ca9089e9a7d229cb452df24dc1beeb7c008e5a7c..84abcd6b14f9e17cd19556372ef24ec90527a918 100644 (file)
@@ -386,14 +386,14 @@ select count(*) from
 (1 row)
 
 -- this query will prefer a sorted setop unless we force it.
-set enable_indexscan to off;
+set enable_groupagg to off;
 explain (costs off)
 select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
-           QUERY PLAN            
----------------------------------
+                         QUERY PLAN                         
+------------------------------------------------------------
  HashSetOp Except
-   ->  Seq Scan on tenk1
-   ->  Seq Scan on tenk1 tenk1_1
+   ->  Index Only Scan using tenk1_unique1 on tenk1
+   ->  Index Only Scan using tenk1_unique2 on tenk1 tenk1_1
          Filter: (unique2 <> 10)
 (4 rows)
 
@@ -403,7 +403,7 @@ select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
       10
 (1 row)
 
-reset enable_indexscan;
+reset enable_groupagg;
 -- the hashed implementation is sensitive to child plans' tuple slot types
 explain (costs off)
 select * from int8_tbl intersect select q2, q1 from int8_tbl order by 1, 2;
@@ -981,19 +981,30 @@ select except select;
 
 -- check hashed implementation
 set enable_hashagg = true;
-set enable_sort = false;
--- We've no way to check hashed UNION as the empty pathkeys in the Append are
--- fine to make use of Unique, which is cheaper than HashAggregate and we've
--- no means to disable Unique.
+set enable_groupagg = false;
+explain (costs off)
+select from generate_series(1,5) union select from generate_series(1,3);
+                           QUERY PLAN                           
+----------------------------------------------------------------
+ HashAggregate
+   ->  Append
+         ->  Function Scan on generate_series
+         ->  Function Scan on generate_series generate_series_1
+(4 rows)
+
 explain (costs off)
 select from generate_series(1,5) intersect select from generate_series(1,3);
                         QUERY PLAN                        
 ----------------------------------------------------------
- SetOp Intersect
HashSetOp Intersect
    ->  Function Scan on generate_series
    ->  Function Scan on generate_series generate_series_1
 (3 rows)
 
+select from generate_series(1,5) union select from generate_series(1,3);
+--
+(1 row)
+
 select from generate_series(1,5) union all select from generate_series(1,3);
 --
 (8 rows)
@@ -1016,7 +1027,7 @@ select from generate_series(1,5) except all select from generate_series(1,3);
 
 -- check sorted implementation
 set enable_hashagg = false;
-set enable_sort = true;
+set enable_groupagg = true;
 explain (costs off)
 select from generate_series(1,5) union select from generate_series(1,3);
                            QUERY PLAN                           
@@ -1075,7 +1086,7 @@ select from cte union select from cte;
 (1 row)
 
 reset enable_hashagg;
-reset enable_sort;
+reset enable_groupagg;
 --
 -- Check handling of a case with unknown constants.  We don't guarantee
 -- an undecorated constant will work in all cases, but historically this
index 342605d5497f58c247b94b25ea5cb223d13bb6f9..5cb9a9dc1be400d84418926e1f5ebcf3e81a0be3 100644 (file)
@@ -493,7 +493,7 @@ drop table minmaxtest cascade;
 
 -- DISTINCT can also trigger wrong answers with hash aggregation (bug #18465)
 begin;
-set local enable_sort = off;
+set local enable_groupagg = off;
 explain (costs off)
   select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1)
   from int4_tbl t0;
@@ -1702,7 +1702,7 @@ select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*)
 -- Hash Aggregation Spill tests
 --
 
-set enable_sort=false;
+set enable_groupagg=false;
 set work_mem='64kB';
 
 select unique1, count(*), sum(twothousand) from tenk1
@@ -1711,7 +1711,7 @@ having sum(fivethous) > 4975
 order by sum(twothousand);
 
 set work_mem to default;
-set enable_sort to default;
+set enable_groupagg to default;
 
 --
 -- Compare results between plans using sorting and plans using hash
@@ -1766,7 +1766,7 @@ select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3
 -- Produce results with hash aggregation
 
 set enable_hashagg = true;
-set enable_sort = false;
+set enable_groupagg = false;
 
 set jit_above_cost = 0;
 
@@ -1799,7 +1799,7 @@ create table agg_hash_4 as
 select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3
   from agg_data_2k group by g/2;
 
-set enable_sort = true;
+set enable_groupagg = true;
 set work_mem to default;
 
 -- Compare group aggregation results to hash aggregation results
index a594449b697868f0b4e18200c83d218b1e6dd378..c5d4ed2eb574e40216a3666df016bdaa38683545 100644 (file)
@@ -583,7 +583,7 @@ update pg_class set reltuples = 10 where relname='bug_16784';
 insert into bug_16784 select g/10, g from generate_series(1,40) g;
 
 set work_mem='64kB';
-set enable_sort = false;
+set enable_groupagg = false;
 
 select * from
   (values (1),(2)) v(a),
@@ -609,7 +609,7 @@ set work_mem='64kB';
 
 -- Produce results with sorting.
 
-set enable_sort = true;
+set enable_groupagg = true;
 set enable_hashagg = false;
 set jit_above_cost = 0;
 
@@ -624,7 +624,7 @@ from gs_data_1 group by cube (g1000, g100,g10);
 -- Produce results with hash aggregation.
 
 set enable_hashagg = true;
-set enable_sort = false;
+set enable_groupagg = false;
 
 explain (costs off)
 select g100, g10, sum(g::numeric), count(*), max(g::text)
@@ -634,7 +634,7 @@ create table gs_hash_1 as
 select g100, g10, sum(g::numeric), count(*), max(g::text)
 from gs_data_1 group by cube (g1000, g100,g10);
 
-set enable_sort = true;
+set enable_groupagg = true;
 set work_mem to default;
 set hash_mem_multiplier to default;
 
index d28ed1c1e851cafb1f4f979926a6fc47892a7d87..d4e8d7d8c9ef46b97d2f39fcd1ad1eff77240ac4 100644 (file)
@@ -927,13 +927,13 @@ SELECT count(distinct j) FROM testjsonb;
 SET enable_hashagg = off;
 SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2;
 SET enable_hashagg = on;
-SET enable_sort = off;
+SET enable_groupagg = off;
 SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2;
 SELECT distinct * FROM (values (jsonb '{}' || ''::text),('{}')) v(j);
-SET enable_sort = on;
+SET enable_groupagg = on;
 
 RESET enable_hashagg;
-RESET enable_sort;
+RESET enable_groupagg;
 
 DROP INDEX jidx;
 DROP INDEX jidx_array;
index ddff722b28cd4ebe957663d494fb01b7bd0a0cbf..cf0fff6fddd10df53bbc726e6352b3fd012f041b 100644 (file)
@@ -862,11 +862,11 @@ drop type two_ints cascade;
 -- Check behavior when subtype lacks a hash function
 --
 
-set enable_sort = off;  -- try to make it pick a hash setop implementation
+set enable_groupagg = off;  -- try to make it pick a hash setop implementation
 
 select '{(01,10)}'::varbitmultirange except select '{(10,11)}'::varbitmultirange;
 
-reset enable_sort;
+reset enable_groupagg;
 
 --
 -- OUT/INOUT/TABLE functions
index 5c4b0337b7a8afd996b58c9ff7991a0dddf5a260..dbfe0d049dab73d258bb3e9c77770f7dfc716cd3 100644 (file)
@@ -587,11 +587,11 @@ drop type two_ints cascade;
 
 create type varbitrange as range (subtype = varbit);
 
-set enable_sort = off;  -- try to make it pick a hash setop implementation
+set enable_groupagg = off;  -- try to make it pick a hash setop implementation
 
 select '(01,10)'::varbitrange except select '(10,11)'::varbitrange;
 
-reset enable_sort;
+reset enable_groupagg;
 
 --
 -- OUT/INOUT/TABLE functions
index 50ac7dde396c6599d48b6e303a701d7fdf210a0b..2ed1616b098f7eb57bb74d0f1b57e7fc91ead63e 100644 (file)
@@ -81,7 +81,7 @@ SET enable_hashagg=TRUE;
 
 -- Produce results with hash aggregation.
 
-SET enable_sort=FALSE;
+SET enable_groupagg=FALSE;
 
 SET jit_above_cost=0;
 
@@ -96,7 +96,7 @@ SET jit_above_cost TO DEFAULT;
 CREATE TABLE distinct_hash_2 AS
 SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g;
 
-SET enable_sort=TRUE;
+SET enable_groupagg=TRUE;
 
 SET work_mem TO DEFAULT;
 
index 3defbc291773d738f3831dd5e38adae2c0b79ee1..76bce5cdba5ca6e76f21419d174dc51dbbc7411d 100644 (file)
@@ -730,7 +730,7 @@ where o.ten = 0;
 -- Test rescan of a hashed SetOp node
 --
 begin;
-set local enable_sort = off;
+set local enable_groupagg = off;
 
 explain (costs off)
 select count(*) from
index 780b704b53b230b01dc40806f64fbb05da3c8407..c8de276c2b5719ee2fd81419d633652246edb90d 100644 (file)
@@ -135,13 +135,13 @@ select count(*) from
   ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss;
 
 -- this query will prefer a sorted setop unless we force it.
-set enable_indexscan to off;
+set enable_groupagg to off;
 
 explain (costs off)
 select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
 select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
 
-reset enable_indexscan;
+reset enable_groupagg;
 
 -- the hashed implementation is sensitive to child plans' tuple slot types
 explain (costs off)
@@ -321,14 +321,14 @@ select except select;
 
 -- check hashed implementation
 set enable_hashagg = true;
-set enable_sort = false;
+set enable_groupagg = false;
 
--- We've no way to check hashed UNION as the empty pathkeys in the Append are
--- fine to make use of Unique, which is cheaper than HashAggregate and we've
--- no means to disable Unique.
+explain (costs off)
+select from generate_series(1,5) union select from generate_series(1,3);
 explain (costs off)
 select from generate_series(1,5) intersect select from generate_series(1,3);
 
+select from generate_series(1,5) union select from generate_series(1,3);
 select from generate_series(1,5) union all select from generate_series(1,3);
 select from generate_series(1,5) intersect select from generate_series(1,3);
 select from generate_series(1,5) intersect all select from generate_series(1,3);
@@ -337,7 +337,7 @@ select from generate_series(1,5) except all select from generate_series(1,3);
 
 -- check sorted implementation
 set enable_hashagg = false;
-set enable_sort = true;
+set enable_groupagg = true;
 
 explain (costs off)
 select from generate_series(1,5) union select from generate_series(1,3);
@@ -363,7 +363,7 @@ with cte as not materialized (select s from generate_series(1,5) s)
 select from cte union select from cte;
 
 reset enable_hashagg;
-reset enable_sort;
+reset enable_groupagg;
 
 --
 -- Check handling of a case with unknown constants.  We don't guarantee