CREATE SCHEMA am_tableoptions; SET search_path TO am_tableoptions; SET columnar.compression TO 'none'; CREATE TABLE table_options (a int) USING columnar; INSERT INTO table_options SELECT generate_series(1,100); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 10000 | 150000 | none | 3 (1 row) -- test changing the compression ALTER TABLE table_options SET (columnar.compression = pglz); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 10000 | 150000 | pglz | 3 (1 row) -- test changing the compression level ALTER TABLE table_options SET (columnar.compression_level = 5); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 10000 | 150000 | pglz | 5 (1 row) -- test changing the chunk_group_row_limit ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 2000); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 2000 | 150000 | pglz | 5 (1 row) -- test changing the chunk_group_row_limit ALTER TABLE table_options SET (columnar.stripe_row_limit = 4000); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 2000 | 4000 | pglz | 5 (1 row) -- VACUUM FULL creates a new table, make sure it copies settings from the table you are vacuuming VACUUM FULL table_options; -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 2000 | 4000 | pglz | 5 (1 row) -- set all settings at the same time ALTER TABLE table_options SET (columnar.stripe_row_limit = 8000, columnar.chunk_group_row_limit = 4000, columnar.compression = none, columnar.compression_level = 7); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 4000 | 8000 | none | 7 (1 row) -- make sure table options are not changed when VACUUM a table VACUUM table_options; -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 4000 | 8000 | none | 7 (1 row) -- make sure table options are not changed when VACUUM FULL a table VACUUM FULL table_options; -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 4000 | 8000 | none | 7 (1 row) -- make sure table options are not changed when truncating a table TRUNCATE table_options; -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 4000 | 8000 | none | 7 (1 row) ALTER TABLE table_options ALTER COLUMN a TYPE bigint; -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 4000 | 8000 | none | 7 (1 row) -- reset settings one by one to the version of the GUC's SET columnar.chunk_group_row_limit TO 1000; SET columnar.stripe_row_limit TO 10000; SET columnar.compression TO 'pglz'; SET columnar.compression_level TO 11; -- verify setting the GUC's didn't change the settings -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 4000 | 8000 | none | 7 (1 row) ALTER TABLE table_options RESET (columnar.chunk_group_row_limit); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 1000 | 8000 | none | 7 (1 row) ALTER TABLE table_options RESET (columnar.stripe_row_limit); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 1000 | 10000 | none | 7 (1 row) ALTER TABLE table_options RESET (columnar.compression); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 1000 | 10000 | pglz | 7 (1 row) ALTER TABLE table_options RESET (columnar.compression_level); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 1000 | 10000 | pglz | 11 (1 row) -- verify resetting all settings at once work SET columnar.chunk_group_row_limit TO 10000; SET columnar.stripe_row_limit TO 100000; SET columnar.compression TO 'none'; SET columnar.compression_level TO 13; -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 1000 | 10000 | pglz | 11 (1 row) ALTER TABLE table_options RESET (columnar.chunk_group_row_limit, columnar.stripe_row_limit, columnar.compression, columnar.compression_level); -- show table_options settings SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 10000 | 100000 | none | 13 (1 row) -- verify edge cases -- first start with a table that is not a columnar table CREATE TABLE not_a_columnar_table (a int); ALTER TABLE not_a_columnar_table SET (columnar.compression = pglz); ERROR: columnar storage parameters specified on non-columnar table ALTER TABLE not_a_columnar_table RESET (columnar.compression); ERROR: columnar storage parameters specified on non-columnar table -- verify you can't use a compression that is not known ALTER TABLE table_options SET (columnar.compression = foobar); ERROR: unknown compression type for columnar table: foobar -- verify you can't use a columnar setting that is not known ALTER TABLE table_options SET (columnar.foobar = 123); ERROR: unrecognized columnar storage parameter "foobar" ALTER TABLE table_options RESET (columnar.foobar); ERROR: unrecognized columnar storage parameter "foobar" -- verify that invalid options are caught early, before query executes -- (error should be about invalid options, not division-by-zero) CREATE TABLE fail(i) USING columnar WITH (columnar.foobar = 123) AS SELECT 1/0; ERROR: unrecognized columnar storage parameter "foobar" CREATE TABLE fail(i) USING columnar WITH (columnar.compression = foobar) AS SELECT 1/0; ERROR: unknown compression type for columnar table: foobar -- verify cannot set out of range compression levels ALTER TABLE table_options SET (columnar.compression_level = 0); ERROR: compression level out of range HINT: compression level must be between 1 and 19 ALTER TABLE table_options SET (columnar.compression_level = 20); ERROR: compression level out of range HINT: compression level must be between 1 and 19 -- verify cannot set out of range stripe_row_limit & chunk_group_row_limit options ALTER TABLE table_options SET (columnar.stripe_row_limit = 999); ERROR: stripe row count limit out of range HINT: stripe row count limit must be between 1000 and 10000000 ALTER TABLE table_options SET (columnar.stripe_row_limit = 10000001); ERROR: stripe row count limit out of range HINT: stripe row count limit must be between 1000 and 10000000 ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 999); ERROR: chunk group row count limit out of range HINT: chunk group row count limit must be between 1000 and 100000 ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 100001); ERROR: chunk group row count limit out of range HINT: chunk group row count limit must be between 1000 and 100000 ALTER TABLE table_options SET (columnar.chunk_group_row_limit = 0); ERROR: chunk group row count limit out of range HINT: chunk group row count limit must be between 1000 and 100000 INSERT INTO table_options VALUES (1); -- multiple SET/RESET clauses ALTER TABLE table_options SET (columnar.compression = pglz, columnar.compression_level = 7), SET (columnar.compression_level = 6); SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 10000 | 100000 | pglz | 6 (1 row) ALTER TABLE table_options SET (columnar.compression = pglz, columnar.stripe_row_limit = 7777), RESET (columnar.stripe_row_limit), SET (columnar.chunk_group_row_limit = 5555); SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 5555 | 100000 | pglz | 6 (1 row) -- a no-op; shouldn't throw an error ALTER TABLE IF EXISTS what SET (columnar.compression = lz4); NOTICE: relation "what" does not exist, skipping -- a no-op; shouldn't throw an error CREATE TABLE IF NOT EXISTS table_options(a int) USING columnar WITH (columnar.compression_level = 4); NOTICE: relation "table_options" already exists, skipping -- test old interface based on functions SELECT alter_columnar_table_reset('table_options', compression => true); alter_columnar_table_reset --------------------------------------------------------------------- (1 row) SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 5555 | 100000 | none | 6 (1 row) SELECT alter_columnar_table_set('table_options', compression_level => 1); alter_columnar_table_set --------------------------------------------------------------------- (1 row) SELECT * FROM columnar.options WHERE relation = 'table_options'::regclass; relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- table_options | 5555 | 100000 | none | 1 (1 row) -- error: set columnar options on heap tables CREATE TABLE heap_options(i int) USING heap; ALTER TABLE heap_options SET (columnar.stripe_row_limit = 12000); ERROR: columnar storage parameters specified on non-columnar table -- ordinarily, postgres allows bogus options for a RESET clause, -- but if it's a heap table and someone specifies columnar options, -- we block them ALTER TABLE heap_options RESET (columnar.stripe_row_limit, foobar); ERROR: columnar storage parameters specified on non-columnar table DROP TABLE heap_options; -- verify options are removed when table is dropped DROP TABLE table_options; -- we expect no entries in çstore.options for anything not found int pg_class SELECT * FROM columnar.options o WHERE o.relation NOT IN (SELECT oid FROM pg_class); relation | chunk_group_row_limit | stripe_row_limit | compression | compression_level --------------------------------------------------------------------- (0 rows) SET client_min_messages TO warning; DROP SCHEMA am_tableoptions CASCADE;