--
-- AGGREGATES
--
SELECT avg(four) AS avg_1 FROM onek;
       avg_1        
--------------------
 1.5000000000000000
(1 row)

SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100;
       avg_32        
---------------------
 32.6666666666666667
(1 row)

-- In 7.1, avg(float4) is computed using float8 arithmetic.
-- Round the result to 3 digits to avoid platform-specific results.
SELECT avg(b)::numeric(10,3) AS avg_107_943 FROM aggtest;
 avg_107_943 
-------------
     107.943
(1 row)

SELECT avg(gpa) AS avg_3_4 FROM ONLY student;
 avg_3_4 
---------
     3.4
(1 row)

SELECT sum(four) AS sum_1500 FROM onek;
 sum_1500 
----------
     1500
(1 row)

SELECT sum(a) AS sum_198 FROM aggtest;
 sum_198 
---------
     198
(1 row)

SELECT sum(b) AS avg_431_773 FROM aggtest;
 avg_431_773 
-------------
     431.773
(1 row)

SELECT sum(gpa) AS avg_6_8 FROM ONLY student;
 avg_6_8 
---------
     6.8
(1 row)

SELECT max(four) AS max_3 FROM onek;
 max_3 
-------
     3
(1 row)

SELECT max(a) AS max_100 FROM aggtest;
 max_100 
---------
     100
(1 row)

SELECT max(aggtest.b) AS max_324_78 FROM aggtest;
 max_324_78 
------------
     324.78
(1 row)

SELECT max(student.gpa) AS max_3_7 FROM student;
 max_3_7 
---------
     3.7
(1 row)

SELECT stddev_pop(b) FROM aggtest;
   stddev_pop    
-----------------
 131.10703231895
(1 row)

SELECT stddev_samp(b) FROM aggtest;
   stddev_samp    
------------------
 151.389360803998
(1 row)

SELECT var_pop(b) FROM aggtest;
     var_pop      
------------------
 17189.0539234823
(1 row)

SELECT var_samp(b) FROM aggtest;
     var_samp     
------------------
 22918.7385646431
(1 row)

SELECT stddev_pop(b::numeric) FROM aggtest;
    stddev_pop    
------------------
 131.107032862199
(1 row)

SELECT stddev_samp(b::numeric) FROM aggtest;
   stddev_samp    
------------------
 151.389361431288
(1 row)

SELECT var_pop(b::numeric) FROM aggtest;
      var_pop       
--------------------
 17189.054065929769
(1 row)

SELECT var_samp(b::numeric) FROM aggtest;
      var_samp      
--------------------
 22918.738754573025
(1 row)

-- population variance is defined for a single tuple, sample variance
-- is not
SELECT var_pop(1.0), var_samp(2.0);
 var_pop | var_samp 
---------+----------
       0 |         
(1 row)

SELECT stddev_pop(3.0::numeric), stddev_samp(4.0::numeric);
 stddev_pop | stddev_samp 
------------+-------------
          0 |            
(1 row)

-- SQL2003 binary aggregates
SELECT regr_count(b, a) FROM aggtest;
 regr_count 
------------
          4
(1 row)

SELECT regr_sxx(b, a) FROM aggtest;
 regr_sxx 
----------
     5099
(1 row)

SELECT regr_syy(b, a) FROM aggtest;
     regr_syy     
------------------
 68756.2156939293
(1 row)

SELECT regr_sxy(b, a) FROM aggtest;
     regr_sxy     
------------------
 2614.51582155004
(1 row)

SELECT regr_avgx(b, a), regr_avgy(b, a) FROM aggtest;
 regr_avgx |    regr_avgy     
-----------+------------------
      49.5 | 107.943152273074
(1 row)

SELECT regr_r2(b, a) FROM aggtest;
      regr_r2       
--------------------
 0.0194977982031803
(1 row)

SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest;
    regr_slope     |  regr_intercept  
-------------------+------------------
 0.512750700441271 | 82.5619926012309
(1 row)

SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest;
    covar_pop    |    covar_samp    
-----------------+------------------
 653.62895538751 | 871.505273850014
(1 row)

SELECT corr(b, a) FROM aggtest;
       corr        
-------------------
 0.139634516517873
(1 row)

SELECT count(four) AS cnt_1000 FROM onek;
 cnt_1000 
----------
     1000
(1 row)

SELECT count(DISTINCT four) AS cnt_4 FROM onek;
 cnt_4 
-------
     4
(1 row)

select ten, count(*), sum(four) from onek
group by ten order by ten;
 ten | count | sum 
-----+-------+-----
   0 |   100 | 100
   1 |   100 | 200
   2 |   100 | 100
   3 |   100 | 200
   4 |   100 | 100
   5 |   100 | 200
   6 |   100 | 100
   7 |   100 | 200
   8 |   100 | 100
   9 |   100 | 200
(10 rows)

select ten, count(four), sum(DISTINCT four) from onek
group by ten order by ten;
 ten | count | sum 
-----+-------+-----
   0 |   100 |   2
   1 |   100 |   4
   2 |   100 |   2
   3 |   100 |   4
   4 |   100 |   2
   5 |   100 |   4
   6 |   100 |   2
   7 |   100 |   4
   8 |   100 |   2
   9 |   100 |   4
(10 rows)

-- user-defined aggregates
SELECT newavg(four) AS avg_1 FROM onek;
       avg_1        
--------------------
 1.5000000000000000
(1 row)

SELECT newsum(four) AS sum_1500 FROM onek;
 sum_1500 
----------
     1500
(1 row)

SELECT newcnt(four) AS cnt_1000 FROM onek;
 cnt_1000 
----------
     1000
(1 row)

SELECT newcnt(*) AS cnt_1000 FROM onek;
 cnt_1000 
----------
     1000
(1 row)

SELECT oldcnt(*) AS cnt_1000 FROM onek;
 cnt_1000 
----------
     1000
(1 row)

SELECT sum2(q1,q2) FROM int8_tbl;
       sum2        
-------------------
 18271560493827981
(1 row)

-- test for outer-level aggregates
-- this should work
select ten, sum(distinct four) from onek a
group by ten
having exists (select 1 from onek b where sum(distinct a.four) = b.four);
 ten | sum 
-----+-----
   0 |   2
   2 |   2
   4 |   2
   6 |   2
   8 |   2
(5 rows)

-- this should fail because subquery has an agg of its own in WHERE
select ten, sum(distinct four) from onek a
group by ten
having exists (select 1 from onek b
               where sum(distinct a.four + b.four) = b.four);
ERROR:  aggregates not allowed in WHERE clause
LINE 4:                where sum(distinct a.four + b.four) = b.four)...
                             ^
-- Test handling of sublinks within outer-level aggregates.
-- Per bug report from Daniel Grace.
select
  (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)))
from tenk1 o;
 ?column? 
----------
     9999
(1 row)

--
-- test for bitwise integer aggregates
--
CREATE TEMPORARY TABLE bitwise_test(
  i2 INT2,
  i4 INT4,
  i8 INT8,
  i INTEGER,
  x INT2,
  y BIT(4)
);
-- empty case
SELECT 
  BIT_AND(i2) AS "?",
  BIT_OR(i4)  AS "?"
FROM bitwise_test;
 ? | ? 
---+---
   |  
(1 row)

COPY bitwise_test FROM STDIN NULL 'null';
SELECT
  BIT_AND(i2) AS "1",
  BIT_AND(i4) AS "1",
  BIT_AND(i8) AS "1",
  BIT_AND(i)  AS "?",
  BIT_AND(x)  AS "0",
  BIT_AND(y)  AS "0100",
  BIT_OR(i2)  AS "7",
  BIT_OR(i4)  AS "7",
  BIT_OR(i8)  AS "7",
  BIT_OR(i)   AS "?",
  BIT_OR(x)   AS "7",
  BIT_OR(y)   AS "1101"
FROM bitwise_test;
 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 
---+---+---+---+---+------+---+---+---+---+---+------
 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101
(1 row)

--
-- test boolean aggregates
--
-- first test all possible transition and final states
SELECT
  -- boolean and transitions
  -- null because strict
  booland_statefunc(NULL, NULL)  IS NULL AS "t",
  booland_statefunc(TRUE, NULL)  IS NULL AS "t",
  booland_statefunc(FALSE, NULL) IS NULL AS "t",
  booland_statefunc(NULL, TRUE)  IS NULL AS "t",
  booland_statefunc(NULL, FALSE) IS NULL AS "t",
  -- and actual computations
  booland_statefunc(TRUE, TRUE) AS "t",
  NOT booland_statefunc(TRUE, FALSE) AS "t",
  NOT booland_statefunc(FALSE, TRUE) AS "t",
  NOT booland_statefunc(FALSE, FALSE) AS "t";
 t | t | t | t | t | t | t | t | t 
---+---+---+---+---+---+---+---+---
 t | t | t | t | t | t | t | t | t
(1 row)

SELECT
  -- boolean or transitions
  -- null because strict
  boolor_statefunc(NULL, NULL)  IS NULL AS "t",
  boolor_statefunc(TRUE, NULL)  IS NULL AS "t",
  boolor_statefunc(FALSE, NULL) IS NULL AS "t",
  boolor_statefunc(NULL, TRUE)  IS NULL AS "t",
  boolor_statefunc(NULL, FALSE) IS NULL AS "t",
  -- actual computations
  boolor_statefunc(TRUE, TRUE) AS "t",
  boolor_statefunc(TRUE, FALSE) AS "t",
  boolor_statefunc(FALSE, TRUE) AS "t",
  NOT boolor_statefunc(FALSE, FALSE) AS "t";
 t | t | t | t | t | t | t | t | t 
---+---+---+---+---+---+---+---+---
 t | t | t | t | t | t | t | t | t
(1 row)

CREATE TEMPORARY TABLE bool_test(  
  b1 BOOL,
  b2 BOOL,
  b3 BOOL,
  b4 BOOL);
-- empty case
SELECT
  BOOL_AND(b1)   AS "n",
  BOOL_OR(b3)    AS "n"
FROM bool_test;
 n | n 
---+---
   | 
(1 row)

COPY bool_test FROM STDIN NULL 'null';
SELECT
  BOOL_AND(b1)     AS "f",
  BOOL_AND(b2)     AS "t",
  BOOL_AND(b3)     AS "f",
  BOOL_AND(b4)     AS "n",
  BOOL_AND(NOT b2) AS "f",
  BOOL_AND(NOT b3) AS "t"
FROM bool_test;
 f | t | f | n | f | t 
---+---+---+---+---+---
 f | t | f |   | f | t
(1 row)

SELECT
  EVERY(b1)     AS "f",
  EVERY(b2)     AS "t",
  EVERY(b3)     AS "f",
  EVERY(b4)     AS "n",
  EVERY(NOT b2) AS "f",
  EVERY(NOT b3) AS "t"
FROM bool_test;
 f | t | f | n | f | t 
---+---+---+---+---+---
 f | t | f |   | f | t
(1 row)

SELECT
  BOOL_OR(b1)      AS "t",
  BOOL_OR(b2)      AS "t",
  BOOL_OR(b3)      AS "f",
  BOOL_OR(b4)      AS "n",
  BOOL_OR(NOT b2)  AS "f",
  BOOL_OR(NOT b3)  AS "t"
FROM bool_test;
 t | t | f | n | f | t 
---+---+---+---+---+---
 t | t | f |   | f | t
(1 row)

--
-- Test several cases that should be optimized into indexscans instead of
-- the generic aggregate implementation.  We can't actually verify that they
-- are done as indexscans, but we can check that the results are correct.
--
-- Basic cases
select max(unique1) from tenk1;
 max  
------
 9999
(1 row)

select max(unique1) from tenk1 where unique1 < 42;
 max 
-----
  41
(1 row)

select max(unique1) from tenk1 where unique1 > 42;
 max  
------
 9999
(1 row)

select max(unique1) from tenk1 where unique1 > 42000;
 max 
-----
    
(1 row)

-- multi-column index (uses tenk1_thous_tenthous)
select max(tenthous) from tenk1 where thousand = 33;
 max  
------
 9033
(1 row)

select min(tenthous) from tenk1 where thousand = 33;
 min 
-----
  33
(1 row)

-- check parameter propagation into an indexscan subquery
select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt
from int4_tbl;
     f1      | gt 
-------------+----
           0 |  1
      123456 |   
     -123456 |  0
  2147483647 |   
 -2147483647 |  0
(5 rows)

-- check some cases that were handled incorrectly in 8.3.0
select distinct max(unique2) from tenk1;
 max  
------
 9999
(1 row)

select max(unique2) from tenk1 order by 1;
 max  
------
 9999
(1 row)

select max(unique2) from tenk1 order by max(unique2);
 max  
------
 9999
(1 row)

select max(unique2) from tenk1 order by max(unique2)+1;
 max  
------
 9999
(1 row)

select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
 max  | g 
------+---
 9999 | 3
 9999 | 2
 9999 | 1
(3 rows)

