mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-22 13:40:56 +08:00
This change refactors our main planner hooks in `planner.c` with the intention of providing a consistent way to classify planned relations across hooks. In our hooks, we'd like to know whether a planned relation (`RelOptInfo`) is one of the following: * Hypertable * Hypertable child (a hypertable can appear as a child of itself) * Chunk as a child of hypertable (from expansion) * Chunk as standalone (operation directly on chunk) * Any other relation Previously, there was no way to consistently know which of these one was dealing with. Instead, a mix of various functions was used without "remembering" the classification for reuse in later sections of the code. When classifying relations according to the above categories, the only source of truth about a relation is our catalog metadata. In case of hypertables, this is cached in the hypertable cache. However, this cache is read-through, so, in case of a cache miss, the metadata will always be scanned to resolve a new entry. To avoid unnecessary metadata scans, this change introduces a way to do cache-only queries. This requires maintaining a single warmed cache throughout planning and is enabled by using a planner-global cache object. The pre-planning query processing warms the cache by populating it with all hypertables in the to-be-planned query.
400 lines
24 KiB
Plaintext
400 lines
24 KiB
Plaintext
-- This file and its contents are licensed under the Timescale License.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-TIMESCALE for a copy of the license.
|
|
\set ON_ERROR_STOP 0
|
|
--table with special column names --
|
|
create table foo2 (a integer, "bacB toD" integer, c integer, d integer);
|
|
select table_name from create_hypertable('foo2', 'a', chunk_time_interval=> 10);
|
|
NOTICE: adding not-null constraint to column "a"
|
|
table_name
|
|
------------
|
|
foo2
|
|
(1 row)
|
|
|
|
create table foo3 (a integer, "bacB toD" integer, c integer, d integer);
|
|
select table_name from create_hypertable('foo3', 'a', chunk_time_interval=> 10);
|
|
NOTICE: adding not-null constraint to column "a"
|
|
table_name
|
|
------------
|
|
foo3
|
|
(1 row)
|
|
|
|
create table non_compressed (a integer, "bacB toD" integer, c integer, d integer);
|
|
select table_name from create_hypertable('non_compressed', 'a', chunk_time_interval=> 10);
|
|
NOTICE: adding not-null constraint to column "a"
|
|
table_name
|
|
----------------
|
|
non_compressed
|
|
(1 row)
|
|
|
|
insert into non_compressed values( 3 , 16 , 20, 4);
|
|
ALTER TABLE foo2 set (timescaledb.compress_segmentby = '"bacB toD",c' , timescaledb.compress_orderby = 'c');
|
|
ERROR: the option timescaledb.compress must be set to true to enable compression
|
|
ALTER TABLE foo2 set (timescaledb.compress, timescaledb.compress_segmentby = '"bacB toD",c' , timescaledb.compress_orderby = 'c');
|
|
ERROR: cannot use column "c" in both timescaledb.compress_orderby and timescaledb.compress_segmentby
|
|
ALTER TABLE foo2 set (timescaledb.compress, timescaledb.compress_segmentby = '"bacB toD",c' , timescaledb.compress_orderby = 'd DESC');
|
|
NOTICE: adding index _compressed_hypertable_4_bacB toD__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_4 USING BTREE(bacB toD, _ts_meta_sequence_num)
|
|
NOTICE: adding index _compressed_hypertable_4_c__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_4 USING BTREE(c, _ts_meta_sequence_num)
|
|
ALTER TABLE foo2 set (timescaledb.compress, timescaledb.compress_segmentby = '"bacB toD",c' , timescaledb.compress_orderby = 'd');
|
|
NOTICE: adding index _compressed_hypertable_5_bacB toD__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_5 USING BTREE(bacB toD, _ts_meta_sequence_num)
|
|
NOTICE: adding index _compressed_hypertable_5_c__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_5 USING BTREE(c, _ts_meta_sequence_num)
|
|
create table with_oids (a integer, b integer) WITH OIDS;
|
|
select table_name from create_hypertable('with_oids', 'a', chunk_time_interval=> 10);
|
|
NOTICE: adding not-null constraint to column "a"
|
|
table_name
|
|
------------
|
|
with_oids
|
|
(1 row)
|
|
|
|
ALTER TABLE with_oids set (timescaledb.compress, timescaledb.compress_orderby='a');
|
|
ERROR: compression cannot be used on table with OIDs
|
|
create table with_rls (a integer, b integer);
|
|
ALTER TABLE with_rls ENABLE ROW LEVEL SECURITY;
|
|
select table_name from create_hypertable('with_rls', 'a', chunk_time_interval=> 10);
|
|
NOTICE: adding not-null constraint to column "a"
|
|
table_name
|
|
------------
|
|
with_rls
|
|
(1 row)
|
|
|
|
ALTER TABLE with_rls set (timescaledb.compress, timescaledb.compress_orderby='a');
|
|
ERROR: compression cannot be used on table with row security
|
|
--note that the time column "a" should be added to the end of the orderby list
|
|
select * from _timescaledb_catalog.hypertable_compression order by attname;
|
|
hypertable_id | attname | compression_algorithm_id | segmentby_column_index | orderby_column_index | orderby_asc | orderby_nullsfirst
|
|
---------------+----------+--------------------------+------------------------+----------------------+-------------+--------------------
|
|
1 | a | 4 | | 2 | f | t
|
|
1 | bacB toD | 0 | 1 | | |
|
|
1 | c | 0 | 2 | | |
|
|
1 | d | 4 | | 1 | t | f
|
|
(4 rows)
|
|
|
|
ALTER TABLE foo3 set (timescaledb.compress, timescaledb.compress_orderby='d DeSc NullS lAsT');
|
|
--shold allow alter since segment by was empty
|
|
ALTER TABLE foo3 set (timescaledb.compress, timescaledb.compress_orderby='d Asc NullS lAsT');
|
|
--this is ok too
|
|
ALTER TABLE foo3 set (timescaledb.compress, timescaledb.compress_segmentby = '"bacB toD",c', timescaledb.compress_orderby = 'd DeSc NullS lAsT');
|
|
NOTICE: adding index _compressed_hypertable_10_bacB toD__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_10 USING BTREE(bacB toD, _ts_meta_sequence_num)
|
|
NOTICE: adding index _compressed_hypertable_10_c__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_10 USING BTREE(c, _ts_meta_sequence_num)
|
|
-- Negative test cases ---
|
|
ALTER TABLE foo2 set (timescaledb.compress, timescaledb.compress_segmentby = '"bacB toD",c');
|
|
ERROR: need to specify timescaledb.compress_orderby if it was previously set
|
|
create table reserved_column_prefix (a integer, _ts_meta_foo integer, "bacB toD" integer, c integer, d integer);
|
|
select table_name from create_hypertable('reserved_column_prefix', 'a', chunk_time_interval=> 10);
|
|
NOTICE: adding not-null constraint to column "a"
|
|
table_name
|
|
------------------------
|
|
reserved_column_prefix
|
|
(1 row)
|
|
|
|
ALTER TABLE reserved_column_prefix set (timescaledb.compress);
|
|
ERROR: cannot compress tables with reserved column prefix '_ts_meta_'
|
|
--basic test with count
|
|
create table foo (a integer, b integer, c integer, t text, p point);
|
|
ALTER TABLE foo ADD CONSTRAINT chk_existing CHECK(b > 0);
|
|
select table_name from create_hypertable('foo', 'a', chunk_time_interval=> 10);
|
|
NOTICE: adding not-null constraint to column "a"
|
|
table_name
|
|
------------
|
|
foo
|
|
(1 row)
|
|
|
|
insert into foo values( 3 , 16 , 20);
|
|
insert into foo values( 10 , 10 , 20);
|
|
insert into foo values( 20 , 11 , 20);
|
|
insert into foo values( 30 , 12 , 20);
|
|
-- should error out --
|
|
ALTER TABLE foo ALTER b SET NOT NULL, set (timescaledb.compress);
|
|
ERROR: ALTER TABLE <hypertable> SET does not support multiple clauses
|
|
ALTER TABLE foo ALTER b SET NOT NULL;
|
|
select attname, attnotnull from pg_attribute where attrelid = (select oid from pg_class where relname like 'foo') and attname like 'b';
|
|
attname | attnotnull
|
|
---------+------------
|
|
b | t
|
|
(1 row)
|
|
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'd');
|
|
ERROR: column "d" specified in option timescaledb.compress_segmentby does not exist
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'd');
|
|
ERROR: column "d" in option timescaledb.compress_orderby does not exist
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c desc nulls');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c desc nulls'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c desc nulls thirsty');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c desc nulls thirsty'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c climb nulls first');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c climb nulls first'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c nulls first asC');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c nulls first asC'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c desc nulls first asc');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c desc nulls first asc'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c desc hurry');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c desc hurry'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c descend');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c descend'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c; SELECT 1');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c; SELECT 1'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = '1,2');
|
|
ERROR: unable to parse timescaledb.compress_orderby option '1,2'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c + 1');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c + 1'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'random()');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'random()'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c LIMIT 1');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c LIMIT 1'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'c USING <');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 'c USING <'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 't COLLATE "en_US"');
|
|
ERROR: unable to parse timescaledb.compress_orderby option 't COLLATE "en_US"'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'c asc' , timescaledb.compress_orderby = 'c');
|
|
ERROR: unable to parse timescaledb.compress_segmentby option 'c asc'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'c nulls last');
|
|
ERROR: unable to parse timescaledb.compress_segmentby option 'c nulls last'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'c + 1');
|
|
ERROR: unable to parse timescaledb.compress_segmentby option 'c + 1'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'random()');
|
|
ERROR: unable to parse timescaledb.compress_segmentby option 'random()'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'c LIMIT 1');
|
|
ERROR: unable to parse timescaledb.compress_segmentby option 'c LIMIT 1'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_segmentby = 'c + b');
|
|
ERROR: unable to parse timescaledb.compress_segmentby option 'c + b'
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, p');
|
|
ERROR: invalid order by column type: could not identify an less-than operator for type point
|
|
--should succeed
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a, b');
|
|
--ddl on ht with compression
|
|
ALTER TABLE foo ADD COLUMN new_column INT;
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
ALTER TABLE foo DROP COLUMN a;
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
ALTER TABLE foo DROP COLUMN t;
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
ALTER TABLE foo ALTER COLUMN t SET NOT NULL;
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
ALTER TABLE foo RESET (timescaledb.compress);
|
|
ERROR: compression options cannot be reset
|
|
ALTER TABLE foo ADD CONSTRAINT chk CHECK(b > 0);
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
ALTER TABLE foo ADD CONSTRAINT chk UNIQUE(b);
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
ALTER TABLE foo DROP CONSTRAINT chk_existing;
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
--note that the time column "a" should not be added to the end of the order by list again (should appear first)
|
|
select hc.* from _timescaledb_catalog.hypertable_compression hc inner join _timescaledb_catalog.hypertable h on (h.id = hc.hypertable_id) where h.table_name = 'foo' order by attname;
|
|
hypertable_id | attname | compression_algorithm_id | segmentby_column_index | orderby_column_index | orderby_asc | orderby_nullsfirst
|
|
---------------+---------+--------------------------+------------------------+----------------------+-------------+--------------------
|
|
12 | a | 4 | | 1 | t | f
|
|
12 | b | 4 | | 2 | t | f
|
|
12 | c | 4 | | | |
|
|
12 | p | 1 | | | |
|
|
12 | t | 2 | | | |
|
|
(5 rows)
|
|
|
|
select decompress_chunk(ch1.schema_name|| '.' || ch1.table_name)
|
|
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht where ch1.hypertable_id = ht.id and ht.table_name like 'foo' ORDER BY ch1.id limit 1;
|
|
ERROR: chunk "_hyper_12_2_chunk" is not compressed
|
|
--test changing the segment by columns
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a', timescaledb.compress_segmentby = 'b');
|
|
NOTICE: adding index _compressed_hypertable_14_b__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_14 USING BTREE(b, _ts_meta_sequence_num)
|
|
select ch1.schema_name|| '.' || ch1.table_name AS "CHUNK_NAME"
|
|
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht where ch1.hypertable_id = ht.id and ht.table_name like 'foo' ORDER BY ch1.id limit 1 \gset
|
|
select decompress_chunk(:'CHUNK_NAME');
|
|
ERROR: chunk "_hyper_12_2_chunk" is not compressed
|
|
select decompress_chunk(:'CHUNK_NAME', if_compressed=>true);
|
|
NOTICE: chunk "_hyper_12_2_chunk" is not compressed
|
|
decompress_chunk
|
|
------------------
|
|
|
|
(1 row)
|
|
|
|
--should succeed
|
|
select compress_chunk(:'CHUNK_NAME');
|
|
compress_chunk
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_12_2_chunk
|
|
(1 row)
|
|
|
|
select compress_chunk(:'CHUNK_NAME');
|
|
ERROR: chunk "_hyper_12_2_chunk" is already compressed
|
|
select compress_chunk(:'CHUNK_NAME', if_not_compressed=>true);
|
|
NOTICE: chunk "_hyper_12_2_chunk" is already compressed
|
|
compress_chunk
|
|
----------------
|
|
|
|
(1 row)
|
|
|
|
select compress_chunk(ch1.schema_name|| '.' || ch1.table_name)
|
|
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht where ch1.hypertable_id = ht.id and ht.table_name like 'non_compressed' ORDER BY ch1.id limit 1;
|
|
ERROR: chunks can be compressed only if compression property is set on the hypertable
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a', timescaledb.compress_segmentby = 'c');
|
|
ERROR: cannot change compression options as compressed chunks already exist for this table
|
|
ALTER TABLE foo set (timescaledb.compress='f');
|
|
ERROR: cannot change compression options as compressed chunks already exist for this table
|
|
ALTER TABLE foo reset (timescaledb.compress);
|
|
ERROR: compression options cannot be reset
|
|
select decompress_chunk(ch1.schema_name|| '.' || ch1.table_name)
|
|
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht where ch1.hypertable_id = ht.id and ht.table_name like 'non_compressed' ORDER BY ch1.id limit 1;
|
|
ERROR: missing compressed hypertable
|
|
--should succeed
|
|
select decompress_chunk(ch1.schema_name|| '.' || ch1.table_name)
|
|
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht where ch1.hypertable_id = ht.id and ht.table_name like 'foo' and ch1.compressed_chunk_id IS NOT NULL;
|
|
decompress_chunk
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_12_2_chunk
|
|
(1 row)
|
|
|
|
--should succeed
|
|
ALTER TABLE foo set (timescaledb.compress, timescaledb.compress_orderby = 'a', timescaledb.compress_segmentby = 'b');
|
|
NOTICE: adding index _compressed_hypertable_15_b__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_15 USING BTREE(b, _ts_meta_sequence_num)
|
|
select hc.* from _timescaledb_catalog.hypertable_compression hc inner join _timescaledb_catalog.hypertable h on (h.id = hc.hypertable_id) where h.table_name = 'foo' order by attname;
|
|
hypertable_id | attname | compression_algorithm_id | segmentby_column_index | orderby_column_index | orderby_asc | orderby_nullsfirst
|
|
---------------+---------+--------------------------+------------------------+----------------------+-------------+--------------------
|
|
12 | a | 4 | | 1 | t | f
|
|
12 | b | 0 | 1 | | |
|
|
12 | c | 4 | | | |
|
|
12 | p | 1 | | | |
|
|
12 | t | 2 | | | |
|
|
(5 rows)
|
|
|
|
SELECT comp_hyper.schema_name|| '.' || comp_hyper.table_name as "COMPRESSED_HYPER_NAME"
|
|
FROM _timescaledb_catalog.hypertable comp_hyper
|
|
INNER JOIN _timescaledb_catalog.hypertable uncomp_hyper ON (comp_hyper.id = uncomp_hyper.compressed_hypertable_id)
|
|
WHERE uncomp_hyper.table_name like 'foo' ORDER BY comp_hyper.id LIMIT 1 \gset
|
|
select add_drop_chunks_policy(:'COMPRESSED_HYPER_NAME', INTERVAL '4 months', true);
|
|
ERROR: cannot add drop chunks policy to compressed hypertable "_compressed_hypertable_15"
|
|
--Constraint checking for compression
|
|
create table fortable(col integer primary key);
|
|
create table table_constr( device_id integer,
|
|
timec integer ,
|
|
location integer ,
|
|
c integer constraint valid_cval check (c > 20) ,
|
|
d integer,
|
|
primary key ( device_id, timec)
|
|
);
|
|
select table_name from create_hypertable('table_constr', 'timec', chunk_time_interval=> 10);
|
|
table_name
|
|
--------------
|
|
table_constr
|
|
(1 row)
|
|
|
|
ALTER TABLE table_constr set (timescaledb.compress, timescaledb.compress_segmentby = 'd');
|
|
ERROR: constraint "table_constr_pkey" requires column "device_id" to be a timescaledb.compress_segmentby or timescaledb.compress_orderby column for compression
|
|
alter table table_constr add constraint table_constr_uk unique (location, timec, device_id);
|
|
ALTER TABLE table_constr set (timescaledb.compress, timescaledb.compress_orderby = 'timec', timescaledb.compress_segmentby = 'device_id');
|
|
ERROR: constraint "table_constr_uk" requires column "location" to be a timescaledb.compress_segmentby or timescaledb.compress_orderby column for compression
|
|
alter table table_constr add constraint table_constr_fk FOREIGN KEY(d) REFERENCES fortable(col) on delete cascade;
|
|
ALTER TABLE table_constr set (timescaledb.compress, timescaledb.compress_orderby = 'timec', timescaledb.compress_segmentby = 'device_id, location');
|
|
ERROR: constraint "table_constr_fk" requires column "d" to be a timescaledb.compress_segmentby column for compression
|
|
--exclusion constraints not allowed
|
|
alter table table_constr add constraint table_constr_exclu exclude using btree (timec with = );
|
|
ALTER TABLE table_constr set (timescaledb.compress, timescaledb.compress_orderby = 'timec', timescaledb.compress_segmentby = 'device_id, location, d');
|
|
ERROR: constraint table_constr_exclu is not supported for compression
|
|
alter table table_constr drop constraint table_constr_exclu ;
|
|
--now it works
|
|
ALTER TABLE table_constr set (timescaledb.compress, timescaledb.compress_orderby = 'timec', timescaledb.compress_segmentby = 'device_id, location, d');
|
|
NOTICE: adding index _compressed_hypertable_17_device_id__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_17 USING BTREE(device_id, _ts_meta_sequence_num)
|
|
NOTICE: adding index _compressed_hypertable_17_location__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_17 USING BTREE(location, _ts_meta_sequence_num)
|
|
NOTICE: adding index _compressed_hypertable_17_d__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_17 USING BTREE(d, _ts_meta_sequence_num)
|
|
--can't add fks after compression enabled
|
|
alter table table_constr add constraint table_constr_fk_add_after FOREIGN KEY(d) REFERENCES fortable(col) on delete cascade;
|
|
ERROR: operation not supported on hypertables that have compression enabled
|
|
--FK check should not error even with dropped columns (previously had a bug related to this)
|
|
CREATE TABLE table_fk (
|
|
time timestamptz NOT NULL,
|
|
id1 int8 NOT NULL,
|
|
id2 int8 NOT NULL,
|
|
value float8 NULL,
|
|
CONSTRAINT fk1 FOREIGN KEY (id1) REFERENCES fortable(col),
|
|
CONSTRAINT fk2 FOREIGN KEY (id2) REFERENCES fortable(col)
|
|
);
|
|
SELECT create_hypertable('table_fk', 'time');
|
|
create_hypertable
|
|
------------------------
|
|
(18,public,table_fk,t)
|
|
(1 row)
|
|
|
|
ALTER TABLE table_fk DROP COLUMN id1;
|
|
ALTER TABLE table_fk SET (timescaledb.compress,timescaledb.compress_segmentby = 'id2');
|
|
NOTICE: adding index _compressed_hypertable_19_id2__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_19 USING BTREE(id2, _ts_meta_sequence_num)
|
|
-- TEST fk cascade delete behavior on compressed chunk --
|
|
insert into fortable values(1);
|
|
insert into fortable values(10);
|
|
--we want 2 chunks here --
|
|
insert into table_constr values(1000, 1, 44, 44, 1);
|
|
insert into table_constr values(1000, 10, 44, 44, 10);
|
|
select ch1.schema_name|| '.' || ch1.table_name AS "CHUNK_NAME"
|
|
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht
|
|
where ch1.hypertable_id = ht.id and ht.table_name like 'table_constr'
|
|
ORDER BY ch1.id limit 1 \gset
|
|
-- we have 1 compressed and 1 uncompressed chunk after this.
|
|
select compress_chunk(:'CHUNK_NAME');
|
|
compress_chunk
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_16_7_chunk
|
|
(1 row)
|
|
|
|
SELECT hypertable_name , total_chunks , number_compressed_chunks
|
|
FROM timescaledb_information.compressed_hypertable_stats;
|
|
hypertable_name | total_chunks | number_compressed_chunks
|
|
-----------------+--------------+--------------------------
|
|
table_constr | 2 | 1
|
|
(1 row)
|
|
|
|
--delete from foreign table, should delete from hypertable too
|
|
select device_id, d from table_constr order by device_id, d;
|
|
device_id | d
|
|
-----------+----
|
|
1000 | 1
|
|
1000 | 10
|
|
(2 rows)
|
|
|
|
delete from fortable where col = 1 or col = 10;
|
|
ERROR: cannot update/delete rows from chunk "_hyper_16_7_chunk" as it is compressed
|
|
select device_id, d from table_constr order by device_id, d;
|
|
device_id | d
|
|
-----------+----
|
|
1000 | 1
|
|
1000 | 10
|
|
(2 rows)
|
|
|
|
--github issue 1661
|
|
--disable compression after enabling it on a table that has fk constraints
|
|
CREATE TABLE table_constr2( device_id integer,
|
|
timec integer ,
|
|
location integer ,
|
|
d integer references fortable(col),
|
|
primary key ( device_id, timec)
|
|
);
|
|
SELECT table_name from create_hypertable('table_constr2', 'timec', chunk_time_interval=> 10);
|
|
table_name
|
|
---------------
|
|
table_constr2
|
|
(1 row)
|
|
|
|
INSERT INTO fortable VALUES( 99 );
|
|
INSERT INTO table_constr2 VALUES( 1000, 10, 5, 99);
|
|
ALTER TABLE table_constr2 SET (timescaledb.compress, timescaledb.compress_segmentby = 'device_id');
|
|
ERROR: constraint "table_constr2_d_fkey" requires column "d" to be a timescaledb.compress_segmentby column for compression
|
|
ALTER TABLE table_constr2 SET (timescaledb.compress, timescaledb.compress_segmentby = 'device_id, d');
|
|
NOTICE: adding index _compressed_hypertable_21_device_id__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_21 USING BTREE(device_id, _ts_meta_sequence_num)
|
|
NOTICE: adding index _compressed_hypertable_21_d__ts_meta_sequence_num_idx ON _timescaledb_internal._compressed_hypertable_21 USING BTREE(d, _ts_meta_sequence_num)
|
|
--compress a chunk and try to disable compression, it should fail --
|
|
SELECT ch1.schema_name|| '.' || ch1.table_name AS "CHUNK_NAME"
|
|
FROM _timescaledb_catalog.chunk ch1, _timescaledb_catalog.hypertable ht
|
|
WHERE ch1.hypertable_id = ht.id and ht.table_name like 'table_constr2' \gset
|
|
SELECT compress_chunk(:'CHUNK_NAME');
|
|
compress_chunk
|
|
------------------------------------------
|
|
_timescaledb_internal._hyper_20_10_chunk
|
|
(1 row)
|
|
|
|
ALTER TABLE table_constr2 set (timescaledb.compress=false);
|
|
ERROR: cannot change compression options as compressed chunks already exist for this table
|
|
--decompress all chunks and disable compression.
|
|
SELECT decompress_chunk(:'CHUNK_NAME');
|
|
decompress_chunk
|
|
------------------------------------------
|
|
_timescaledb_internal._hyper_20_10_chunk
|
|
(1 row)
|
|
|
|
ALTER TABLE table_constr2 SET (timescaledb.compress=false);
|