From 8bea1dc29e059513f7bcb7507012d4d13dc06400 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@pgaddict.com>
Date: Sun, 12 Jul 2015 20:30:58 +0200
Subject: [PATCH 23/24] regression tests for cstore

---
 src/test/regress/expected/cstore.out | 367 +++++++++++++++++++++++++++++++++++
 src/test/regress/parallel_schedule   |   2 +-
 src/test/regress/serial_schedule     |   1 +
 src/test/regress/sql/cstore.sql      | 263 +++++++++++++++++++++++++
 4 files changed, 632 insertions(+), 1 deletion(-)
 create mode 100644 src/test/regress/expected/cstore.out
 create mode 100644 src/test/regress/sql/cstore.sql

diff --git a/src/test/regress/expected/cstore.out b/src/test/regress/expected/cstore.out
new file mode 100644
index 0000000..dfe1689
--- /dev/null
+++ b/src/test/regress/expected/cstore.out
@@ -0,0 +1,367 @@
+-- create two fake cstore AM instances (no implementation)
+CREATE COLUMN STORE ACCESS METHOD store_am_one HANDLER cstore_dummy_handler;
+CREATE COLUMN STORE ACCESS METHOD store_am_two HANDLER cstore_dummy_handler;
+-- column-level column store definition
+-- missing USING clause
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE foo,
+    c INT
+);
+ERROR:  syntax error at or near ","
+LINE 3:     b INT COLUMN STORE foo,
+                                  ^
+-- missing column store name
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE USING store_am_one,
+    c INT
+);
+ERROR:  syntax error at or near "USING"
+LINE 3:     b INT COLUMN STORE USING store_am_one,
+                               ^
+-- missing USING and column store name
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE,
+    c INT
+);
+ERROR:  syntax error at or near ","
+LINE 3:     b INT COLUMN STORE,
+                              ^
+-- missing column store name
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE USING store_am_one,
+    c INT
+);
+ERROR:  syntax error at or near "USING"
+LINE 3:     b INT COLUMN STORE USING store_am_one,
+                               ^
+-- unknown name of a column store AM
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE foo USING no_store_am,
+    c INT
+);
+ERROR:  column store access method "no_store_am" does not exist
+-- conflicting column store name
+CREATE TABLE test_columnar_single_conflict (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT COLUMN STORE foo USING store_am_one,
+    d INT
+);
+ERROR:  duplicate column store name "foo"
+-- correct definition (single store) 
+CREATE TABLE test_columnar_single_ok (
+    a INT,
+    b INT COLUMN STORE foo1 USING store_am_one,
+    c INT
+);
+\d test_columnar_single_ok
+Table "public.test_columnar_single_ok"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+Column stores: foo1 USING store_am_one ({b})
+
+-- correct definition (two stores)
+CREATE TABLE test_columnar_single_ok2 (
+    a INT,
+    b INT COLUMN STORE foo1 USING store_am_one,
+    c INT COLUMN STORE foo2 USING store_am_two,
+    d INT
+);
+\d test_columnar_single_ok2
+Table "public.test_columnar_single_ok2"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+ d      | integer | 
+Column stores: foo1 USING store_am_one ({b}),
+               foo2 USING store_am_two ({c})
+
+-- table-level column store definition
+-- no column list
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one
+);
+ERROR:  syntax error at or near ")"
+LINE 7: );
+        ^
+-- empty column list
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one ()
+);
+ERROR:  syntax error at or near ")"
+LINE 6:     COLUMN STORE foo USING store_am_one ()
+                                                 ^
+-- invalid column in store
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one (z)
+);
+ERROR:  no column "z" in the table
+-- unknown name of a column store AM
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING no_store_am (b,c)
+);
+ERROR:  column store access method "no_store_am" does not exist
+-- conflicting column store name
+CREATE TABLE test_columnar_multi_conflict (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one (a,b),
+    COLUMN STORE foo USING store_am_one (c,d)
+);
+ERROR:  duplicate column store name "foo"
+-- overlapping list of columns
+CREATE TABLE test_columnar_multi_conflict2 (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo1 USING store_am_one (a,b),
+    COLUMN STORE foo2 USING store_am_two (b,c,d)
+);
+ERROR:  column already in a store
+-- correct definition (single store) 
+CREATE TABLE test_columnar_multi_ok (
+    a INT,
+    b INT,
+    c INT,
+    COLUMN STORE foo USING store_am_one (a,b)
+);
+\d test_columnar_multi_ok
+Table "public.test_columnar_multi_ok"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+Column stores: foo USING store_am_one ({a,b})
+
+-- correct definition (two stores)
+CREATE TABLE test_columnar_multi_ok2 (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo1 USING store_am_one (a,b),
+    COLUMN STORE foo2 USING store_am_one (c,d)
+);
+\d test_columnar_multi_ok2
+Table "public.test_columnar_multi_ok2"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+ d      | integer | 
+Column stores: foo1 USING store_am_one ({a,b}),
+               foo2 USING store_am_one ({c,d})
+
+-- combination of column-level and table-level column stores
+-- conflicting column store name
+CREATE TABLE test_columnar_multi_conflict (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one (c,d)
+);
+ERROR:  duplicate column store name "foo"
+-- overlapping list of columns
+CREATE TABLE test_columnar_combi_conflict2 (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT,
+    d INT,
+    COLUMN STORE foo2 USING store_am_two (b,c,d)
+);
+ERROR:  column already in a store
+-- correct definition (two stores)
+CREATE TABLE test_columnar_combi_ok (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT,
+    d INT,
+    COLUMN STORE foo2 USING store_am_one (c,d)
+);
+\d test_columnar_combi_ok
+Table "public.test_columnar_combi_ok"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+ d      | integer | 
+Column stores: foo USING store_am_one ({b}),
+               foo2 USING store_am_one ({c,d})
+
+-- test cleanup
+CREATE TABLE cstore_oids AS
+SELECT cststoreid
+  FROM pg_cstore JOIN pg_class ON (pg_cstore.cstrelid = pg_class.oid)
+ WHERE relname IN ('test_columnar_single_ok',
+                   'test_columnar_single_ok2',
+                   'test_columnar_multi_ok',
+                   'test_columnar_multi_ok2',
+                   'test_columnar_combi_ok');
+CREATE TABLE cstore_oids_2 AS
+SELECT pg_class.oid
+  FROM pg_class JOIN cstore_oids ON (pg_class.oid = cstore_oids.cststoreid);
+DROP TABLE test_columnar_single_ok;
+DROP TABLE test_columnar_single_ok2;
+DROP TABLE test_columnar_multi_ok;
+DROP TABLE test_columnar_multi_ok2;
+DROP TABLE test_columnar_combi_ok;
+-- should return 0
+SELECT COUNT(*) FROM pg_class WHERE oid IN (SELECT cststoreid FROM cstore_oids);
+ count 
+-------
+     0
+(1 row)
+
+SELECT COUNT(*) FROM pg_class WHERE oid IN (SELECT oid FROM cstore_oids_2);
+ count 
+-------
+     0
+(1 row)
+
+SELECT COUNT(*) FROM pg_cstore WHERE cststoreid IN (SELECT oid FROM cstore_oids);
+ count 
+-------
+     0
+(1 row)
+
+SELECT COUNT(*) FROM pg_attribute WHERE attrelid IN (SELECT cststoreid FROM cstore_oids);
+ count 
+-------
+     0
+(1 row)
+
+SELECT COUNT(*) FROM pg_attribute WHERE attrelid IN (SELECT oid FROM cstore_oids_2);
+ count 
+-------
+     0
+(1 row)
+
+DROP TABLE cstore_oids;
+DROP TABLE cstore_oids_2;
+-- INHERITANCE
+-- parent table with two column stores
+CREATE TABLE parent_table (
+    a INT,
+    b INT COLUMN STORE foo1 USING store_am_one,
+    c INT,
+    d INT,
+    e INT,
+    COLUMN STORE foo2 USING store_am_two (d,e)
+);
+-- child table with two separate column stores
+CREATE TABLE child_table_1 (
+    f INT,
+    g INT COLUMN STORE foo1c USING store_am_one,
+    h INT,
+    i INT,
+    COLUMN STORE foo2c USING store_am_two(h,i)
+) INHERITS (parent_table);
+-- FIXME BUG: should have cstores foo1 and foo2
+\d child_table_1
+ Table "public.child_table_1"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+ d      | integer | 
+ e      | integer | 
+ f      | integer | 
+ g      | integer | 
+ h      | integer | 
+ i      | integer | 
+Inherits: parent_table
+Column stores: foo1c USING store_am_one ({g}),
+               foo2c USING store_am_two ({h,i})
+
+-- child table with two column stores - one modifying, one redefining the parent
+CREATE TABLE child_table_2 (
+    f INT,
+    g INT COLUMN STORE foo1c USING store_am_one, -- new column store
+    h INT,
+    i INT,
+    COLUMN STORE foo2c USING store_am_two(b,h,i) -- redefines the parent colstore
+) INHERITS (parent_table);
+\d child_table_2
+ Table "public.child_table_2"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+ d      | integer | 
+ e      | integer | 
+ f      | integer | 
+ g      | integer | 
+ h      | integer | 
+ i      | integer | 
+Inherits: parent_table
+Column stores: foo2c USING store_am_two ({b,h,i}),
+               foo1c USING store_am_one ({g})
+
+-- child table with a single column store of the whole table
+CREATE TABLE child_table_3 (
+    f INT,
+    g INT,
+    h INT,
+    i INT,
+    COLUMN STORE foo1 USING store_am_one(a,b,c,d,e,f,g,h,i)
+) INHERITS (parent_table);
+\d child_table_3
+ Table "public.child_table_3"
+ Column |  Type   | Modifiers 
+--------+---------+-----------
+ a      | integer | 
+ b      | integer | 
+ c      | integer | 
+ d      | integer | 
+ e      | integer | 
+ f      | integer | 
+ g      | integer | 
+ h      | integer | 
+ i      | integer | 
+Inherits: parent_table
+Column stores: foo1 USING store_am_one ({a,b,c,d,e,f,g,h,i})
+
+--- FIXME -- add tests with multiple inheritance
+DROP TABLE parent_table CASCADE;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table child_table_1
+drop cascades to table child_table_2
+drop cascades to table child_table_3
+--- delete the fake cstore AM records
+-- FIXME -- this should be a DROP command
+DELETE FROM pg_cstore_am WHERE cstamname IN ('store_am_one', 'store_am_two');
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 6fc5d1e..352c92e 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -60,7 +60,7 @@ test: create_index create_view
 # ----------
 # Another group of parallel tests
 # ----------
-test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames roleattributes
+test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames roleattributes cstore
 
 # ----------
 # sanity_check does a vacuum, affecting the sort order of SELECT *
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 2ae51cf..164d836 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -74,6 +74,7 @@ test: drop_if_exists
 test: updatable_views
 test: rolenames
 test: roleattributes
+test: cstore
 test: sanity_check
 test: errors
 test: select
diff --git a/src/test/regress/sql/cstore.sql b/src/test/regress/sql/cstore.sql
new file mode 100644
index 0000000..aa589b4
--- /dev/null
+++ b/src/test/regress/sql/cstore.sql
@@ -0,0 +1,263 @@
+-- create two fake cstore AM instances (no implementation)
+CREATE COLUMN STORE ACCESS METHOD store_am_one HANDLER cstore_dummy_handler;
+CREATE COLUMN STORE ACCESS METHOD store_am_two HANDLER cstore_dummy_handler;
+
+-- column-level column store definition
+
+-- missing USING clause
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE foo,
+    c INT
+);
+
+-- missing column store name
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE USING store_am_one,
+    c INT
+);
+
+-- missing USING and column store name
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE,
+    c INT
+);
+
+-- missing column store name
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE USING store_am_one,
+    c INT
+);
+
+-- unknown name of a column store AM
+CREATE TABLE test_columnar_single_missing (
+    a INT,
+    b INT COLUMN STORE foo USING no_store_am,
+    c INT
+);
+
+-- conflicting column store name
+CREATE TABLE test_columnar_single_conflict (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT COLUMN STORE foo USING store_am_one,
+    d INT
+);
+
+-- correct definition (single store) 
+CREATE TABLE test_columnar_single_ok (
+    a INT,
+    b INT COLUMN STORE foo1 USING store_am_one,
+    c INT
+);
+
+\d test_columnar_single_ok
+
+-- correct definition (two stores)
+CREATE TABLE test_columnar_single_ok2 (
+    a INT,
+    b INT COLUMN STORE foo1 USING store_am_one,
+    c INT COLUMN STORE foo2 USING store_am_two,
+    d INT
+);
+
+\d test_columnar_single_ok2
+
+-- table-level column store definition
+
+-- no column list
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one
+);
+
+-- empty column list
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one ()
+);
+
+-- invalid column in store
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one (z)
+);
+
+-- unknown name of a column store AM
+CREATE TABLE test_columnar_multi_missing (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING no_store_am (b,c)
+);
+
+-- conflicting column store name
+CREATE TABLE test_columnar_multi_conflict (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one (a,b),
+    COLUMN STORE foo USING store_am_one (c,d)
+);
+
+-- overlapping list of columns
+CREATE TABLE test_columnar_multi_conflict2 (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo1 USING store_am_one (a,b),
+    COLUMN STORE foo2 USING store_am_two (b,c,d)
+);
+
+-- correct definition (single store) 
+CREATE TABLE test_columnar_multi_ok (
+    a INT,
+    b INT,
+    c INT,
+    COLUMN STORE foo USING store_am_one (a,b)
+);
+
+\d test_columnar_multi_ok
+
+-- correct definition (two stores)
+CREATE TABLE test_columnar_multi_ok2 (
+    a INT,
+    b INT,
+    c INT,
+    d INT,
+    COLUMN STORE foo1 USING store_am_one (a,b),
+    COLUMN STORE foo2 USING store_am_one (c,d)
+);
+
+\d test_columnar_multi_ok2
+
+-- combination of column-level and table-level column stores
+
+-- conflicting column store name
+CREATE TABLE test_columnar_multi_conflict (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT,
+    d INT,
+    COLUMN STORE foo USING store_am_one (c,d)
+);
+
+-- overlapping list of columns
+CREATE TABLE test_columnar_combi_conflict2 (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT,
+    d INT,
+    COLUMN STORE foo2 USING store_am_two (b,c,d)
+);
+
+-- correct definition (two stores)
+CREATE TABLE test_columnar_combi_ok (
+    a INT,
+    b INT COLUMN STORE foo USING store_am_one,
+    c INT,
+    d INT,
+    COLUMN STORE foo2 USING store_am_one (c,d)
+);
+
+\d test_columnar_combi_ok
+
+-- test cleanup
+CREATE TABLE cstore_oids AS
+SELECT cststoreid
+  FROM pg_cstore JOIN pg_class ON (pg_cstore.cstrelid = pg_class.oid)
+ WHERE relname IN ('test_columnar_single_ok',
+                   'test_columnar_single_ok2',
+                   'test_columnar_multi_ok',
+                   'test_columnar_multi_ok2',
+                   'test_columnar_combi_ok');
+
+CREATE TABLE cstore_oids_2 AS
+SELECT pg_class.oid
+  FROM pg_class JOIN cstore_oids ON (pg_class.oid = cstore_oids.cststoreid);
+
+DROP TABLE test_columnar_single_ok;
+DROP TABLE test_columnar_single_ok2;
+DROP TABLE test_columnar_multi_ok;
+DROP TABLE test_columnar_multi_ok2;
+DROP TABLE test_columnar_combi_ok;
+
+-- should return 0
+SELECT COUNT(*) FROM pg_class WHERE oid IN (SELECT cststoreid FROM cstore_oids);
+SELECT COUNT(*) FROM pg_class WHERE oid IN (SELECT oid FROM cstore_oids_2);
+
+SELECT COUNT(*) FROM pg_cstore WHERE cststoreid IN (SELECT oid FROM cstore_oids);
+
+SELECT COUNT(*) FROM pg_attribute WHERE attrelid IN (SELECT cststoreid FROM cstore_oids);
+SELECT COUNT(*) FROM pg_attribute WHERE attrelid IN (SELECT oid FROM cstore_oids_2);
+
+DROP TABLE cstore_oids;
+DROP TABLE cstore_oids_2;
+
+-- INHERITANCE
+
+-- parent table with two column stores
+CREATE TABLE parent_table (
+    a INT,
+    b INT COLUMN STORE foo1 USING store_am_one,
+    c INT,
+    d INT,
+    e INT,
+    COLUMN STORE foo2 USING store_am_two (d,e)
+);
+
+-- child table with two separate column stores
+CREATE TABLE child_table_1 (
+    f INT,
+    g INT COLUMN STORE foo1c USING store_am_one,
+    h INT,
+    i INT,
+    COLUMN STORE foo2c USING store_am_two(h,i)
+) INHERITS (parent_table);
+-- FIXME BUG: should have cstores foo1 and foo2
+\d child_table_1
+
+-- child table with two column stores - one modifying, one redefining the parent
+CREATE TABLE child_table_2 (
+    f INT,
+    g INT COLUMN STORE foo1c USING store_am_one, -- new column store
+    h INT,
+    i INT,
+    COLUMN STORE foo2c USING store_am_two(b,h,i) -- redefines the parent colstore
+) INHERITS (parent_table);
+
+\d child_table_2
+
+-- child table with a single column store of the whole table
+CREATE TABLE child_table_3 (
+    f INT,
+    g INT,
+    h INT,
+    i INT,
+    COLUMN STORE foo1 USING store_am_one(a,b,c,d,e,f,g,h,i)
+) INHERITS (parent_table);
+
+\d child_table_3
+
+--- FIXME -- add tests with multiple inheritance
+
+DROP TABLE parent_table CASCADE;
+
+--- delete the fake cstore AM records
+-- FIXME -- this should be a DROP command
+DELETE FROM pg_cstore_am WHERE cstamname IN ('store_am_one', 'store_am_two');
-- 
2.1.4

