-- 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.
\c :TEST_DBNAME :ROLE_SUPERUSER
-- Uncomment these two settings to run this test with hypercore TAM
--set timescaledb.default_hypercore_use_access_method=true;
--set enable_indexscan=off;
create function stable_abs(x int4) returns int4 as 'int4abs' language internal stable;
create table dvagg(a int, b int);
select create_hypertable('dvagg', 'a', chunk_time_interval => 1000);
 create_hypertable  
--------------------
 (1,public,dvagg,t)

insert into dvagg select x, x % 5 from generate_series(1, 999) x;
alter table dvagg set (timescaledb.compress);
select compress_chunk(show_chunks('dvagg'));
             compress_chunk             
----------------------------------------
 _timescaledb_internal._hyper_1_1_chunk

alter table dvagg add column c int default 7;
insert into dvagg select x, x % 5, 11 from generate_series(1001, 1999) x;
select compress_chunk(show_chunks('dvagg'));
NOTICE:  chunk "_hyper_1_1_chunk" is already converted to columnstore
             compress_chunk             
----------------------------------------
 _timescaledb_internal._hyper_1_1_chunk
 _timescaledb_internal._hyper_1_3_chunk

vacuum analyze dvagg;
-- Just the most basic vectorized aggregation query on a table with default
-- compressed column.
explain (buffers off, costs off) select sum(c) from dvagg;
--- QUERY PLAN ---
 Finalize Aggregate
   ->  Append
         ->  Custom Scan (VectorAgg)
               ->  Custom Scan (ColumnarScan) on _hyper_1_1_chunk
                     ->  Seq Scan on compress_hyper_2_2_chunk
         ->  Custom Scan (VectorAgg)
               ->  Custom Scan (ColumnarScan) on _hyper_1_3_chunk
                     ->  Seq Scan on compress_hyper_2_4_chunk

select sum(c) from dvagg;
  sum  
-------
 17982

set timescaledb.debug_require_vector_agg = 'require';
---- Uncomment to generate reference
--set timescaledb.debug_require_vector_agg = 'forbid';
--set timescaledb.enable_vectorized_aggregation to off;
-- Vectorized aggregation should work with vectorized filters.
select sum(c) from dvagg where b >= 0;
  sum  
-------
 17982

select sum(c) from dvagg where b = 0;
 sum  
------
 3582

select sum(c) from dvagg where b in (0, 1);
 sum  
------
 7182

select sum(c) from dvagg where b in (0, 1, 3);
  sum  
-------
 10782

select sum(c) from dvagg where b > 10;
 sum 
-----
    

select count(*) from dvagg where b >= 0;
 count 
-------
  1998

select count(*) from dvagg where b = 0;
 count 
-------
   398

select count(*) from dvagg where b in (0, 1);
 count 
-------
   798

select count(*) from dvagg where b in (0, 1, 3);
 count 
-------
  1198

select count(*) from dvagg where b > 10;
 count 
-------
     0

explain (buffers off, costs off) select sum(c) from dvagg where b in (0, 1, 3);
--- QUERY PLAN ---
 Finalize Aggregate
   ->  Append
         ->  Custom Scan (VectorAgg)
               ->  Custom Scan (ColumnarScan) on _hyper_1_1_chunk
                     Vectorized Filter: (b = ANY ('{0,1,3}'::integer[]))
                     ->  Seq Scan on compress_hyper_2_2_chunk
         ->  Custom Scan (VectorAgg)
               ->  Custom Scan (ColumnarScan) on _hyper_1_3_chunk
                     Vectorized Filter: (b = ANY ('{0,1,3}'::integer[]))
                     ->  Seq Scan on compress_hyper_2_4_chunk

select sum(a), sum(b), sum(c) from dvagg where b in (0, 1, 3);
   sum   | sum  |  sum  
---------+------+-------
 1197600 | 1600 | 10782

explain (buffers off, costs off) select sum(a), sum(b), sum(c) from dvagg where b in (0, 1, 3);
--- QUERY PLAN ---
 Finalize Aggregate
   ->  Append
         ->  Custom Scan (VectorAgg)
               ->  Custom Scan (ColumnarScan) on _hyper_1_1_chunk
                     Vectorized Filter: (b = ANY ('{0,1,3}'::integer[]))
                     ->  Seq Scan on compress_hyper_2_2_chunk
         ->  Custom Scan (VectorAgg)
               ->  Custom Scan (ColumnarScan) on _hyper_1_3_chunk
                     Vectorized Filter: (b = ANY ('{0,1,3}'::integer[]))
                     ->  Seq Scan on compress_hyper_2_4_chunk

reset timescaledb.enable_vectorized_aggregation;
-- The runtime chunk exclusion should work.
explain (buffers off, costs off) select sum(c) from dvagg where a < stable_abs(1000);
--- QUERY PLAN ---
 Finalize Aggregate
   ->  Custom Scan (ChunkAppend) on dvagg
         Chunks excluded during startup: 1
         ->  Custom Scan (VectorAgg)
               ->  Custom Scan (ColumnarScan) on _hyper_1_1_chunk
                     Vectorized Filter: (a < stable_abs(1000))
                     ->  Seq Scan on compress_hyper_2_2_chunk
                           Filter: (_ts_meta_min_1 < stable_abs(1000))

-- The case with HAVING can still be vectorized because it is applied after
-- final aggregation.
select sum(c) from dvagg having sum(c) > 0;
  sum  
-------
 17982

-- Some negative cases.
set timescaledb.debug_require_vector_agg to 'forbid';
explain (buffers off, costs off) select sum(c) from dvagg group by grouping sets ((), (a));
--- QUERY PLAN ---
 MixedAggregate
   Hash Key: dvagg.a
   Group Key: ()
   ->  Append
         ->  Custom Scan (ColumnarScan) on _hyper_1_1_chunk
               ->  Seq Scan on compress_hyper_2_2_chunk
         ->  Custom Scan (ColumnarScan) on _hyper_1_3_chunk
               ->  Seq Scan on compress_hyper_2_4_chunk

-- As a reference, the result on decompressed table.
select decompress_chunk(show_chunks('dvagg'));
            decompress_chunk            
----------------------------------------
 _timescaledb_internal._hyper_1_1_chunk
 _timescaledb_internal._hyper_1_3_chunk

select sum(c) from dvagg;
  sum  
-------
 17982

drop table dvagg;
