-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
-- Check that the vectorized aggregation works properly in the GroupAggregate
-- mode.
\pset null $
set max_parallel_workers_per_gather = 0;
set enable_hashagg to off;
--set timescaledb.enable_vectorized_aggregation to off;
--set timescaledb.debug_require_vector_agg to 'forbid';
create table groupagg(t int, s int, value int);
select create_hypertable('groupagg', 't', chunk_time_interval => 10000);
   create_hypertable   
-----------------------
 (1,public,groupagg,t)

insert into groupagg
select
    xslow * 10,
    case when xfast = 13 then null else xfast end,
    xfast * 7 + xslow * 3
from generate_series(10, 99) xfast,
    generate_series(1, 1487) xslow
;
alter table groupagg set (timescaledb.compress, timescaledb.compress_segmentby = '',
    timescaledb.compress_orderby = 's');
select count(compress_chunk(x)) from show_chunks('groupagg') x;
 count 
-------
     2

vacuum analyze groupagg;
set timescaledb.debug_require_vector_agg to 'require';
select s, sum(value) from groupagg group by s order by s limit 10;
 s  |   sum   
----+---------
 10 | 3423074
 11 | 3433483
 12 | 3443892
 14 | 3464710
 15 | 3475119
 16 | 3485528
 17 | 3495937
 18 | 3506346
 19 | 3516755
 20 | 3527164

-- The hash grouping policies do not support the GroupAggregate mode in the
-- reverse order.
set timescaledb.debug_require_vector_agg to 'forbid';
select s, sum(value) from groupagg group by s order by s desc limit 10;
 s  |   sum   
----+---------
  $ | 3454301
 99 | 4349475
 98 | 4339066
 97 | 4328657
 96 | 4318248
 95 | 4307839
 94 | 4297430
 93 | 4287021
 92 | 4276612
 91 | 4266203

reset timescaledb.debug_require_vector_agg;
-- Also test the NULLS FIRST order.
select count(decompress_chunk(x)) from show_chunks('groupagg') x;
 count 
-------
     2

alter table groupagg set (timescaledb.compress, timescaledb.compress_segmentby = '',
    timescaledb.compress_orderby = 's nulls first');
select count(compress_chunk(x)) from show_chunks('groupagg') x;
 count 
-------
     2

vacuum analyze groupagg;
set timescaledb.debug_require_vector_agg to 'require';
select s, sum(value) from groupagg group by s order by s nulls first limit 10;
 s  |   sum   
----+---------
  $ | 3454301
 10 | 3423074
 11 | 3433483
 12 | 3443892
 14 | 3464710
 15 | 3475119
 16 | 3485528
 17 | 3495937
 18 | 3506346
 19 | 3516755

reset timescaledb.debug_require_vector_agg;
-- More tests for dictionary encoding.
create table text_table(ts int, a text);
select create_hypertable('text_table', 'ts', chunk_time_interval => 3);
    create_hypertable    
-------------------------
 (3,public,text_table,t)

alter table text_table set (timescaledb.compress, timescaledb.compress_segmentby = 'a');
insert into text_table select -1, 'scalar' from generate_series(1, 1000) x;
select count(compress_chunk(x)) from show_chunks('text_table') x;
 count 
-------
     1

insert into text_table select 1, '' from generate_series(1, 1000) x;
insert into text_table select 2, 'same' from generate_series(1, 1000) x;
insert into text_table select 3, 'different' || x from generate_series(1, 1000) x;
insert into text_table select 4, case when x % 2 = 0 then null else 'samewithnulls' end from generate_series(1, 1000) x;
insert into text_table select 5, case when x % 2 = 0 then null else 'differentwithnulls' || x end from generate_series(1, 1000) x;
alter table text_table set (timescaledb.compress,
    timescaledb.compress_segmentby = '', timescaledb.compress_orderby = 'a');
select count(compress_chunk(x)) from show_chunks('text_table') x;
NOTICE:  chunk "_hyper_3_7_chunk" is already converted to columnstore
 count 
-------
     3

vacuum analyze text_table;
set timescaledb.debug_require_vector_agg to 'require';
select a, count(*) from text_table group by a order by count(*) desc, a limit 10;
       a       | count 
---------------+-------
               |  1000
 same          |  1000
 scalar        |  1000
 $             |  1000
 samewithnulls |   500
 different1    |     1
 different10   |     1
 different100  |     1
 different1000 |     1
 different101  |     1

-- The hash grouping policies do not support the GroupAggregate mode in the
-- reverse order. We have to filter out the chunk where 'a' is segmentby.
set timescaledb.debug_require_vector_agg to 'forbid';
select a, count(*) from text_table where ts >= 0 group by a order by a desc limit 10;
           a           | count 
-----------------------+-------
 $                     |  1000
 samewithnulls         |   500
 same                  |  1000
 differentwithnulls999 |     1
 differentwithnulls997 |     1
 differentwithnulls995 |     1
 differentwithnulls993 |     1
 differentwithnulls991 |     1
 differentwithnulls99  |     1
 differentwithnulls989 |     1

reset timescaledb.debug_require_vector_agg;
reset enable_sort;
-- with NULLS FIRST
select count(decompress_chunk(x)) from show_chunks('text_table') x;
 count 
-------
     3

alter table text_table set (timescaledb.compress,
    timescaledb.compress_segmentby = '', timescaledb.compress_orderby = 'a nulls first');
select count(compress_chunk(x)) from show_chunks('text_table') x;
 count 
-------
     3

set timescaledb.debug_require_vector_agg to 'require';
select a, count(*) from text_table group by a order by a nulls first limit 10;
       a       | count 
---------------+-------
 $             |  1000
               |  1000
 different1    |     1
 different10   |     1
 different100  |     1
 different1000 |     1
 different101  |     1
 different102  |     1
 different103  |     1
 different104  |     1

reset timescaledb.debug_require_vector_agg;
-- TODO verify that this works with the serialized hash grouping strategy
set timescaledb.debug_require_vector_agg to 'forbid';
select ts, a, count(*) from text_table group by ts, a order by ts, a limit 10;
 ts |       a       | count 
----+---------------+-------
 -1 | scalar        |  1000
  1 |               |  1000
  2 | same          |  1000
  3 | different1    |     1
  3 | different10   |     1
  3 | different100  |     1
  3 | different1000 |     1
  3 | different101  |     1
  3 | different102  |     1
  3 | different103  |     1

select a, ts, count(*) from text_table group by a, ts order by a desc, ts desc limit 10;
           a           | ts | count 
-----------------------+----+-------
 $                     |  5 |   500
 $                     |  4 |   500
 scalar                | -1 |  1000
 samewithnulls         |  4 |   500
 same                  |  2 |  1000
 differentwithnulls999 |  5 |     1
 differentwithnulls997 |  5 |     1
 differentwithnulls995 |  5 |     1
 differentwithnulls993 |  5 |     1
 differentwithnulls991 |  5 |     1

reset timescaledb.debug_require_vector_agg;
reset max_parallel_workers_per_gather;
reset timescaledb.debug_require_vector_agg;
reset enable_hashagg;
