From 471fa58082f0489ff0fab26e7c6a72fbb9e50f50 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Sat, 26 Mar 2016 14:10:52 +1300
Subject: [PATCH 3/5] Add sanity regression tests for new aggregate serialize
 code.

This goes to ensure that the standard set of aggregates match the same
rules as is enforced by CREATE AGGREGATE
---
 src/test/regress/expected/opr_sanity.out | 69 ++++++++++++++++++++++++++++++++
 src/test/regress/sql/opr_sanity.sql      | 47 ++++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index b930f97..32ed078 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -1534,6 +1534,75 @@ WHERE proisagg AND provariadic != 0 AND a.aggkind = 'n';
 -----+---------
 (0 rows)
 
+-- Check that all serial functions have a return type the same as the serial
+-- type.
+SELECT a.aggserialfn,a.aggserialtype,p.prorettype
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggserialfn = p.oid
+WHERE a.aggserialtype <> p.prorettype;
+ aggserialfn | aggserialtype | prorettype 
+-------------+---------------+------------
+(0 rows)
+
+-- Check that all the deserial functions have the same input type as the
+-- serialtype
+SELECT a.aggserialfn,a.aggserialtype,p.proargtypes[0]
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
+WHERE p.proargtypes[0] <> a.aggserialtype;
+ aggserialfn | aggserialtype | proargtypes 
+-------------+---------------+-------------
+(0 rows)
+
+-- An aggregate should either have a complete set of serialtype, serial func
+-- and deserial func, or none of them.
+SELECT aggserialtype,aggserialfn,aggdeserialfn
+FROM pg_aggregate
+WHERE (aggserialtype <> 0 OR aggserialfn <> 0 OR aggdeserialfn <> 0)
+  AND (aggserialtype = 0 OR aggserialfn = 0 OR aggdeserialfn = 0);
+ aggserialtype | aggserialfn | aggdeserialfn 
+---------------+-------------+---------------
+(0 rows)
+
+-- Check that all aggregates with serialtypes have internal states.
+-- (There's no point in serializing anything apart from internal)
+SELECT aggfnoid,aggserialtype,aggtranstype
+FROM pg_aggregate
+WHERE aggserialtype <> 0 AND aggtranstype <> 'internal'::regtype;
+ aggfnoid | aggserialtype | aggtranstype 
+----------+---------------+--------------
+(0 rows)
+
+-- Check that all serial functions are strict. It's wasteful for these to be
+-- called with NULL values.
+SELECT aggfnoid,aggserialfn
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggserialfn = p.oid
+WHERE p.proisstrict = false;
+ aggfnoid | aggserialfn 
+----------+-------------
+(0 rows)
+
+-- Check that all deserial functions are strict. It's wasteful for these to be
+-- called with NULL values.
+SELECT aggfnoid,aggdeserialfn
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
+WHERE p.proisstrict = false;
+ aggfnoid | aggdeserialfn 
+----------+---------------
+(0 rows)
+
+-- Check that no combine functions with an INTERNAL return type are strict.
+SELECT aggfnoid,aggcombinefn
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggcombinefn = p.oid
+INNER JOIN pg_type t ON a.aggtranstype = t.oid
+WHERE t.typname = 'internal' AND p.proisstrict = true;
+ aggfnoid | aggcombinefn 
+----------+--------------
+(0 rows)
+
 -- **************** pg_opfamily ****************
 -- Look for illegal values in pg_opfamily fields
 SELECT p1.oid
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index 60794bc..8d8f413 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -1004,6 +1004,53 @@ SELECT p.oid, proname
 FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid
 WHERE proisagg AND provariadic != 0 AND a.aggkind = 'n';
 
+-- Check that all serial functions have a return type the same as the serial
+-- type.
+SELECT a.aggserialfn,a.aggserialtype,p.prorettype
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggserialfn = p.oid
+WHERE a.aggserialtype <> p.prorettype;
+
+-- Check that all the deserial functions have the same input type as the
+-- serialtype
+SELECT a.aggserialfn,a.aggserialtype,p.proargtypes[0]
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
+WHERE p.proargtypes[0] <> a.aggserialtype;
+
+-- An aggregate should either have a complete set of serialtype, serial func
+-- and deserial func, or none of them.
+SELECT aggserialtype,aggserialfn,aggdeserialfn
+FROM pg_aggregate
+WHERE (aggserialtype <> 0 OR aggserialfn <> 0 OR aggdeserialfn <> 0)
+  AND (aggserialtype = 0 OR aggserialfn = 0 OR aggdeserialfn = 0);
+
+-- Check that all aggregates with serialtypes have internal states.
+-- (There's no point in serializing anything apart from internal)
+SELECT aggfnoid,aggserialtype,aggtranstype
+FROM pg_aggregate
+WHERE aggserialtype <> 0 AND aggtranstype <> 'internal'::regtype;
+
+-- Check that all serial functions are strict. It's wasteful for these to be
+-- called with NULL values.
+SELECT aggfnoid,aggserialfn
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggserialfn = p.oid
+WHERE p.proisstrict = false;
+
+-- Check that all deserial functions are strict. It's wasteful for these to be
+-- called with NULL values.
+SELECT aggfnoid,aggdeserialfn
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggdeserialfn = p.oid
+WHERE p.proisstrict = false;
+
+-- Check that no combine functions with an INTERNAL return type are strict.
+SELECT aggfnoid,aggcombinefn
+FROM pg_aggregate a
+INNER JOIN pg_proc p ON a.aggcombinefn = p.oid
+INNER JOIN pg_type t ON a.aggtranstype = t.oid
+WHERE t.typname = 'internal' AND p.proisstrict = true;
 
 -- **************** pg_opfamily ****************
 
-- 
1.9.5.msysgit.1

