mirror of
https://github.com/postgres/postgres.git
synced 2026-07-09 17:51:00 -04:00
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:
parent
ff076c042a
commit
e01b23b84e
29 changed files with 153 additions and 75 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
--
|
||||
|
|
|
|||
|
|
@ -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
|
||||
--
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue