diff --git a/src/test/Makefile b/src/test/Makefile index 69ef074d75..a2a01105f3 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -18,6 +18,10 @@ ifeq ($(with_icu),yes) SUBDIRS += icu endif +ifeq ($(with_zstd),yes) +SUBDIRS += zstd +endif + # Test suites that are not safe by default but can be run if selected # by the user via the whitespace-separated list in variable # PG_TEST_EXTRA: diff --git a/src/test/README b/src/test/README index afdc767651..b44d0c21d9 100644 --- a/src/test/README +++ b/src/test/README @@ -48,3 +48,6 @@ ssl/ subscription/ Tests for logical replication + +zstd/ + Tests for page compression with zstd diff --git a/src/test/recovery/t/001_stream_rep.pl b/src/test/recovery/t/001_stream_rep.pl index 86864098f9..87fd3a3030 100644 --- a/src/test/recovery/t/001_stream_rep.pl +++ b/src/test/recovery/t/001_stream_rep.pl @@ -46,6 +46,9 @@ $node_standby_2->start; $node_primary->safe_psql('postgres', "CREATE TABLE tab_int AS SELECT generate_series(1,1002) AS a"); +$node_primary->safe_psql('postgres', + "CREATE TABLE tab_int_compressed WITH(compresstype=pglz)AS SELECT generate_series(1,1002) AS a"); + # Wait for standbys to catch up my $primary_lsn = $node_primary->lsn('write'); $node_primary->wait_for_catchup($node_standby_1, 'replay', $primary_lsn); @@ -56,6 +59,11 @@ my $result = print "standby 1: $result\n"; is($result, qq(1002), 'check streamed content on standby 1'); +my $result = + $node_standby_1->safe_psql('postgres', "SELECT count(*) FROM tab_int_compressed"); +print "standby 1: $result\n"; +is($result, qq(1002), 'check streamed content for compressed table on standby 1'); + $result = $node_standby_2->safe_psql('postgres', "SELECT count(*) FROM tab_int"); print "standby 2: $result\n"; @@ -78,6 +86,11 @@ $result = $node_standby_2->safe_psql('postgres', "SELECT * FROM seq1"); print "standby 2: $result\n"; is($result, qq(33|0|t), 'check streamed sequence content on standby 2'); +$result = + $node_standby_2->safe_psql('postgres', "SELECT count(*) FROM tab_int_compressed"); +print "standby 2: $result\n"; +is($result, qq(1002), 'check streamed content for compressed table on standby 2'); + # Check that only READ-only queries can run on standbys is($node_standby_1->psql('postgres', 'INSERT INTO tab_int VALUES (1)'), 3, 'read-only queries on standby 1'); diff --git a/src/test/regress/expected/page_compression.out b/src/test/regress/expected/page_compression.out new file mode 100644 index 0000000000..e7ab05935a --- /dev/null +++ b/src/test/regress/expected/page_compression.out @@ -0,0 +1,877 @@ +-- +-- Page compression tests +-- +-- +-- create compressed table +-- +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=pglz + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=512); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=pglz, compress_chunk_size=512 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=1024); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=pglz, compress_chunk_size=1024 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=2048); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=pglz, compress_chunk_size=2048 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compresslevel=0, compress_chunk_size=4096, compress_prealloc_chunks=0); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=pglz, compresslevel=0, compress_chunk_size=4096, compress_prealloc_chunks=0 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compresslevel=-1, compress_chunk_size=1024, compress_prealloc_chunks=15); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=pglz, compresslevel=-1, compress_chunk_size=1024, compress_prealloc_chunks=15 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=15) + AS SELECT id, id::text c1 FROM generate_series(1,1000)id; +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=15 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE TABLE tbl_pc2(LIKE tbl_pc INCLUDING ALL); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) WITH (compresstype=pglz, compresslevel='1', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +DROP TABLE tbl_pc; +DROP TABLE tbl_pc2; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=none); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=none + +DROP TABLE tbl_pc; +-- invalid storage parameter +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=xyz); -- fail +ERROR: invalid value for enum option "compresstype": xyz +DETAIL: Valid values are "none", "pglz", "lz4" and "zstd". +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=pglz, compresslevel=xyz); -- fail +ERROR: invalid value for integer option "compresslevel": xyz +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=1025); -- fail +ERROR: invalid compress_chunk_size 1025, must be one of 512, 1024, 2048 or 4096 +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=pglz, compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +-- +-- create compressed index +-- +SET enable_seqscan = OFF; +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE INDEX tbl_pc_idx1 on tbl_pc(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) WITH (compresstype=pglz, compresslevel='1', compress_chunk_size='1024', compress_prealloc_chunks='2') + "tbl_pc_idx1" btree (c1) WITH (compresstype=pglz, compresslevel='1', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; +-- call CHECKPOINT to flush shared buffer to compressed relation file +CHECKPOINT; +-- run ANALYZE REINDEX VACUUM and CLUSTER on compressed table and index +ANALYZE tbl_pc; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Index Scan using tbl_pc_idx1 on tbl_pc + Index Cond: (c1 = '100'::text) +(2 rows) + +REINDEX INDEX tbl_pc_idx1; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +REINDEX TABLE tbl_pc; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +VACUUM tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +VACUUM FULL tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +CLUSTER tbl_pc USING tbl_pc_idx1; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +DROP INDEX tbl_pc_idx1; +-- check usage of compressed index with data +CREATE INDEX tbl_pc_idx1 on tbl_pc USING hash(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Index Scan using tbl_pc_idx1 on tbl_pc + Index Cond: (c1 = '100'::text) +(2 rows) + +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; + QUERY PLAN +------------------------------------------------------- + Bitmap Heap Scan on tbl_pc + Recheck Cond: (ARRAY[id] @> '{100}'::integer[]) + -> Bitmap Index Scan on tbl_pc_idx1 + Index Cond: (ARRAY[id] @> '{100}'::integer[]) +(4 rows) + +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gist((point(id,id))) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit + -> Index Scan using tbl_pc_idx1 on tbl_pc + Order By: (point((id)::double precision, (id)::double precision) <-> '(100,100)'::point) +(3 rows) + +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING spgist(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Index Scan using tbl_pc_idx1 on tbl_pc + Index Cond: (c1 = '100'::text) +(2 rows) + +DROP INDEX tbl_pc_idx1; +-- brin index does not support compression +CREATE INDEX tbl_pc_idx1 on tbl_pc USING brin(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); -- fail +ERROR: unrecognized parameter "compresstype" +DROP TABLE tbl_pc; +RESET enable_seqscan; +-- +-- alter table and index +-- +-- ALTER TABLE +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE TABLE tbl_pc(id int, c1 text); +ALTER TABLE tbl_pc SET(compresstype=pglz); -- fail +ERROR: change compresstype parameter is not supported +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER TABLE tbl_pc SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER TABLE tbl_pc SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER TABLE tbl_pc SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=pglz, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER TABLE tbl_pc RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER TABLE tbl_pc RESET(compresslevel); -- ok +ALTER TABLE tbl_pc RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=pglz, compress_chunk_size=1024 + +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 0 +(1 row) + +-- ALTER INDEX +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1); +ALTER INDEX tbl_pc_idx1 SET(compresstype=pglz); -- fail +ERROR: change compresstype parameter is not supported +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx1 SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx1 SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx1 SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) + "tbl_pc_idx1" btree (c1) WITH (compresstype=pglz, compress_chunk_size='1024', compresslevel='2', compress_prealloc_chunks='0') +Options: compresstype=pglz, compress_chunk_size=1024 + +ALTER INDEX tbl_pc_idx1 RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx1 RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx1 RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx1 RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) + "tbl_pc_idx1" btree (c1) WITH (compresstype=pglz, compress_chunk_size='1024') +Options: compresstype=pglz, compress_chunk_size=1024 + +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +----+---- +(0 rows) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Bitmap Heap Scan on tbl_pc + Recheck Cond: (c1 = '100'::text) + -> Bitmap Index Scan on tbl_pc_idx1 + Index Cond: (c1 = '100'::text) +(4 rows) + +-- alter hash index +CREATE INDEX tbl_pc_idx_hash on tbl_pc USING hash(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_hash SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_hash SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_hash SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_hash SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_hash + Index "public.tbl_pc_idx_hash" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + c1 | integer | yes | c1 | plain | +hash, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_hash RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_hash RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_hash RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_hash RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_hash + Index "public.tbl_pc_idx_hash" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + c1 | integer | yes | c1 | plain | +hash, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024 + +-- alter gin index +CREATE INDEX tbl_pc_idx_gin on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_gin SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gin SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gin SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_gin SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gin + Index "public.tbl_pc_idx_gin" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+-------------+---------+-------------- + array | integer | yes | (ARRAY[id]) | plain | +gin, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_gin RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gin RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gin RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gin RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gin + Index "public.tbl_pc_idx_gin" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+-------------+---------+-------------- + array | integer | yes | (ARRAY[id]) | plain | +gin, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024 + +-- alter gist index +CREATE INDEX tbl_pc_idx_gist on tbl_pc USING gist((point(id,id))) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_gist SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gist SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gist SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_gist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gist + Index "public.tbl_pc_idx_gist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+---------------------------------------------------+---------+-------------- + point | box | yes | point(id::double precision, id::double precision) | plain | +gist, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_gist RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gist RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gist + Index "public.tbl_pc_idx_gist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+---------------------------------------------------+---------+-------------- + point | box | yes | point(id::double precision, id::double precision) | plain | +gist, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024 + +-- alter spgist index +CREATE INDEX tbl_pc_idx_spgist on tbl_pc USING spgist(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_spgist SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_spgist SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_spgist SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_spgist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_spgist + Index "public.tbl_pc_idx_spgist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+------------+----------+-------------- + c1 | text | yes | c1 | extended | +spgist, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_spgist RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_spgist RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_spgist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_spgist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_spgist + Index "public.tbl_pc_idx_spgist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+------------+----------+-------------- + c1 | text | yes | c1 | extended | +spgist, for table "public.tbl_pc" +Options: compresstype=pglz, compress_chunk_size=1024 + +-- alter brin index (do not support compression) +CREATE INDEX tbl_pc_idx_brin on tbl_pc USING brin(c1); +ALTER INDEX tbl_pc_idx_brin SET(compress_prealloc_chunks=3); -- fail +ERROR: unrecognized parameter "compress_prealloc_chunks" +DROP TABLE tbl_pc; +-- +-- partitioned table and index +-- +-- partition table does not support compression, but index of partition table and its child tables can use compression +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id) WITH(compresstype=pglz); -- fail +ERROR: unrecognized parameter "compresstype" +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id); +CREATE TABLE tbl_pc_part_1 PARTITION OF tbl_pc_part FOR VALUES FROM (1) TO (1001); +CREATE TABLE tbl_pc_part_2 PARTITION OF tbl_pc_part FOR VALUES FROM (1001) TO (2001) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE INDEX part_id_idx ON tbl_pc_part(id) WITH(compresstype=pglz, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE TABLE tbl_pc_part_3 PARTITION OF tbl_pc_part FOR VALUES FROM (2001) TO (3001); +CREATE INDEX part3_id_idx1 ON tbl_pc_part_3(id) WITH(compresstype=pglz, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc_part + Partitioned table "public.tbl_pc_part" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition key: RANGE (id) +Indexes: + "part_id_idx" btree (id) WITH (compresstype=pglz, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Partitions: tbl_pc_part_1 FOR VALUES FROM (1) TO (1001), + tbl_pc_part_2 FOR VALUES FROM (1001) TO (2001), + tbl_pc_part_3 FOR VALUES FROM (2001) TO (3001) + +\d+ part_id_idx + Partitioned index "public.part_id_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + id | integer | yes | id | plain | +btree, for table "public.tbl_pc_part" +Partitions: tbl_pc_part_1_id_idx, + tbl_pc_part_2_id_idx, + tbl_pc_part_3_id_idx +Options: compresstype=pglz, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2 + +\d+ tbl_pc_part_1 + Table "public.tbl_pc_part_1" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (1) TO (1001) +Partition constraint: ((id IS NOT NULL) AND (id >= 1) AND (id < 1001)) +Indexes: + "tbl_pc_part_1_id_idx" btree (id) WITH (compresstype=pglz, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') + +\d+ tbl_pc_part_2 + Table "public.tbl_pc_part_2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (1001) TO (2001) +Partition constraint: ((id IS NOT NULL) AND (id >= 1001) AND (id < 2001)) +Indexes: + "tbl_pc_part_2_id_idx" btree (id) WITH (compresstype=pglz, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +\d+ tbl_pc_part_3 + Table "public.tbl_pc_part_3" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (2001) TO (3001) +Partition constraint: ((id IS NOT NULL) AND (id >= 2001) AND (id < 3001)) +Indexes: + "part3_id_idx1" btree (id) WITH (compresstype=pglz, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') + "tbl_pc_part_3_id_idx" btree (id) WITH (compresstype=pglz, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; + count +------- + 3000 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=100; + id | c1 +-----+----- + 100 | 100 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=1100; + id | c1 +------+------ + 1100 | 1100 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=2100; + id | c1 +------+------ + 2100 | 2100 +(1 row) + +ALTER TABLE tbl_pc_part SET(compresstype=pglz); -- fail +ERROR: unrecognized parameter "compresstype" +ALTER TABLE tbl_pc_part_1 SET(compresstype=pglz); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc_part_2 SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc_part_2 SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER TABLE tbl_pc_part_2 SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER TABLE tbl_pc_part_2 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_part_2 + Table "public.tbl_pc_part_2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (1001) TO (2001) +Partition constraint: ((id IS NOT NULL) AND (id >= 1001) AND (id < 2001)) +Indexes: + "tbl_pc_part_2_id_idx" btree (id) WITH (compresstype=pglz, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=pglz, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX part3_id_idx1 SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX part3_id_idx1 SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX part3_id_idx1 SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX part3_id_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ part3_id_idx1 + Index "public.part3_id_idx1" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + id | integer | yes | id | plain | +btree, for table "public.tbl_pc_part_3" +Options: compresstype=pglz, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX part_id_idx SET(compresstype=pglz); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +ALTER INDEX part_id_idx SET(compress_chunk_size=2048); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +ALTER INDEX part_id_idx SET(compress_prealloc_chunks=16); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +ALTER INDEX part_id_idx SET(compresslevel=2, compress_prealloc_chunks=0); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +\d+ tbl_pc_part + Partitioned table "public.tbl_pc_part" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition key: RANGE (id) +Indexes: + "part_id_idx" btree (id) WITH (compresstype=pglz, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Partitions: tbl_pc_part_1 FOR VALUES FROM (1) TO (1001), + tbl_pc_part_2 FOR VALUES FROM (1001) TO (2001), + tbl_pc_part_3 FOR VALUES FROM (2001) TO (3001) + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; + count +------- + 6000 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=100; + id | c1 +-----+----- + 100 | 100 + 100 | 100 +(2 rows) + +SELECT * FROM tbl_pc_part WHERE id=1100; + id | c1 +------+------ + 1100 | 1100 + 1100 | 1100 +(2 rows) + +SELECT * FROM tbl_pc_part WHERE id=2100; + id | c1 +------+------ + 2100 | 2100 + 2100 | 2100 +(2 rows) + +DROP TABLE tbl_pc_part; +-- +-- recycling space with vacuum (do not support) +-- +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compress_chunk_size=2048, compress_prealloc_chunks=0); +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_0 \gset +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_1000 \gset +SELECT :size_1000 > :size_0; -- true + ?column? +---------- + t +(1 row) + +DELETE FROM tbl_pc WHERE id > 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_500 \gset +SELECT count(*) FROM tbl_pc; + count +------- + 500 +(1 row) + +SELECT :size_500 = :size_1000; -- true + ?column? +---------- + t +(1 row) + +DELETE FROM tbl_pc WHERE id < 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_1 \gset +SELECT count(*) FROM tbl_pc; + count +------- + 1 +(1 row) + +SELECT :size_1 = :size_500; -- true + ?column? +---------- + t +(1 row) + +DELETE FROM tbl_pc; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_2 \gset +SELECT :size_0_2 = :size_500; -- true + ?column? +---------- + t +(1 row) + +VACUUM FULL tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_3 \gset +SELECT :size_0_3 = :size_0; -- true + ?column? +---------- + t +(1 row) + +DROP TABLE tbl_pc; +-- +-- truncate +-- +CREATE TABLE tbl_pc(id int) WITH(compresstype=pglz, compress_chunk_size=1024); +CREATE INDEX tbl_pc_idx ON tbl_pc(id) WITH(compresstype=pglz, compress_chunk_size=1024); +SELECT pg_relation_size('tbl_pc'::regclass) init_tbl_size, pg_relation_size('tbl_pc_idx'::regclass) init_idx_size \gset +INSERT INTO tbl_pc SELECT generate_series(1,3000); +CHECKPOINT; +SELECT pg_relation_size('tbl_pc'::regclass) > :init_tbl_size; -- true + ?column? +---------- + t +(1 row) + +SELECT pg_relation_size('tbl_pc_idx'::regclass) > :init_idx_size; -- true + ?column? +---------- + t +(1 row) + +TRUNCATE tbl_pc; +SELECT pg_relation_size('tbl_pc'::regclass) = :init_tbl_size; -- true + ?column? +---------- + t +(1 row) + +SELECT pg_relation_size('tbl_pc_idx'::regclass) = :init_idx_size; -- true + ?column? +---------- + t +(1 row) + +DROP TABLE tbl_pc; +-- combining commands(CREATE + TRUNCATE) +CREATE TABLE tbl_pc(id int) WITH(compresstype=pglz, compress_chunk_size=1024) \; +CREATE INDEX tbl_pc_idx ON tbl_pc(id) WITH(compresstype=pglz, compress_chunk_size=1024) \; +INSERT INTO tbl_pc SELECT generate_series(1,3000) \; +TRUNCATE tbl_pc; +SELECT pg_relation_size('tbl_pc'::regclass) = :init_tbl_size; -- true + ?column? +---------- + t +(1 row) + +SELECT pg_relation_size('tbl_pc_idx'::regclass) = :init_idx_size; -- true + ?column? +---------- + t +(1 row) + +DROP TABLE tbl_pc; +-- +-- database templete support +-- +SELECT current_database() olddb \gset +CREATE DATABASE pctest_dbt; +\c pctest_dbt +CREATE TABLE tbl_pc(id int) WITH(compresstype=pglz, compress_chunk_size=1024); +INSERT INTO tbl_pc SELECT generate_series(1,3000); +CREATE INDEX tbl_pc_idx ON tbl_pc(id) WITH(compresstype=pglz, compress_chunk_size=1024); +\c :olddb +CREATE DATABASE pctest_db1 template pctest_dbt; +\c pctest_db1 +SELECT count(*) FROM tbl_pc; + count +------- + 3000 +(1 row) + +SELECT id FROM tbl_pc WHERE id = 3000; + id +------ + 3000 +(1 row) + +\c :olddb +DROP DATABASE pctest_dbt; +DROP DATABASE pctest_db1; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 103e11483d..82f0e71990 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -135,3 +135,6 @@ test: event_trigger oidjoins # this test also uses event triggers, so likewise run it by itself test: fast_default + +# run page_compression alone temporarily +test: page_compression diff --git a/src/test/regress/sql/page_compression.sql b/src/test/regress/sql/page_compression.sql new file mode 100644 index 0000000000..67a146baf9 --- /dev/null +++ b/src/test/regress/sql/page_compression.sql @@ -0,0 +1,387 @@ +-- +-- Page compression tests +-- + +-- +-- create compressed table +-- +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=512); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=1024); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=2048); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=pglz, compresslevel=0, compress_chunk_size=4096, compress_prealloc_chunks=0); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compresslevel=-1, compress_chunk_size=1024, compress_prealloc_chunks=15); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=15) + AS SELECT id, id::text c1 FROM generate_series(1,1000)id; +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE TABLE tbl_pc2(LIKE tbl_pc INCLUDING ALL); +\d+ tbl_pc +DROP TABLE tbl_pc; +DROP TABLE tbl_pc2; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=none); +\d+ tbl_pc +DROP TABLE tbl_pc; + +-- invalid storage parameter +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=xyz); -- fail +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=pglz, compresslevel=xyz); -- fail +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=pglz, compress_chunk_size=1025); -- fail +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=pglz, compress_prealloc_chunks=16); -- fail + + +-- +-- create compressed index +-- +SET enable_seqscan = OFF; + +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +CREATE INDEX tbl_pc_idx1 on tbl_pc(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +\d+ tbl_pc + +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; + +-- call CHECKPOINT to flush shared buffer to compressed relation file +CHECKPOINT; + +-- run ANALYZE REINDEX VACUUM and CLUSTER on compressed table and index +ANALYZE tbl_pc; + +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + +REINDEX INDEX tbl_pc_idx1; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + +REINDEX TABLE tbl_pc; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + +VACUUM tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; + +VACUUM FULL tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; + +CLUSTER tbl_pc USING tbl_pc_idx1; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; + +DROP INDEX tbl_pc_idx1; + +-- check usage of compressed index with data +CREATE INDEX tbl_pc_idx1 on tbl_pc USING hash(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gist((point(id,id))) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING spgist(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; +DROP INDEX tbl_pc_idx1; + +-- brin index does not support compression +CREATE INDEX tbl_pc_idx1 on tbl_pc USING brin(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); -- fail + +DROP TABLE tbl_pc; +RESET enable_seqscan; + +-- +-- alter table and index +-- + +-- ALTER TABLE +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE TABLE tbl_pc(id int, c1 text); +ALTER TABLE tbl_pc SET(compresstype=pglz); -- fail +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER TABLE tbl_pc SET(compresstype=none); -- fail +ALTER TABLE tbl_pc SET(compress_chunk_size=2048); -- fail +ALTER TABLE tbl_pc SET(compress_prealloc_chunks=16); -- fail +ALTER TABLE tbl_pc SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc +ALTER TABLE tbl_pc RESET(compresstype); -- fail +ALTER TABLE tbl_pc RESET(compress_chunk_size); -- fail +ALTER TABLE tbl_pc RESET(compresslevel); -- ok +ALTER TABLE tbl_pc RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + +-- ALTER INDEX +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1); +ALTER INDEX tbl_pc_idx1 SET(compresstype=pglz); -- fail +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx1 SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx1 SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx1 SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc +ALTER INDEX tbl_pc_idx1 RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx1 RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx1 RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx1 RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + +-- alter hash index +CREATE INDEX tbl_pc_idx_hash on tbl_pc USING hash(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_hash SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_hash SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_hash SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_hash SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_hash +ALTER INDEX tbl_pc_idx_hash RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_hash RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_hash RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_hash RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_hash + +-- alter gin index +CREATE INDEX tbl_pc_idx_gin on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_gin SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_gin SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_gin SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_gin SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gin +ALTER INDEX tbl_pc_idx_gin RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_gin RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_gin RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gin RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gin + +-- alter gist index +CREATE INDEX tbl_pc_idx_gist on tbl_pc USING gist((point(id,id))) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_gist SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_gist SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_gist SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_gist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gist +ALTER INDEX tbl_pc_idx_gist RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_gist RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_gist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gist + +-- alter spgist index +CREATE INDEX tbl_pc_idx_spgist on tbl_pc USING spgist(c1) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_spgist SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_spgist SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_spgist SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_spgist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_spgist +ALTER INDEX tbl_pc_idx_spgist RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_spgist RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_spgist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_spgist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_spgist + +-- alter brin index (do not support compression) +CREATE INDEX tbl_pc_idx_brin on tbl_pc USING brin(c1); +ALTER INDEX tbl_pc_idx_brin SET(compress_prealloc_chunks=3); -- fail + +DROP TABLE tbl_pc; + +-- +-- partitioned table and index +-- + +-- partition table does not support compression, but index of partition table and its child tables can use compression +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id) WITH(compresstype=pglz); -- fail + +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id); +CREATE TABLE tbl_pc_part_1 PARTITION OF tbl_pc_part FOR VALUES FROM (1) TO (1001); +CREATE TABLE tbl_pc_part_2 PARTITION OF tbl_pc_part FOR VALUES FROM (1001) TO (2001) WITH(compresstype=pglz, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +CREATE INDEX part_id_idx ON tbl_pc_part(id) WITH(compresstype=pglz, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); + +CREATE TABLE tbl_pc_part_3 PARTITION OF tbl_pc_part FOR VALUES FROM (2001) TO (3001); + +CREATE INDEX part3_id_idx1 ON tbl_pc_part_3(id) WITH(compresstype=pglz, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); + +\d+ tbl_pc_part +\d+ part_id_idx +\d+ tbl_pc_part_1 +\d+ tbl_pc_part_2 +\d+ tbl_pc_part_3 + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; +SELECT * FROM tbl_pc_part WHERE id=100; +SELECT * FROM tbl_pc_part WHERE id=1100; +SELECT * FROM tbl_pc_part WHERE id=2100; + +ALTER TABLE tbl_pc_part SET(compresstype=pglz); -- fail +ALTER TABLE tbl_pc_part_1 SET(compresstype=pglz); -- fail + +ALTER TABLE tbl_pc_part_2 SET(compresstype=none); -- fail +ALTER TABLE tbl_pc_part_2 SET(compress_chunk_size=2048); -- fail +ALTER TABLE tbl_pc_part_2 SET(compress_prealloc_chunks=16); -- fail +ALTER TABLE tbl_pc_part_2 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_part_2 + +ALTER INDEX part3_id_idx1 SET(compresstype=none); -- fail +ALTER INDEX part3_id_idx1 SET(compress_chunk_size=2048); -- fail +ALTER INDEX part3_id_idx1 SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX part3_id_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ part3_id_idx1 + +ALTER INDEX part_id_idx SET(compresstype=pglz); -- fail +ALTER INDEX part_id_idx SET(compress_chunk_size=2048); -- fail +ALTER INDEX part_id_idx SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX part_id_idx SET(compresslevel=2, compress_prealloc_chunks=0); -- fail +\d+ tbl_pc_part + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; +SELECT * FROM tbl_pc_part WHERE id=100; +SELECT * FROM tbl_pc_part WHERE id=1100; +SELECT * FROM tbl_pc_part WHERE id=2100; + +DROP TABLE tbl_pc_part; + + +-- +-- recycling space with vacuum (do not support) +-- +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=pglz, compress_chunk_size=2048, compress_prealloc_chunks=0); +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_0 \gset + +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_1000 \gset + +SELECT :size_1000 > :size_0; -- true + +DELETE FROM tbl_pc WHERE id > 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_500 \gset +SELECT count(*) FROM tbl_pc; +SELECT :size_500 = :size_1000; -- true + +DELETE FROM tbl_pc WHERE id < 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_1 \gset +SELECT count(*) FROM tbl_pc; +SELECT :size_1 = :size_500; -- true + +DELETE FROM tbl_pc; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_2 \gset + +SELECT :size_0_2 = :size_500; -- true + +VACUUM FULL tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_3 \gset + +SELECT :size_0_3 = :size_0; -- true + +DROP TABLE tbl_pc; + +-- +-- truncate +-- + +CREATE TABLE tbl_pc(id int) WITH(compresstype=pglz, compress_chunk_size=1024); +CREATE INDEX tbl_pc_idx ON tbl_pc(id) WITH(compresstype=pglz, compress_chunk_size=1024); +SELECT pg_relation_size('tbl_pc'::regclass) init_tbl_size, pg_relation_size('tbl_pc_idx'::regclass) init_idx_size \gset +INSERT INTO tbl_pc SELECT generate_series(1,3000); +CHECKPOINT; +SELECT pg_relation_size('tbl_pc'::regclass) > :init_tbl_size; -- true +SELECT pg_relation_size('tbl_pc_idx'::regclass) > :init_idx_size; -- true + +TRUNCATE tbl_pc; +SELECT pg_relation_size('tbl_pc'::regclass) = :init_tbl_size; -- true +SELECT pg_relation_size('tbl_pc_idx'::regclass) = :init_idx_size; -- true +DROP TABLE tbl_pc; + +-- combining commands(CREATE + TRUNCATE) +CREATE TABLE tbl_pc(id int) WITH(compresstype=pglz, compress_chunk_size=1024) \; +CREATE INDEX tbl_pc_idx ON tbl_pc(id) WITH(compresstype=pglz, compress_chunk_size=1024) \; +INSERT INTO tbl_pc SELECT generate_series(1,3000) \; +TRUNCATE tbl_pc; + +SELECT pg_relation_size('tbl_pc'::regclass) = :init_tbl_size; -- true +SELECT pg_relation_size('tbl_pc_idx'::regclass) = :init_idx_size; -- true +DROP TABLE tbl_pc; + +-- +-- database templete support +-- +SELECT current_database() olddb \gset +CREATE DATABASE pctest_dbt; +\c pctest_dbt +CREATE TABLE tbl_pc(id int) WITH(compresstype=pglz, compress_chunk_size=1024); +INSERT INTO tbl_pc SELECT generate_series(1,3000); +CREATE INDEX tbl_pc_idx ON tbl_pc(id) WITH(compresstype=pglz, compress_chunk_size=1024); +\c :olddb +CREATE DATABASE pctest_db1 template pctest_dbt; +\c pctest_db1 +SELECT count(*) FROM tbl_pc; +SELECT id FROM tbl_pc WHERE id = 3000; +\c :olddb +DROP DATABASE pctest_dbt; +DROP DATABASE pctest_db1; + diff --git a/src/test/zstd/.gitignore b/src/test/zstd/.gitignore new file mode 100644 index 0000000000..5dcb3ff972 --- /dev/null +++ b/src/test/zstd/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/zstd/Makefile b/src/test/zstd/Makefile new file mode 100644 index 0000000000..0f6e446b9e --- /dev/null +++ b/src/test/zstd/Makefile @@ -0,0 +1,14 @@ +# src/test/zstd/Makefile + +REGRESS = page_compression_with_zstd + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/zstd +top_builddir = ../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/zstd/README b/src/test/zstd/README new file mode 100644 index 0000000000..b8b7c592d7 --- /dev/null +++ b/src/test/zstd/README @@ -0,0 +1,3 @@ +This directory contains tests for page compression with ztsd. + +The premise of running this test is to enable the '-with-zstd' option when running configure diff --git a/src/test/zstd/expected/page_compression_with_zstd.out b/src/test/zstd/expected/page_compression_with_zstd.out new file mode 100644 index 0000000000..1b7fe635d3 --- /dev/null +++ b/src/test/zstd/expected/page_compression_with_zstd.out @@ -0,0 +1,798 @@ +-- +-- Page compression tests +-- +-- +-- create compressed table +-- +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=zstd + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=512); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=zstd, compress_chunk_size=512 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=1024); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=zstd, compress_chunk_size=1024 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=2048); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=zstd, compress_chunk_size=2048 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compresslevel=0, compress_chunk_size=4096, compress_prealloc_chunks=0); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=zstd, compresslevel=0, compress_chunk_size=4096, compress_prealloc_chunks=0 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compresslevel=-1, compress_chunk_size=1024, compress_prealloc_chunks=15); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=zstd, compresslevel=-1, compress_chunk_size=1024, compress_prealloc_chunks=15 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=15) + AS SELECT id, id::text c1 FROM generate_series(1,1000)id; +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Options: compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=15 + +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE TABLE tbl_pc2(LIKE tbl_pc INCLUDING ALL); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) WITH (compresstype=zstd, compresslevel='1', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +DROP TABLE tbl_pc; +DROP TABLE tbl_pc2; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=none); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=none + +DROP TABLE tbl_pc; +-- invalid storage parameter +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=xyz); -- fail +ERROR: invalid value for enum option "compresstype": xyz +DETAIL: Valid values are "none", "pglz", "lz4" and "zstd". +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=zstd, compresslevel=xyz); -- fail +ERROR: invalid value for integer option "compresslevel": xyz +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=1025); -- fail +ERROR: invalid compress_chunk_size 1025, must be one of 512, 1024, 2048 or 4096 +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=zstd, compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +-- +-- create compressed index +-- +SET enable_seqscan = OFF; +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE INDEX tbl_pc_idx1 on tbl_pc(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) WITH (compresstype=zstd, compresslevel='1', compress_chunk_size='1024', compress_prealloc_chunks='2') + "tbl_pc_idx1" btree (c1) WITH (compresstype=zstd, compresslevel='1', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; +-- call CHECKPOINT to flush shared buffer to compressed relation file +CHECKPOINT; +-- run ANALYZE REINDEX VACUUM and CLUSTER on compressed table and index +ANALYZE tbl_pc; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Index Scan using tbl_pc_idx1 on tbl_pc + Index Cond: (c1 = '100'::text) +(2 rows) + +REINDEX INDEX tbl_pc_idx1; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +REINDEX TABLE tbl_pc; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +VACUUM tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +VACUUM FULL tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +CLUSTER tbl_pc USING tbl_pc_idx1; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 1000 +(1 row) + +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +DROP INDEX tbl_pc_idx1; +-- check usage of compressed index with data +CREATE INDEX tbl_pc_idx1 on tbl_pc USING hash(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Index Scan using tbl_pc_idx1 on tbl_pc + Index Cond: (c1 = '100'::text) +(2 rows) + +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; + QUERY PLAN +------------------------------------------------------- + Bitmap Heap Scan on tbl_pc + Recheck Cond: (ARRAY[id] @> '{100}'::integer[]) + -> Bitmap Index Scan on tbl_pc_idx1 + Index Cond: (ARRAY[id] @> '{100}'::integer[]) +(4 rows) + +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gist((point(id,id))) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Limit + -> Index Scan using tbl_pc_idx1 on tbl_pc + Order By: (point((id)::double precision, (id)::double precision) <-> '(100,100)'::point) +(3 rows) + +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING spgist(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +-----+----- + 100 | 100 +(1 row) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Index Scan using tbl_pc_idx1 on tbl_pc + Index Cond: (c1 = '100'::text) +(2 rows) + +DROP INDEX tbl_pc_idx1; +-- brin index does not support compression +CREATE INDEX tbl_pc_idx1 on tbl_pc USING brin(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); -- fail +ERROR: unrecognized parameter "compresstype" +DROP TABLE tbl_pc; +RESET enable_seqscan; +-- +-- alter table and index +-- +-- ALTER TABLE +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE TABLE tbl_pc(id int, c1 text); +ALTER TABLE tbl_pc SET(compresstype=zstd); -- fail +ERROR: change compresstype parameter is not supported +DROP TABLE tbl_pc; +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER TABLE tbl_pc SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER TABLE tbl_pc SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER TABLE tbl_pc SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=zstd, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER TABLE tbl_pc RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER TABLE tbl_pc RESET(compresslevel); -- ok +ALTER TABLE tbl_pc RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) +Options: compresstype=zstd, compress_chunk_size=1024 + +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + count +------- + 0 +(1 row) + +-- ALTER INDEX +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1); +ALTER INDEX tbl_pc_idx1 SET(compresstype=zstd); -- fail +ERROR: change compresstype parameter is not supported +DROP INDEX tbl_pc_idx1; +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx1 SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx1 SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx1 SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) + "tbl_pc_idx1" btree (c1) WITH (compresstype=zstd, compress_chunk_size='1024', compresslevel='2', compress_prealloc_chunks='0') +Options: compresstype=zstd, compress_chunk_size=1024 + +ALTER INDEX tbl_pc_idx1 RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx1 RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx1 RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx1 RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc + Table "public.tbl_pc" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | not null | | plain | | + c1 | text | | | | extended | | +Indexes: + "tbl_pc_pkey" PRIMARY KEY, btree (id) + "tbl_pc_idx1" btree (c1) WITH (compresstype=zstd, compress_chunk_size='1024') +Options: compresstype=zstd, compress_chunk_size=1024 + +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + id | c1 +----+---- +(0 rows) + +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + QUERY PLAN +---------------------------------------- + Bitmap Heap Scan on tbl_pc + Recheck Cond: (c1 = '100'::text) + -> Bitmap Index Scan on tbl_pc_idx1 + Index Cond: (c1 = '100'::text) +(4 rows) + +-- alter hash index +CREATE INDEX tbl_pc_idx_hash on tbl_pc USING hash(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_hash SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_hash SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_hash SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_hash SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_hash + Index "public.tbl_pc_idx_hash" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + c1 | integer | yes | c1 | plain | +hash, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_hash RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_hash RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_hash RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_hash RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_hash + Index "public.tbl_pc_idx_hash" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + c1 | integer | yes | c1 | plain | +hash, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024 + +-- alter gin index +CREATE INDEX tbl_pc_idx_gin on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_gin SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gin SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gin SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_gin SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gin + Index "public.tbl_pc_idx_gin" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+-------------+---------+-------------- + array | integer | yes | (ARRAY[id]) | plain | +gin, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_gin RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gin RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gin RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gin RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gin + Index "public.tbl_pc_idx_gin" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+-------------+---------+-------------- + array | integer | yes | (ARRAY[id]) | plain | +gin, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024 + +-- alter gist index +CREATE INDEX tbl_pc_idx_gist on tbl_pc USING gist((point(id,id))) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_gist SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gist SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gist SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_gist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gist + Index "public.tbl_pc_idx_gist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+---------------------------------------------------+---------+-------------- + point | box | yes | point(id::double precision, id::double precision) | plain | +gist, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_gist RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_gist RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_gist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gist + Index "public.tbl_pc_idx_gist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+---------------------------------------------------+---------+-------------- + point | box | yes | point(id::double precision, id::double precision) | plain | +gist, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024 + +-- alter spgist index +CREATE INDEX tbl_pc_idx_spgist on tbl_pc USING spgist(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx_spgist SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_spgist SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_spgist SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX tbl_pc_idx_spgist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_spgist + Index "public.tbl_pc_idx_spgist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+------------+----------+-------------- + c1 | text | yes | c1 | extended | +spgist, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX tbl_pc_idx_spgist RESET(compresstype); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX tbl_pc_idx_spgist RESET(compress_chunk_size); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX tbl_pc_idx_spgist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_spgist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_spgist + Index "public.tbl_pc_idx_spgist" + Column | Type | Key? | Definition | Storage | Stats target +--------+------+------+------------+----------+-------------- + c1 | text | yes | c1 | extended | +spgist, for table "public.tbl_pc" +Options: compresstype=zstd, compress_chunk_size=1024 + +-- alter brin index (do not support compression) +CREATE INDEX tbl_pc_idx_brin on tbl_pc USING brin(c1); +ALTER INDEX tbl_pc_idx_brin SET(compress_prealloc_chunks=3); -- fail +ERROR: unrecognized parameter "compress_prealloc_chunks" +DROP TABLE tbl_pc; +-- +-- partitioned table and index +-- +-- partition table does not support compression, but index of partition table and its child tables can use compression +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id) WITH(compresstype=zstd); -- fail +ERROR: unrecognized parameter "compresstype" +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id); +CREATE TABLE tbl_pc_part_1 PARTITION OF tbl_pc_part FOR VALUES FROM (1) TO (1001); +CREATE TABLE tbl_pc_part_2 PARTITION OF tbl_pc_part FOR VALUES FROM (1001) TO (2001) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE INDEX part_id_idx ON tbl_pc_part(id) WITH(compresstype=zstd, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE TABLE tbl_pc_part_3 PARTITION OF tbl_pc_part FOR VALUES FROM (2001) TO (3001); +CREATE INDEX part3_id_idx1 ON tbl_pc_part_3(id) WITH(compresstype=zstd, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc_part + Partitioned table "public.tbl_pc_part" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition key: RANGE (id) +Indexes: + "part_id_idx" btree (id) WITH (compresstype=zstd, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Partitions: tbl_pc_part_1 FOR VALUES FROM (1) TO (1001), + tbl_pc_part_2 FOR VALUES FROM (1001) TO (2001), + tbl_pc_part_3 FOR VALUES FROM (2001) TO (3001) + +\d+ part_id_idx + Partitioned index "public.part_id_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + id | integer | yes | id | plain | +btree, for table "public.tbl_pc_part" +Partitions: tbl_pc_part_1_id_idx, + tbl_pc_part_2_id_idx, + tbl_pc_part_3_id_idx +Options: compresstype=zstd, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2 + +\d+ tbl_pc_part_1 + Table "public.tbl_pc_part_1" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (1) TO (1001) +Partition constraint: ((id IS NOT NULL) AND (id >= 1) AND (id < 1001)) +Indexes: + "tbl_pc_part_1_id_idx" btree (id) WITH (compresstype=zstd, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') + +\d+ tbl_pc_part_2 + Table "public.tbl_pc_part_2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (1001) TO (2001) +Partition constraint: ((id IS NOT NULL) AND (id >= 1001) AND (id < 2001)) +Indexes: + "tbl_pc_part_2_id_idx" btree (id) WITH (compresstype=zstd, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2 + +\d+ tbl_pc_part_3 + Table "public.tbl_pc_part_3" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (2001) TO (3001) +Partition constraint: ((id IS NOT NULL) AND (id >= 2001) AND (id < 3001)) +Indexes: + "part3_id_idx1" btree (id) WITH (compresstype=zstd, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') + "tbl_pc_part_3_id_idx" btree (id) WITH (compresstype=zstd, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; + count +------- + 3000 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=100; + id | c1 +-----+----- + 100 | 100 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=1100; + id | c1 +------+------ + 1100 | 1100 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=2100; + id | c1 +------+------ + 2100 | 2100 +(1 row) + +ALTER TABLE tbl_pc_part SET(compresstype=zstd); -- fail +ERROR: unrecognized parameter "compresstype" +ALTER TABLE tbl_pc_part_1 SET(compresstype=zstd); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc_part_2 SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER TABLE tbl_pc_part_2 SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER TABLE tbl_pc_part_2 SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER TABLE tbl_pc_part_2 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_part_2 + Table "public.tbl_pc_part_2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition of: tbl_pc_part FOR VALUES FROM (1001) TO (2001) +Partition constraint: ((id IS NOT NULL) AND (id >= 1001) AND (id < 2001)) +Indexes: + "tbl_pc_part_2_id_idx" btree (id) WITH (compresstype=zstd, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Options: compresstype=zstd, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX part3_id_idx1 SET(compresstype=none); -- fail +ERROR: change compresstype parameter is not supported +ALTER INDEX part3_id_idx1 SET(compress_chunk_size=2048); -- fail +ERROR: change compress_chunk_size parameter is not supported +ALTER INDEX part3_id_idx1 SET(compress_prealloc_chunks=16); -- fail +ERROR: value 16 out of bounds for option "compress_prealloc_chunks" +DETAIL: Valid values are between "0" and "15". +ALTER INDEX part3_id_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ part3_id_idx1 + Index "public.part3_id_idx1" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + id | integer | yes | id | plain | +btree, for table "public.tbl_pc_part_3" +Options: compresstype=zstd, compress_chunk_size=1024, compresslevel=2, compress_prealloc_chunks=0 + +ALTER INDEX part_id_idx SET(compresstype=zstd); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +ALTER INDEX part_id_idx SET(compress_chunk_size=2048); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +ALTER INDEX part_id_idx SET(compress_prealloc_chunks=16); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +ALTER INDEX part_id_idx SET(compresslevel=2, compress_prealloc_chunks=0); -- fail +ERROR: ALTER action SET cannot be performed on relation "part_id_idx" +DETAIL: This operation is not supported for partitioned indexes. +\d+ tbl_pc_part + Partitioned table "public.tbl_pc_part" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + id | integer | | | | plain | | + c1 | text | | | | extended | | +Partition key: RANGE (id) +Indexes: + "part_id_idx" btree (id) WITH (compresstype=zstd, compresslevel='2', compress_chunk_size='1024', compress_prealloc_chunks='2') +Partitions: tbl_pc_part_1 FOR VALUES FROM (1) TO (1001), + tbl_pc_part_2 FOR VALUES FROM (1001) TO (2001), + tbl_pc_part_3 FOR VALUES FROM (2001) TO (3001) + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; + count +------- + 6000 +(1 row) + +SELECT * FROM tbl_pc_part WHERE id=100; + id | c1 +-----+----- + 100 | 100 + 100 | 100 +(2 rows) + +SELECT * FROM tbl_pc_part WHERE id=1100; + id | c1 +------+------ + 1100 | 1100 + 1100 | 1100 +(2 rows) + +SELECT * FROM tbl_pc_part WHERE id=2100; + id | c1 +------+------ + 2100 | 2100 + 2100 | 2100 +(2 rows) + +DROP TABLE tbl_pc_part; +-- +-- recycling space with vacuum (do not support) +-- +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compress_chunk_size=2048, compress_prealloc_chunks=0); +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_0 \gset +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_1000 \gset +SELECT :size_1000 > :size_0; -- true + ?column? +---------- + t +(1 row) + +DELETE FROM tbl_pc WHERE id > 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_500 \gset +SELECT count(*) FROM tbl_pc; + count +------- + 500 +(1 row) + +SELECT :size_500 = :size_1000; -- true + ?column? +---------- + t +(1 row) + +DELETE FROM tbl_pc WHERE id < 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_1 \gset +SELECT count(*) FROM tbl_pc; + count +------- + 1 +(1 row) + +SELECT :size_1 = :size_500; -- true + ?column? +---------- + t +(1 row) + +DELETE FROM tbl_pc; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_2 \gset +SELECT :size_0_2 = :size_500; -- true + ?column? +---------- + t +(1 row) + +VACUUM FULL tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_3 \gset +SELECT :size_0_3 = :size_0; -- true + ?column? +---------- + t +(1 row) + +DROP TABLE tbl_pc; diff --git a/src/test/zstd/sql/page_compression_with_zstd.sql b/src/test/zstd/sql/page_compression_with_zstd.sql new file mode 100644 index 0000000000..c68fbb0ef5 --- /dev/null +++ b/src/test/zstd/sql/page_compression_with_zstd.sql @@ -0,0 +1,341 @@ +-- +-- Page compression tests +-- + +-- +-- create compressed table +-- +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=512); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=1024); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=2048); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int, c1 text) WITH(compresstype=zstd, compresslevel=0, compress_chunk_size=4096, compress_prealloc_chunks=0); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compresslevel=-1, compress_chunk_size=1024, compress_prealloc_chunks=15); +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=15) + AS SELECT id, id::text c1 FROM generate_series(1,1000)id; +\d+ tbl_pc +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CREATE TABLE tbl_pc2(LIKE tbl_pc INCLUDING ALL); +\d+ tbl_pc +DROP TABLE tbl_pc; +DROP TABLE tbl_pc2; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=none); +\d+ tbl_pc +DROP TABLE tbl_pc; + +-- invalid storage parameter +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=xyz); -- fail +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=zstd, compresslevel=xyz); -- fail +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=zstd, compress_chunk_size=1025); -- fail +CREATE TABLE tbl_pc_error(id int, c1 text) WITH(compresstype=zstd, compress_prealloc_chunks=16); -- fail + + +-- +-- create compressed index +-- +SET enable_seqscan = OFF; + +CREATE TABLE tbl_pc(id int PRIMARY KEY WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2), c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +CREATE INDEX tbl_pc_idx1 on tbl_pc(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +\d+ tbl_pc + +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; + +-- call CHECKPOINT to flush shared buffer to compressed relation file +CHECKPOINT; + +-- run ANALYZE REINDEX VACUUM and CLUSTER on compressed table and index +ANALYZE tbl_pc; + +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + +REINDEX INDEX tbl_pc_idx1; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + +REINDEX TABLE tbl_pc; +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; + +VACUUM tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; + +VACUUM FULL tbl_pc; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; + +CLUSTER tbl_pc USING tbl_pc_idx1; +CHECKPOINT; +SELECT count(*) FROM tbl_pc; +SELECT * FROM tbl_pc WHERE c1='100'; + +DROP INDEX tbl_pc_idx1; + +-- check usage of compressed index with data +CREATE INDEX tbl_pc_idx1 on tbl_pc USING hash(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE ARRAY[id] @> ARRAY[100]; +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING gist((point(id,id))) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc ORDER BY point(id,id) <-> point(100,100) limit 1; +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING spgist(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; +DROP INDEX tbl_pc_idx1; + +-- brin index does not support compression +CREATE INDEX tbl_pc_idx1 on tbl_pc USING brin(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); -- fail + +DROP TABLE tbl_pc; +RESET enable_seqscan; + +-- +-- alter table and index +-- + +-- ALTER TABLE +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE TABLE tbl_pc(id int, c1 text); +ALTER TABLE tbl_pc SET(compresstype=zstd); -- fail +DROP TABLE tbl_pc; + +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER TABLE tbl_pc SET(compresstype=none); -- fail +ALTER TABLE tbl_pc SET(compress_chunk_size=2048); -- fail +ALTER TABLE tbl_pc SET(compress_prealloc_chunks=16); -- fail +ALTER TABLE tbl_pc SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc +ALTER TABLE tbl_pc RESET(compresstype); -- fail +ALTER TABLE tbl_pc RESET(compress_chunk_size); -- fail +ALTER TABLE tbl_pc RESET(compresslevel); -- ok +ALTER TABLE tbl_pc RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc +CHECKPOINT; +SELECT count(*) FROM tbl_pc; + +-- ALTER INDEX +-- ALTER compresstype and compress_chunk_size currently is not supported +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1); +ALTER INDEX tbl_pc_idx1 SET(compresstype=zstd); -- fail +DROP INDEX tbl_pc_idx1; + +CREATE INDEX tbl_pc_idx1 on tbl_pc USING btree(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); +ALTER INDEX tbl_pc_idx1 SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx1 SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx1 SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc +ALTER INDEX tbl_pc_idx1 RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx1 RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx1 RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx1 RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc +CHECKPOINT; +SELECT * FROM tbl_pc WHERE c1='100'; +EXPLAIN(COSTS off) SELECT * FROM tbl_pc WHERE c1='100'; + +-- alter hash index +CREATE INDEX tbl_pc_idx_hash on tbl_pc USING hash(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_hash SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_hash SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_hash SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_hash SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_hash +ALTER INDEX tbl_pc_idx_hash RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_hash RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_hash RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_hash RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_hash + +-- alter gin index +CREATE INDEX tbl_pc_idx_gin on tbl_pc USING gin((ARRAY[id])) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_gin SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_gin SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_gin SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_gin SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gin +ALTER INDEX tbl_pc_idx_gin RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_gin RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_gin RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gin RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gin + +-- alter gist index +CREATE INDEX tbl_pc_idx_gist on tbl_pc USING gist((point(id,id))) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_gist SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_gist SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_gist SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_gist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_gist +ALTER INDEX tbl_pc_idx_gist RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_gist RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_gist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_gist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_gist + +-- alter spgist index +CREATE INDEX tbl_pc_idx_spgist on tbl_pc USING spgist(c1) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +ALTER INDEX tbl_pc_idx_spgist SET(compresstype=none); -- fail +ALTER INDEX tbl_pc_idx_spgist SET(compress_chunk_size=2048); -- fail +ALTER INDEX tbl_pc_idx_spgist SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX tbl_pc_idx_spgist SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_idx_spgist +ALTER INDEX tbl_pc_idx_spgist RESET(compresstype); -- fail +ALTER INDEX tbl_pc_idx_spgist RESET(compress_chunk_size); -- fail +ALTER INDEX tbl_pc_idx_spgist RESET(compresslevel); -- ok +ALTER INDEX tbl_pc_idx_spgist RESET(compress_prealloc_chunks); -- ok +\d+ tbl_pc_idx_spgist + +-- alter brin index (do not support compression) +CREATE INDEX tbl_pc_idx_brin on tbl_pc USING brin(c1); +ALTER INDEX tbl_pc_idx_brin SET(compress_prealloc_chunks=3); -- fail + +DROP TABLE tbl_pc; + +-- +-- partitioned table and index +-- + +-- partition table does not support compression, but index of partition table and its child tables can use compression +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id) WITH(compresstype=zstd); -- fail + +CREATE TABLE tbl_pc_part (id int, c1 text) PARTITION BY RANGE (id); +CREATE TABLE tbl_pc_part_1 PARTITION OF tbl_pc_part FOR VALUES FROM (1) TO (1001); +CREATE TABLE tbl_pc_part_2 PARTITION OF tbl_pc_part FOR VALUES FROM (1001) TO (2001) WITH(compresstype=zstd, compresslevel=1, compress_chunk_size=1024, compress_prealloc_chunks=2); + +CREATE INDEX part_id_idx ON tbl_pc_part(id) WITH(compresstype=zstd, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); + +CREATE TABLE tbl_pc_part_3 PARTITION OF tbl_pc_part FOR VALUES FROM (2001) TO (3001); + +CREATE INDEX part3_id_idx1 ON tbl_pc_part_3(id) WITH(compresstype=zstd, compresslevel=2, compress_chunk_size=1024, compress_prealloc_chunks=2); + +\d+ tbl_pc_part +\d+ part_id_idx +\d+ tbl_pc_part_1 +\d+ tbl_pc_part_2 +\d+ tbl_pc_part_3 + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; +SELECT * FROM tbl_pc_part WHERE id=100; +SELECT * FROM tbl_pc_part WHERE id=1100; +SELECT * FROM tbl_pc_part WHERE id=2100; + +ALTER TABLE tbl_pc_part SET(compresstype=zstd); -- fail +ALTER TABLE tbl_pc_part_1 SET(compresstype=zstd); -- fail + +ALTER TABLE tbl_pc_part_2 SET(compresstype=none); -- fail +ALTER TABLE tbl_pc_part_2 SET(compress_chunk_size=2048); -- fail +ALTER TABLE tbl_pc_part_2 SET(compress_prealloc_chunks=16); -- fail +ALTER TABLE tbl_pc_part_2 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ tbl_pc_part_2 + +ALTER INDEX part3_id_idx1 SET(compresstype=none); -- fail +ALTER INDEX part3_id_idx1 SET(compress_chunk_size=2048); -- fail +ALTER INDEX part3_id_idx1 SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX part3_id_idx1 SET(compresslevel=2, compress_prealloc_chunks=0); -- ok +\d+ part3_id_idx1 + +ALTER INDEX part_id_idx SET(compresstype=zstd); -- fail +ALTER INDEX part_id_idx SET(compress_chunk_size=2048); -- fail +ALTER INDEX part_id_idx SET(compress_prealloc_chunks=16); -- fail +ALTER INDEX part_id_idx SET(compresslevel=2, compress_prealloc_chunks=0); -- fail +\d+ tbl_pc_part + +INSERT INTO tbl_pc_part SELECT id, id::text FROM generate_series(1,3000)id; +CHECKPOINT; +SELECT count(*) FROM tbl_pc_part; +SELECT * FROM tbl_pc_part WHERE id=100; +SELECT * FROM tbl_pc_part WHERE id=1100; +SELECT * FROM tbl_pc_part WHERE id=2100; + +DROP TABLE tbl_pc_part; + + +-- +-- recycling space with vacuum (do not support) +-- +CREATE TABLE tbl_pc(id int PRIMARY KEY, c1 text) WITH(compresstype=zstd, compress_chunk_size=2048, compress_prealloc_chunks=0); +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_0 \gset + +INSERT INTO tbl_pc SELECT id, id::text FROM generate_series(1,1000)id; +CHECKPOINT; +SELECT pg_relation_size('tbl_pc') size_1000 \gset + +SELECT :size_1000 > :size_0; -- true + +DELETE FROM tbl_pc WHERE id > 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_500 \gset +SELECT count(*) FROM tbl_pc; +SELECT :size_500 = :size_1000; -- true + +DELETE FROM tbl_pc WHERE id < 500; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_1 \gset +SELECT count(*) FROM tbl_pc; +SELECT :size_1 = :size_500; -- true + +DELETE FROM tbl_pc; +VACUUM tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_2 \gset + +SELECT :size_0_2 = :size_500; -- true + +VACUUM FULL tbl_pc; +SELECT pg_relation_size('tbl_pc') size_0_3 \gset + +SELECT :size_0_3 = :size_0; -- true + +DROP TABLE tbl_pc;