Add an enable_groupagg GUC parameter

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
This commit is contained in:
Richard Guo 2026-07-09 09:44:56 +09:00
parent ff076c042a
commit e01b23b84e
29 changed files with 153 additions and 75 deletions

View 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);

View 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;

View 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));

View 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;

View 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>

View 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;
}

View 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
{

View file

@ -905,6 +905,13 @@
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',

View file

@ -426,6 +426,7 @@
#enable_async_append = on
#enable_bitmapscan = on
#enable_gathermerge = on
#enable_groupagg = on
#enable_hashagg = on
#enable_hashjoin = on
#enable_incremental_sort = on

View 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;

View 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

View 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;

View 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)

View 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

View 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

View 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
--

View 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
--

View 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)

View 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 (

View 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.

View 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

View 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

View 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;

View 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;

View 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

View 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

View 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;

View 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

View 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