diff --git a/src/test/regress/expected/alter_distribution_policy.out b/src/test/regress/expected/alter_distribution_policy.out index 20b3f6fded38a7afd62bd1177a617fe24975b532..e2f72c1502ba250bbaa3f4ece08eaec9f7f99284 100644 --- a/src/test/regress/expected/alter_distribution_policy.out +++ b/src/test/regress/expected/alter_distribution_policy.out @@ -117,19 +117,15 @@ select * from atsdb where i = 1; drop table atsdb; -- Now try AO -create table atsdb_ao (i int, j text) distributed by (i); +create table atsdb_ao (i int, j text) with (appendonly=true) distributed by (i); insert into atsdb_ao select i, (i+1)::text from generate_series(1, 100) i; insert into atsdb_ao select i, (i+1)::text from generate_series(1, 100) i; -- check that we're an AO table -explain select count(*) from atsdb_ao; - QUERY PLAN ---------------------------------------------------------------------------- - Aggregate (cost=3.31..3.32 rows=1 width=0) - -> Gather Motion 2:1 (slice1) (cost=3.25..3.29 rows=1 width=0) - -> Aggregate (cost=3.25..3.26 rows=0 width=0) - -> Seq Scan on atsdb_ao (cost=0.00..3.00 rows=50 width=0) - Settings: enable_seqscan=off -(5 rows) +select count(*) from pg_appendonly where relid='atsdb_ao'::regclass; + count +------- + 1 +(1 row) select count(*) from atsdb_ao; count @@ -139,15 +135,11 @@ select count(*) from atsdb_ao; alter table atsdb_ao set distributed by (j); -- Still AO? -explain select count(*) from atsdb_ao; - QUERY PLAN ---------------------------------------------------------------------------- - Aggregate (cost=3.31..3.32 rows=1 width=0) - -> Gather Motion 2:1 (slice1) (cost=3.25..3.29 rows=1 width=0) - -> Aggregate (cost=3.25..3.26 rows=0 width=0) - -> Seq Scan on atsdb_ao (cost=0.00..3.00 rows=50 width=0) - Settings: enable_seqscan=off -(5 rows) +select count(*) from pg_appendonly where relid='atsdb_ao'::regclass; + count +------- + 1 +(1 row) select count(*) from atsdb_ao; count @@ -155,6 +147,16 @@ select count(*) from atsdb_ao; 200 (1 row) +-- check alter, vacuum analyze, and then alter +delete from atsdb_ao where i = any(array(select generate_series(1,90))); +vacuum analyze atsdb_ao; +alter table atsdb_ao set distributed randomly; +select count(*) from atsdb_ao; + count +------- + 20 +(1 row) + drop table atsdb_ao; -- Check divergent distribution policies for partitioning. create table atsdb (i int, j int, k int) distributed by (i) partition by range(k) diff --git a/src/test/regress/expected/alter_distribution_policy_optimizer.out b/src/test/regress/expected/alter_distribution_policy_optimizer.out index b5070d26f8bfc7f8d98a4d58eb2cafd6f69b6956..d4d5954c5773f42cf037998b7cf705d97450e26e 100644 --- a/src/test/regress/expected/alter_distribution_policy_optimizer.out +++ b/src/test/regress/expected/alter_distribution_policy_optimizer.out @@ -117,19 +117,15 @@ select * from atsdb where i = 1; drop table atsdb; -- Now try AO -create table atsdb_ao (i int, j text) distributed by (i); +create table atsdb_ao (i int, j text) with (appendonly=true) distributed by (i); insert into atsdb_ao select i, (i+1)::text from generate_series(1, 100) i; insert into atsdb_ao select i, (i+1)::text from generate_series(1, 100) i; -- check that we're an AO table -explain select count(*) from atsdb_ao; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate (cost=0.00..434.00 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..433.00 rows=1 width=8) - -> Aggregate (cost=0.00..432.00 rows=1 width=8) - -> Table Scan on atsdb_ao (cost=0.00..431.00 rows=34 width=1) - Settings: enable_seqscan=off; optimizer=on -(5 rows) +select count(*) from pg_appendonly where relid='atsdb_ao'::regclass; + count +------- + 1 +(1 row) select count(*) from atsdb_ao; count @@ -139,15 +135,11 @@ select count(*) from atsdb_ao; alter table atsdb_ao set distributed by (j); -- Still AO? -explain select count(*) from atsdb_ao; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate (cost=0.00..434.00 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..433.00 rows=1 width=8) - -> Aggregate (cost=0.00..432.00 rows=1 width=8) - -> Table Scan on atsdb_ao (cost=0.00..431.00 rows=34 width=1) - Settings: enable_seqscan=off; optimizer=on -(5 rows) +select count(*) from pg_appendonly where relid='atsdb_ao'::regclass; + count +------- + 1 +(1 row) select count(*) from atsdb_ao; count @@ -155,6 +147,16 @@ select count(*) from atsdb_ao; 200 (1 row) +-- check alter, vacuum analyze, and then alter +delete from atsdb_ao where i = any(array(select generate_series(1,90))); +vacuum analyze atsdb_ao; +alter table atsdb_ao set distributed randomly; +select count(*) from atsdb_ao; + count +------- + 20 +(1 row) + drop table atsdb_ao; -- Check divergent distribution policies for partitioning. create table atsdb (i int, j int, k int) distributed by (i) partition by range(k) diff --git a/src/test/regress/expected/alter_table_aocs.out b/src/test/regress/expected/alter_table_aocs.out index d06eb11359ad392a9a7f320c38836a15857d9754..4c8a670e2d80b35019a10e50168faed82fe45e71 100644 --- a/src/test/regress/expected/alter_table_aocs.out +++ b/src/test/regress/expected/alter_table_aocs.out @@ -1,6 +1,6 @@ set optimizer_disable_missing_stats_collection = on; -- --- This test case covers basic ADD COLUMN functionality for AOCS relations. +-- This test case covers ALTER functionality for AOCS relations. -- -- -- Switching on these gucs may be helpful in the event of failures. @@ -423,9 +423,114 @@ Append-Only Columnar Table "aocs_addcol.addcol8" Checksum: t Distributed by: (a) +-- try renaming table and see if stuff still works +alter table addcol1 rename to addcol1_renamed; +alter table addcol1_renamed add column new_column int default 10; +alter table addcol1_renamed alter column new_column set not null; +alter table addcol1_renamed add column new_column2 int not null; -- should fail +ERROR: ADD COLUMN with no default value in append-only tables is not yet supported. +select count(*) from addcol1_renamed; + count +------- + 46 +(1 row) + +alter table addcol1_renamed drop column new_column; +alter table addcol1_renamed rename to addcol1; +-- try renaming columns and see if stuff still works +alter table addcol1 rename column f to f_renamed; +alter table addcol1 alter column f_renamed set default 10; +insert into addcol1 values (999); +select a, f_renamed from addcol1 where a = 999; + a | f_renamed +-----+----------- + 999 | 10 +(1 row) + +-- try dropping and adding back the column +alter table addcol1 drop column f_renamed; +alter table addcol1 add column f_renamed int default 20; +select a, f_renamed from addcol1 where a = 999; + a | f_renamed +-----+----------- + 999 | 20 +(1 row) + +-- try altering statistics of a column +alter table addcol1 alter column f_renamed set statistics 1000; +select attstattarget from pg_attribute where attrelid = 'aocs_addcol.addcol1'::regclass and attname = 'f_renamed'; + attstattarget +--------------- + 1000 +(1 row) + +set client_min_messages to error; +alter table addcol1 alter column f_renamed set statistics 1001; -- should limit to 1000 and give warning +set client_min_messages to notice; +select attstattarget from pg_attribute where attrelid = 'aocs_addcol.addcol1'::regclass and attname = 'f_renamed'; + attstattarget +--------------- + 1000 +(1 row) + +-- test alter distribution policy +alter table addcol1 set distributed randomly; +alter table addcol1 set distributed by (a); +-- test some constraints (unique indexes do not work for unique and pkey) +alter table addcol1 add constraint tunique unique(a); +ERROR: append-only tables do not support unique indexes +alter table addcol1 add constraint tpkey primary key(a); +ERROR: append-only tables do not support unique indexes +alter table addcol1 add constraint tcheck check (a is not null); +-- test some aocs partition table altering +create table alter_aocs_part_table (a int, b int) with (appendonly=true, orientation=column) distributed by (a) + partition by range(b) (start (1) end (5) exclusive every (1), default partition foo); +insert into alter_aocs_part_table values (generate_series(1,10), generate_series(1,10)); +alter table alter_aocs_part_table drop partition for (rank(1)); +alter table alter_aocs_part_table split default partition start(6) inclusive end(7) exclusive; +NOTICE: dropped partition "foo" for relation "alter_aocs_part_table" +alter table alter_aocs_part_table split default partition start(6) inclusive end(8) exclusive; +NOTICE: dropped partition "foo" for relation "alter_aocs_part_table" +ERROR: new partition overlaps existing partition "r2064870801" +alter table alter_aocs_part_table split default partition start(7) inclusive end(8) exclusive; +NOTICE: dropped partition "foo" for relation "alter_aocs_part_table" +select partitionrangestart, partitionstartinclusive, partitionrangeend, partitionendinclusive, partitionisdefault + from pg_partitions where tablename = 'alter_aocs_part_table'; + partitionrangestart | partitionstartinclusive | partitionrangeend | partitionendinclusive | partitionisdefault +---------------------+-------------------------+-------------------+-----------------------+-------------------- + | f | | f | t + 2 | t | 3 | f | f + 3 | t | 4 | f | f + 4 | t | 5 | f | f + 6 | t | 7 | f | f + 7 | t | 8 | f | f +(6 rows) + +create table alter_aocs_ao_table (a int, b int) with (appendonly=true) distributed by (a); +insert into alter_aocs_ao_table values (2,2); +alter table alter_aocs_part_table exchange partition for (rank(1)) with table alter_aocs_ao_table; +create table alter_aocs_heap_table (a int, b int) distributed by (a); +insert into alter_aocs_heap_table values (3,3); +alter table alter_aocs_part_table exchange partition for (rank(2)) with table alter_aocs_heap_table; -- cleanup so as not to affect other installcheck tests -- (e.g. column_compression). drop schema aocs_addcol cascade; +NOTICE: drop cascades to table alter_aocs_part_table_1_prt_4 +NOTICE: drop cascades to constraint alter_aocs_part_table_1_prt_4_check on table alter_aocs_part_table_1_prt_4 +NOTICE: drop cascades to append only table alter_aocs_part_table_1_prt_3 +NOTICE: drop cascades to constraint alter_aocs_part_table_1_prt_3_check on append only table alter_aocs_part_table_1_prt_3 +NOTICE: drop cascades to append only columnar table alter_aocs_part_table_1_prt_foo +NOTICE: drop cascades to append only columnar table alter_aocs_part_table_1_prt_r1302684005 +NOTICE: drop cascades to constraint alter_aocs_part_table_1_prt_r1302684005_check on append only columnar table alter_aocs_part_table_1_prt_r1302684005 +NOTICE: drop cascades to append only columnar table alter_aocs_part_table_1_prt_r2045619544 +NOTICE: drop cascades to constraint alter_aocs_part_table_1_prt_r2045619544_check on append only columnar table alter_aocs_part_table_1_prt_r2045619544 +NOTICE: drop cascades to append only columnar table alter_aocs_part_table_1_prt_5 +NOTICE: drop cascades to constraint alter_aocs_part_table_1_prt_5_check on append only columnar table alter_aocs_part_table_1_prt_5 +NOTICE: drop cascades to append only columnar table alter_aocs_heap_table +NOTICE: drop cascades to constraint alter_aocs_part_table_1_prt_4_check on append only columnar table alter_aocs_heap_table +NOTICE: drop cascades to append only columnar table alter_aocs_ao_table +NOTICE: drop cascades to constraint alter_aocs_part_table_1_prt_3_check on append only columnar table alter_aocs_ao_table +NOTICE: drop cascades to append only columnar table alter_aocs_part_table NOTICE: drop cascades to append only columnar table addcol8 NOTICE: drop cascades to append only table addcol7_1_prt_part201204 NOTICE: drop cascades to constraint addcol7_1_prt_part201204_check on append only table addcol7_1_prt_part201204 @@ -442,3 +547,4 @@ NOTICE: drop cascades to append only columnar table addcol4 NOTICE: drop cascades to append only columnar table addcol3 NOTICE: drop cascades to append only columnar table addcol2 NOTICE: drop cascades to append only columnar table addcol1 +NOTICE: drop cascades to constraint tcheck on append only columnar table addcol1 diff --git a/src/test/regress/expected/aoco_privileges.out b/src/test/regress/expected/aoco_privileges.out new file mode 100644 index 0000000000000000000000000000000000000000..9cda67d3c35001b4da8df2f34bf9a61d96349e49 --- /dev/null +++ b/src/test/regress/expected/aoco_privileges.out @@ -0,0 +1,128 @@ +-- Create roles. -- +CREATE ROLE new_aoco_table_owner; +NOTICE: resource queue required -- using default resource queue "pg_default" +CREATE ROLE user_with_privileges_from_first_owner; +NOTICE: resource queue required -- using default resource queue "pg_default" +CREATE ROLE user_with_privileges_from_second_owner; +NOTICE: resource queue required -- using default resource queue "pg_default" +CREATE ROLE user_with_no_privileges; +NOTICE: resource queue required -- using default resource queue "pg_default" +-- Create the table. -- +CREATE TABLE aoco_privileges_table (a int) WITH (appendonly=true, orientation=column) DISTRIBUTED randomly; +-- Grant privileges to only one user +GRANT ALL ON aoco_privileges_table TO user_with_privileges_from_first_owner; +SELECT has_table_privilege('user_with_privileges_from_first_owner', 'aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + t +(1 row) + +-- The original owner should have privileges +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + t +(1 row) + +-- The following users should not have privileges +SELECT has_table_privilege('new_aoco_table_owner', 'aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + f +(1 row) + +SELECT has_table_privilege('user_with_privileges_from_second_owner', 'aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + f +(1 row) + +SELECT has_table_privilege('user_with_no_privileges', 'aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + f +(1 row) + +SET ROLE user_with_no_privileges; +SELECT * FROM aoco_privileges_table; +ERROR: permission denied for relation aoco_privileges_table +RESET ROLE; +-- Now change ownership to the new owner +ALTER TABLE aoco_privileges_table OWNER TO new_aoco_table_owner; +-- The original owner should still have privileges +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + t +(1 row) + +SELECT * FROM aoco_privileges_table; + a +--- +(0 rows) + +-- The people to whom the original owner granted privileges should still have privileges +SELECT has_table_privilege('user_with_privileges_from_first_owner', 'aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + t +(1 row) + +SET ROLE user_with_privileges_from_first_owner; +SELECT * FROM aoco_privileges_table; + a +--- +(0 rows) + +-- The new owner of the table should have privileges +SET ROLE new_aoco_table_owner; +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + t +(1 row) + +SELECT * FROM aoco_privileges_table; + a +--- +(0 rows) + +-- The new owner should be able to grant privileges +GRANT ALL ON aoco_privileges_table TO user_with_privileges_from_second_owner; +SELECT has_table_privilege('user_with_privileges_from_second_owner', 'aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + t +(1 row) + +SET ROLE user_with_privileges_from_second_owner; +SELECT * FROM aoco_privileges_table; + a +--- +(0 rows) + +-- The no privileges user should have no privileges still +SET ROLE user_with_no_privileges; +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + f +(1 row) + +SELECT * FROM aoco_privileges_table; +ERROR: permission denied for relation aoco_privileges_table +-- Revoke privileges +RESET ROLE; +REVOKE ALL ON aoco_privileges_table FROM user_with_privileges_from_first_owner; +SELECT has_table_privilege('user_with_privileges_from_first_owner', 'aoco_privileges_table', 'SELECT'); + has_table_privilege +--------------------- + f +(1 row) + +-- Clean up +DROP TABLE aoco_privileges_table; +DROP ROLE new_aoco_table_owner; +DROP ROLE user_with_privileges_from_first_owner; +DROP ROLE user_with_privileges_from_second_owner; +DROP ROLE user_with_no_privileges; diff --git a/src/test/regress/greenplum_schedule b/src/test/regress/greenplum_schedule index 4be49126bf12ba5fc2393f241b2b46d582412fb7..feccd101f320ae267d4548e0ccae0bcf0cd3cfa1 100755 --- a/src/test/regress/greenplum_schedule +++ b/src/test/regress/greenplum_schedule @@ -60,7 +60,7 @@ test: vacuum_gp #test: gpic_bigtup ignore: gp_portal_error -test: partition_indexing column_compression eagerfree mapred gpparams tidycat aocs co_nestloop_idxscan gpdtm_plpgsql alter_table_aocs alter_distribution_policy ic +test: partition_indexing column_compression eagerfree mapred gpparams tidycat aocs co_nestloop_idxscan gpdtm_plpgsql alter_table_aocs alter_distribution_policy ic aoco_privileges ignore: icudp_full ignore: gp_delete_as_trunc diff --git a/src/test/regress/init_file b/src/test/regress/init_file index c9b9fc174e7b37a6280e2bca22ad04bdb59a97dd..9cb4c7dcbf4576620d4db0279eaa61b866a24eea 100644 --- a/src/test/regress/init_file +++ b/src/test/regress/init_file @@ -111,4 +111,7 @@ s/\(cdbdisp\.c:\d+\)// m/^NOTICE:.*drop cascades to.*/ s/^NOTICE:.*drop cascades to.*/^NOTICE: drop cascades to / +# Mask out some numbers (parts of partition names) that vary from run to run. +m/overlaps existing partition "r\d+"/ +s/overlaps existing partition "r\d+"/partition "r##########"/ -- end_matchsubs diff --git a/src/test/regress/input/aocs.source b/src/test/regress/input/aocs.source index 6b53a830152cb63382ae2464b78fcf16dc508428..1974c0635b951976d4df723715477603e5fadce9 100644 --- a/src/test/regress/input/aocs.source +++ b/src/test/regress/input/aocs.source @@ -39,19 +39,29 @@ CREATE TABLE tenk_heap_for_aocs ( -- create few AO tables. test various reloptions combinations. use a sample -- of them (the first 4) for later testing. -- --- valid +-- valid combinations CREATE TABLE tenk_aocs1 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, checksum=true) distributed by(unique1); CREATE TABLE tenk_aocs2 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=0, blocksize=262144) distributed by(unique1); CREATE TABLE tenk_aocs3 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, blocksize=1048576, checksum=true) distributed by(unique1); CREATE TABLE tenk_aocs4 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=1, compresstype=zlib) distributed by(unique1); -CREATE TABLE tenk_aocs5 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib, blocksize=1048576, checksum=true) distributed by(unique1); --- invalid -CREATE TABLE tenk_aocs6 (like tenk_heap_for_aocs) with (appendonly=false, orientation=column, compresslevel=6, checksum=true) distributed by(unique1); -CREATE TABLE tenk_aocs7 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib) distributed by(unique1); -CREATE TABLE tenk_aocs8 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, blocksize=100) distributed by(unique1); -CREATE TABLE tenk_aocs9 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=0, compresstype=zlib) distributed by(unique1); --- cs without ao is invalid. -CREATE TABLE tenk_aocs10 (like tenk_heap_for_aocs) with (orientation=column) distributed by(unique1); +CREATE TABLE tenk_aocs5 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib) distributed by(unique1); +CREATE TABLE tenk_aocs6 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib, blocksize=1048576, checksum=true) distributed by(unique1); +-- invalid combinations +-- col instead of column +CREATE TABLE tenk_aocs7 (like tenk_heap_for_aocs) with (appendonly=true, orientation=col) distributed by(unique1); +-- no parentheses surrounding storage options +CREATE TABLE tenk_aocs8 (like tenk_heap_for_aocs) with appendonly=true, orientation=column distributed by(unique1); +-- no comma separating storage options +CREATE TABLE tenk_aocs9 (like tenk_heap_for_aocs) with (appendonly=true orientation=column) distributed by(unique1); +-- appendonly=false with orientation=column should not work +CREATE TABLE tenk_aocs10 (like tenk_heap_for_aocs) with (appendonly=false, orientation=column, compresslevel=6, checksum=true) distributed by(unique1); +-- block size must be between 8KB and 2MB w/ 8KB multiple +CREATE TABLE tenk_aocs11 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, blocksize=100) distributed by(unique1); +-- cannot have compresslevel 0 +CREATE TABLE tenk_aocs12 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=0, compresstype=zlib) distributed by(unique1); +-- orientation=column must be combined with appendonly=true +CREATE TABLE tenk_aocs13 (like tenk_heap_for_aocs) with (orientation=column) distributed by(unique1); + -------------------- -- catalog checks @@ -213,6 +223,10 @@ SELECT count(*) FROM tenk_aocs2; SELECT count(*) FROM tenk_aocs3; SELECT count(*) FROM tenk_aocs4; +-- INHERITS +-- This is not supported in aocs and should error out +CREATE TABLE tenk_inherits_tenk_aocs1() INHERITS (tenk_aocs1); + -- NYI -- test get_ao_compression_ratio. use uncompressed table, so result is always 1. -- SELECT get_ao_compression_ratio('tenk_aocs2'); @@ -232,6 +246,30 @@ SELECT count(*) FROM tenk_aocs2; SELECT count(*) FROM tenk_aocs3; SELECT count(*) FROM tenk_aocs4; +-- LIKE +-- Should not copy storage options if not specified +CREATE TABLE tenk_like_nocopy_storage (LIKE tenk_aocs1); +SELECT count(*) FROM pg_class WHERE relstorage = 'c' AND relname = 'tenk_like_nocopy_storage'; +-- Check tables are truly decoupled +CREATE TABLE tenk_truly_decoupled (LIKE tenk_aocs4); +ALTER TABLE tenk_aocs4 DROP COLUMN two; +SELECT count(two) FROM tenk_truly_decoupled; + +-- DOMAIN +CREATE DOMAIN aocs_domain_constraint AS VARCHAR + DEFAULT 'Default value for varchar.' + CONSTRAINT constr1 + NOT NULL + CHECK (length(VALUE) > 16 AND length(VALUE) < 50); +CREATE TABLE aocs_with_domain_constraint (id integer, vc1 aocs_domain_constraint) + WITH (appendonly=true, orientation=column) DISTRIBUTED BY (id); +-- The following should succeed +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (1, 'Long enough, but not too long.;'); +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (2, 'This is purrfect.'); +-- The following should fail +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (3, 'Not long enough.'); +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (4, NULL); + -- JOIN SELECT count(*) FROM tenk_aocs1 t1, tenk_aocs2 t2 where t1.unique1 = t2.unique2; SELECT count(*) FROM tenk_aocs1 t1, tenk_heap_for_aocs t2 where t1.unique1 = t2.unique2; @@ -242,6 +280,7 @@ SELECT unique1 FROM tenk_heap_for_aocs EXCEPT SELECT unique1 FROM tenk_aocs3; -- TRUNCATE TRUNCATE tenk_aocs2; +SELECT count(*) FROM tenk_aocs2; -- OID with aocs NYI -- OIDS @@ -289,6 +328,9 @@ select * from co where j = 2; select i from co where j = 2; select j,i from co where k = 'aaa' or k = 'bbb'; +-- Test clustering errors out +cluster co_j_cluster on co_j; + --------------------- -- UAO --------------------- @@ -303,16 +345,6 @@ UPDATE tenk_aocs1 SET unique2 = 1 WHERE unique2 = 2; -- modcount after UPDATE must increment to flag table should be included in -- incremental backup select count(*) from gp_toolkit.__gp_aocsseg_name('tenk_aocs1') where modcount > 1; --------------------- --- unsupported sql --------------------- --- ALTER -ALTER TABLE tenk_aocs1 RENAME TO tenk_renamed; -ALTER TABLE tenk_renamed ADD COLUMN newcol int default 10; -ALTER TABLE tenk_renamed ALTER COLUMN twothousand SET NOT NULL; -ALTER TABLE tenk_renamed ADD COLUMN newcol2 int NOT NULL; -- should fail -SELECT count(*) FROM tenk_renamed; -ALTER TABLE tenk_renamed RENAME TO tenk_aocs1; -------------------- -- system columns diff --git a/src/test/regress/output/aocs.source b/src/test/regress/output/aocs.source index e63c6151ea8ae956e6ddac8ed3a3145534cf1860..13928c736452fb4c26b86d3067319bdd41544d62 100644 --- a/src/test/regress/output/aocs.source +++ b/src/test/regress/output/aocs.source @@ -35,24 +35,40 @@ CREATE TABLE tenk_heap_for_aocs ( -- create few AO tables. test various reloptions combinations. use a sample -- of them (the first 4) for later testing. -- --- valid +-- valid combinations CREATE TABLE tenk_aocs1 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, checksum=true) distributed by(unique1); CREATE TABLE tenk_aocs2 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=0, blocksize=262144) distributed by(unique1); CREATE TABLE tenk_aocs3 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, blocksize=1048576, checksum=true) distributed by(unique1); CREATE TABLE tenk_aocs4 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=1, compresstype=zlib) distributed by(unique1); -CREATE TABLE tenk_aocs5 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib, blocksize=1048576, checksum=true) distributed by(unique1); --- invalid -CREATE TABLE tenk_aocs6 (like tenk_heap_for_aocs) with (appendonly=false, orientation=column, compresslevel=6, checksum=true) distributed by(unique1); +CREATE TABLE tenk_aocs5 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib) distributed by(unique1); +CREATE TABLE tenk_aocs6 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib, blocksize=1048576, checksum=true) distributed by(unique1); +-- invalid combinations +-- col instead of column +CREATE TABLE tenk_aocs7 (like tenk_heap_for_aocs) with (appendonly=true, orientation=col) distributed by(unique1); +ERROR: invalid parameter value for "orientation": "col" +-- no parentheses surrounding storage options +CREATE TABLE tenk_aocs8 (like tenk_heap_for_aocs) with appendonly=true, orientation=column distributed by(unique1); +ERROR: syntax error at or near "appendonly" +LINE 1: ...E TABLE tenk_aocs8 (like tenk_heap_for_aocs) with appendonly... + ^ +-- no comma separating storage options +CREATE TABLE tenk_aocs9 (like tenk_heap_for_aocs) with (appendonly=true orientation=column) distributed by(unique1); +ERROR: syntax error at or near "orientation" +LINE 1: ...9 (like tenk_heap_for_aocs) with (appendonly=true orientatio... + ^ +-- appendonly=false with orientation=column should not work +CREATE TABLE tenk_aocs10 (like tenk_heap_for_aocs) with (appendonly=false, orientation=column, compresslevel=6, checksum=true) distributed by(unique1); ERROR: invalid option 'compresslevel' for base relation. Only valid for Append Only relations -CREATE TABLE tenk_aocs7 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=6, compresstype=zlib) distributed by(unique1); -CREATE TABLE tenk_aocs8 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, blocksize=100) distributed by(unique1); +-- block size must be between 8KB and 2MB w/ 8KB multiple +CREATE TABLE tenk_aocs11 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, blocksize=100) distributed by(unique1); ERROR: block size must be between 8KB and 2MB and be an 8KB multiple. Got 100 -CREATE TABLE tenk_aocs9 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=0, compresstype=zlib) distributed by(unique1); +-- cannot have compresslevel 0 +CREATE TABLE tenk_aocs12 (like tenk_heap_for_aocs) with (appendonly=true, orientation=column, compresslevel=0, compresstype=zlib) distributed by(unique1); ERROR: compresstype can't be used with compresslevel 0 --- cs without ao is invalid. -CREATE TABLE tenk_aocs10 (like tenk_heap_for_aocs) with (orientation=column) distributed by(unique1); +-- orientation=column must be combined with appendonly=true +CREATE TABLE tenk_aocs13 (like tenk_heap_for_aocs) with (orientation=column) distributed by(unique1); ERROR: invalid option "orientation" for base relation. Only valid for Append Only relations --------------------- +-------------------- -- catalog checks -------------------- -- check pg_appendonly @@ -63,8 +79,8 @@ SELECT c.relname, a.blocksize, a.compresstype, a.compresslevel, a.checksum FROM tenk_aocs2 | 262144 | | 0 | t tenk_aocs3 | 1048576 | zlib | 6 | t tenk_aocs4 | 32768 | zlib | 1 | t - tenk_aocs5 | 1048576 | zlib | 6 | t - tenk_aocs7 | 32768 | zlib | 6 | t + tenk_aocs5 | 32768 | zlib | 6 | t + tenk_aocs6 | 1048576 | zlib | 6 | t (6 rows) -------------------- @@ -374,8 +390,8 @@ SELECT c.relname, a.blocksize, a.compresstype, a.compresslevel, a.checksum FROM tenk_aocs2 | 262144 | | 0 | t tenk_aocs3 | 1048576 | zlib | 6 | t tenk_aocs4 | 32768 | zlib | 1 | t - tenk_aocs5 | 1048576 | zlib | 6 | t - tenk_aocs7 | 32768 | zlib | 6 | t + tenk_aocs5 | 32768 | zlib | 6 | t + tenk_aocs6 | 1048576 | zlib | 6 | t (6 rows) SELECT count(*) FROM tenk_aocs1; @@ -402,6 +418,10 @@ SELECT count(*) FROM tenk_aocs4; 10000 (1 row) +-- INHERITS +-- This is not supported in aocs and should error out +CREATE TABLE tenk_inherits_tenk_aocs1() INHERITS (tenk_aocs1); +ERROR: cannot inherit relation "tenk_aocs1" as it is column oriented -- NYI -- test get_ao_compression_ratio. use uncompressed table, so result is always 1. -- SELECT get_ao_compression_ratio('tenk_aocs2'); @@ -438,6 +458,40 @@ SELECT count(*) FROM tenk_aocs4; 10000 (1 row) +-- LIKE +-- Should not copy storage options if not specified +CREATE TABLE tenk_like_nocopy_storage (LIKE tenk_aocs1); +SELECT count(*) FROM pg_class WHERE relstorage = 'c' AND relname = 'tenk_like_nocopy_storage'; + count +------- + 0 +(1 row) + +-- Check tables are truly decoupled +CREATE TABLE tenk_truly_decoupled (LIKE tenk_aocs4); +ALTER TABLE tenk_aocs4 DROP COLUMN two; +SELECT count(two) FROM tenk_truly_decoupled; + count +------- + 0 +(1 row) + +-- DOMAIN +CREATE DOMAIN aocs_domain_constraint AS VARCHAR + DEFAULT 'Default value for varchar.' + CONSTRAINT constr1 + NOT NULL + CHECK (length(VALUE) > 16 AND length(VALUE) < 50); +CREATE TABLE aocs_with_domain_constraint (id integer, vc1 aocs_domain_constraint) + WITH (appendonly=true, orientation=column) DISTRIBUTED BY (id); +-- The following should succeed +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (1, 'Long enough, but not too long.;'); +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (2, 'This is purrfect.'); +-- The following should fail +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (3, 'Not long enough.'); +ERROR: value for domain aocs_domain_constraint violates check constraint "aocs_domain_constraint_check" +INSERT INTO aocs_with_domain_constraint (id, vc1) VALUES (4, NULL); +ERROR: domain aocs_domain_constraint does not allow null values -- JOIN SELECT count(*) FROM tenk_aocs1 t1, tenk_aocs2 t2 where t1.unique1 = t2.unique2; count @@ -464,6 +518,12 @@ SELECT unique1 FROM tenk_heap_for_aocs EXCEPT SELECT unique1 FROM tenk_aocs3; -- TRUNCATE TRUNCATE tenk_aocs2; +SELECT count(*) FROM tenk_aocs2; + count +------- + 0 +(1 row) + -- OID with aocs NYI -- OIDS -- @@ -566,6 +626,9 @@ select j,i from co where k = 'aaa' or k = 'bbb'; 2 | 11 (3 rows) +-- Test clustering errors out +cluster co_j_cluster on co_j; +ERROR: "co_j" is an index --------------------- -- UAO --------------------- @@ -595,22 +658,6 @@ select count(*) from gp_toolkit.__gp_aocsseg_name('tenk_aocs1') where modcount > 16 (1 row) --------------------- --- unsupported sql --------------------- --- ALTER -ALTER TABLE tenk_aocs1 RENAME TO tenk_renamed; -ALTER TABLE tenk_renamed ADD COLUMN newcol int default 10; -ALTER TABLE tenk_renamed ALTER COLUMN twothousand SET NOT NULL; -ALTER TABLE tenk_renamed ADD COLUMN newcol2 int NOT NULL; -- should fail -ERROR: ADD COLUMN with no default value in append-only tables is not yet supported. -SELECT count(*) FROM tenk_renamed; - count -------- - 9999 -(1 row) - -ALTER TABLE tenk_renamed RENAME TO tenk_aocs1; -------------------- -- system columns -------------------- diff --git a/src/test/regress/sql/alter_distribution_policy.sql b/src/test/regress/sql/alter_distribution_policy.sql index bb5949643aba101a8d7b011e014416b9175010ba..f1f24c2c092d882cd30ae8fcb806605fdf10a06b 100644 --- a/src/test/regress/sql/alter_distribution_policy.sql +++ b/src/test/regress/sql/alter_distribution_policy.sql @@ -58,15 +58,20 @@ select * from atsdb where i = 1; drop table atsdb; -- Now try AO -create table atsdb_ao (i int, j text) distributed by (i); +create table atsdb_ao (i int, j text) with (appendonly=true) distributed by (i); insert into atsdb_ao select i, (i+1)::text from generate_series(1, 100) i; insert into atsdb_ao select i, (i+1)::text from generate_series(1, 100) i; -- check that we're an AO table -explain select count(*) from atsdb_ao; +select count(*) from pg_appendonly where relid='atsdb_ao'::regclass; select count(*) from atsdb_ao; alter table atsdb_ao set distributed by (j); -- Still AO? -explain select count(*) from atsdb_ao; +select count(*) from pg_appendonly where relid='atsdb_ao'::regclass; +select count(*) from atsdb_ao; +-- check alter, vacuum analyze, and then alter +delete from atsdb_ao where i = any(array(select generate_series(1,90))); +vacuum analyze atsdb_ao; +alter table atsdb_ao set distributed randomly; select count(*) from atsdb_ao; drop table atsdb_ao; diff --git a/src/test/regress/sql/alter_table_aocs.sql b/src/test/regress/sql/alter_table_aocs.sql index a85fedaaac5068a66d1f593bb89d259b2e1762ef..7d22af103f504db4b09249ab5a91c7d5c7c8ac25 100644 --- a/src/test/regress/sql/alter_table_aocs.sql +++ b/src/test/regress/sql/alter_table_aocs.sql @@ -1,6 +1,6 @@ set optimizer_disable_missing_stats_collection = on; -- --- This test case covers basic ADD COLUMN functionality for AOCS relations. +-- This test case covers ALTER functionality for AOCS relations. -- -- @@ -258,6 +258,60 @@ alter table addcol8 select * from addcol8 order by a; \d addcol8 +-- try renaming table and see if stuff still works +alter table addcol1 rename to addcol1_renamed; +alter table addcol1_renamed add column new_column int default 10; +alter table addcol1_renamed alter column new_column set not null; +alter table addcol1_renamed add column new_column2 int not null; -- should fail +select count(*) from addcol1_renamed; +alter table addcol1_renamed drop column new_column; +alter table addcol1_renamed rename to addcol1; + +-- try renaming columns and see if stuff still works +alter table addcol1 rename column f to f_renamed; +alter table addcol1 alter column f_renamed set default 10; +insert into addcol1 values (999); +select a, f_renamed from addcol1 where a = 999; + +-- try dropping and adding back the column +alter table addcol1 drop column f_renamed; +alter table addcol1 add column f_renamed int default 20; +select a, f_renamed from addcol1 where a = 999; + +-- try altering statistics of a column +alter table addcol1 alter column f_renamed set statistics 1000; +select attstattarget from pg_attribute where attrelid = 'aocs_addcol.addcol1'::regclass and attname = 'f_renamed'; +set client_min_messages to error; +alter table addcol1 alter column f_renamed set statistics 1001; -- should limit to 1000 and give warning +set client_min_messages to notice; +select attstattarget from pg_attribute where attrelid = 'aocs_addcol.addcol1'::regclass and attname = 'f_renamed'; + +-- test alter distribution policy +alter table addcol1 set distributed randomly; +alter table addcol1 set distributed by (a); + +-- test some constraints (unique indexes do not work for unique and pkey) +alter table addcol1 add constraint tunique unique(a); +alter table addcol1 add constraint tpkey primary key(a); +alter table addcol1 add constraint tcheck check (a is not null); + +-- test some aocs partition table altering +create table alter_aocs_part_table (a int, b int) with (appendonly=true, orientation=column) distributed by (a) + partition by range(b) (start (1) end (5) exclusive every (1), default partition foo); +insert into alter_aocs_part_table values (generate_series(1,10), generate_series(1,10)); +alter table alter_aocs_part_table drop partition for (rank(1)); +alter table alter_aocs_part_table split default partition start(6) inclusive end(7) exclusive; +alter table alter_aocs_part_table split default partition start(6) inclusive end(8) exclusive; +alter table alter_aocs_part_table split default partition start(7) inclusive end(8) exclusive; +select partitionrangestart, partitionstartinclusive, partitionrangeend, partitionendinclusive, partitionisdefault + from pg_partitions where tablename = 'alter_aocs_part_table'; +create table alter_aocs_ao_table (a int, b int) with (appendonly=true) distributed by (a); +insert into alter_aocs_ao_table values (2,2); +alter table alter_aocs_part_table exchange partition for (rank(1)) with table alter_aocs_ao_table; +create table alter_aocs_heap_table (a int, b int) distributed by (a); +insert into alter_aocs_heap_table values (3,3); +alter table alter_aocs_part_table exchange partition for (rank(2)) with table alter_aocs_heap_table; + -- cleanup so as not to affect other installcheck tests -- (e.g. column_compression). drop schema aocs_addcol cascade; diff --git a/src/test/regress/sql/aoco_privileges.sql b/src/test/regress/sql/aoco_privileges.sql new file mode 100644 index 0000000000000000000000000000000000000000..096fcfe97809bc4d9e5e58bb7781b31f7c066d46 --- /dev/null +++ b/src/test/regress/sql/aoco_privileges.sql @@ -0,0 +1,63 @@ +-- Create roles. -- +CREATE ROLE new_aoco_table_owner; +CREATE ROLE user_with_privileges_from_first_owner; +CREATE ROLE user_with_privileges_from_second_owner; +CREATE ROLE user_with_no_privileges; + +-- Create the table. -- +CREATE TABLE aoco_privileges_table (a int) WITH (appendonly=true, orientation=column) DISTRIBUTED randomly; + +-- Grant privileges to only one user +GRANT ALL ON aoco_privileges_table TO user_with_privileges_from_first_owner; +SELECT has_table_privilege('user_with_privileges_from_first_owner', 'aoco_privileges_table', 'SELECT'); + +-- The original owner should have privileges +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); + +-- The following users should not have privileges +SELECT has_table_privilege('new_aoco_table_owner', 'aoco_privileges_table', 'SELECT'); +SELECT has_table_privilege('user_with_privileges_from_second_owner', 'aoco_privileges_table', 'SELECT'); +SELECT has_table_privilege('user_with_no_privileges', 'aoco_privileges_table', 'SELECT'); +SET ROLE user_with_no_privileges; +SELECT * FROM aoco_privileges_table; +RESET ROLE; + +-- Now change ownership to the new owner +ALTER TABLE aoco_privileges_table OWNER TO new_aoco_table_owner; + +-- The original owner should still have privileges +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); +SELECT * FROM aoco_privileges_table; + +-- The people to whom the original owner granted privileges should still have privileges +SELECT has_table_privilege('user_with_privileges_from_first_owner', 'aoco_privileges_table', 'SELECT'); +SET ROLE user_with_privileges_from_first_owner; +SELECT * FROM aoco_privileges_table; + +-- The new owner of the table should have privileges +SET ROLE new_aoco_table_owner; +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); +SELECT * FROM aoco_privileges_table; + +-- The new owner should be able to grant privileges +GRANT ALL ON aoco_privileges_table TO user_with_privileges_from_second_owner; +SELECT has_table_privilege('user_with_privileges_from_second_owner', 'aoco_privileges_table', 'SELECT'); +SET ROLE user_with_privileges_from_second_owner; +SELECT * FROM aoco_privileges_table; + +-- The no privileges user should have no privileges still +SET ROLE user_with_no_privileges; +SELECT has_table_privilege('aoco_privileges_table', 'SELECT'); +SELECT * FROM aoco_privileges_table; + +-- Revoke privileges +RESET ROLE; +REVOKE ALL ON aoco_privileges_table FROM user_with_privileges_from_first_owner; +SELECT has_table_privilege('user_with_privileges_from_first_owner', 'aoco_privileges_table', 'SELECT'); + +-- Clean up +DROP TABLE aoco_privileges_table; +DROP ROLE new_aoco_table_owner; +DROP ROLE user_with_privileges_from_first_owner; +DROP ROLE user_with_privileges_from_second_owner; +DROP ROLE user_with_no_privileges;