mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 18:43:18 +08:00
381 lines
17 KiB
Plaintext
381 lines
17 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
|
|
CREATE VIEW hypertable_details AS
|
|
WITH
|
|
names AS (SELECT * FROM pg_class cl JOIN pg_namespace ns ON ns.oid = relnamespace)
|
|
SELECT (SELECT format('%I.%I', ht.schema_name, ht.table_name) FROM names
|
|
WHERE ht.schema_name = nspname AND ht.table_name = relname) AS hypertable,
|
|
(SELECT relacl FROM names
|
|
WHERE ht.schema_name = nspname AND ht.table_name = relname) AS hypertable_acl,
|
|
(SELECT format('%I.%I', ct.schema_name, ct.table_name) FROM names
|
|
WHERE ct.schema_name = nspname AND ct.table_name = relname) AS compressed,
|
|
(SELECT relacl FROM names
|
|
WHERE ct.schema_name = nspname AND ct.table_name = relname) AS compressed_acl
|
|
FROM _timescaledb_catalog.hypertable ht
|
|
LEFT JOIN _timescaledb_catalog.hypertable ct ON ht.compressed_hypertable_id = ct.id;
|
|
CREATE VIEW chunk_details AS
|
|
WITH
|
|
names AS (SELECT * FROM pg_class cl JOIN pg_namespace ns ON ns.oid = relnamespace)
|
|
SELECT (SELECT format('%I.%I', ht.schema_name, ht.table_name) FROM names
|
|
WHERE ht.schema_name = nspname AND ht.table_name = relname) AS hypertable,
|
|
(SELECT relacl FROM names
|
|
WHERE ht.schema_name = nspname AND ht.table_name = relname) AS hypertable_acl,
|
|
(SELECT format('%I.%I', ch.schema_name, ch.table_name) FROM names
|
|
WHERE ch.schema_name = nspname AND ch.table_name = relname) AS chunk,
|
|
(SELECT relacl FROM names
|
|
WHERE ch.schema_name = nspname AND ch.table_name = relname) AS chunk_acl
|
|
FROM _timescaledb_catalog.hypertable ht
|
|
JOIN _timescaledb_catalog.chunk ch ON ch.hypertable_id = ht.id;
|
|
CREATE TABLE conditions (
|
|
timec TIMESTAMPTZ NOT NULL,
|
|
location TEXT NOT NULL,
|
|
location2 char(10) NOT NULL,
|
|
temperature DOUBLE PRECISION NULL,
|
|
humidity DOUBLE PRECISION NULL
|
|
);
|
|
select table_name from create_hypertable( 'conditions', 'timec', chunk_time_interval=>'1month'::interval);
|
|
table_name
|
|
------------
|
|
conditions
|
|
(1 row)
|
|
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
alter table conditions set (timescaledb.compress, timescaledb.compress_segmentby = 'location', timescaledb.compress_orderby = 'timec');
|
|
ERROR: must be owner of table conditions
|
|
insert into conditions
|
|
select generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '1 day'), 'POR', 'klick', 55, 75;
|
|
ERROR: permission denied for table conditions
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
--now owner tries and succeeds --
|
|
alter table conditions set (timescaledb.compress, timescaledb.compress_segmentby = 'location', timescaledb.compress_orderby = 'timec');
|
|
insert into conditions
|
|
select generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '1 day'), 'POR', 'klick', 55, 75;
|
|
--try modifying compress properties --
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
alter table conditions set (timescaledb.compress, timescaledb.compress_segmentby = 'location', timescaledb.compress_orderby = 'humidity');
|
|
ERROR: must be owner of table conditions
|
|
--- compress_chunks and decompress_chunks fail without correct perm --
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
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 'conditions' and ch1.compressed_chunk_id IS NULL;
|
|
ERROR: must be owner of hypertable "conditions"
|
|
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 'conditions';
|
|
ERROR: must be owner of hypertable "conditions"
|
|
select add_compression_policy('conditions', '1day'::interval);
|
|
ERROR: must be owner of hypertable "conditions"
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
select add_compression_policy('conditions', '1day'::interval);
|
|
add_compression_policy
|
|
------------------------
|
|
1000
|
|
(1 row)
|
|
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
--try dropping policy
|
|
select remove_compression_policy('conditions', true);
|
|
ERROR: must be owner of hypertable "conditions"
|
|
--Tests for GRANTS.
|
|
-- as owner grant select , compress chunk and check SELECT works
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
GRANT SELECT on conditions to :ROLE_DEFAULT_PERM_USER_2;
|
|
select count(*) from
|
|
(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 'conditions' and ch1.compressed_chunk_id IS NULL ) as subq;
|
|
count
|
|
-------
|
|
2
|
|
(1 row)
|
|
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
select count(*) from conditions;
|
|
count
|
|
-------
|
|
31
|
|
(1 row)
|
|
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
GRANT INSERT on conditions to :ROLE_DEFAULT_PERM_USER_2;
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
insert into conditions
|
|
select '2019-04-01 00:00+0'::timestamp with time zone, 'NYC', 'klick', 55, 75;
|
|
select count(*) from conditions;
|
|
count
|
|
-------
|
|
32
|
|
(1 row)
|
|
|
|
update conditions
|
|
set location = 'SFO'
|
|
where timec = '2019-04-01 00:00+0'::timestamp with time zone;
|
|
ERROR: permission denied for table conditions
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
GRANT UPDATE, DELETE on conditions to :ROLE_DEFAULT_PERM_USER_2;
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
select location from conditions where timec = '2019-04-01 00:00+0';
|
|
location
|
|
----------
|
|
NYC
|
|
(1 row)
|
|
|
|
--NOTE constraint exclusion excludes the other chunks here
|
|
--otherwise update would fail
|
|
update conditions
|
|
set location = 'SFO'
|
|
where timec = '2019-04-01 00:00+0'::timestamp with time zone;
|
|
select location from conditions where timec = '2019-04-01 00:00+0';
|
|
location
|
|
----------
|
|
SFO
|
|
(1 row)
|
|
|
|
--update expected to fail as executor touches all chunks
|
|
update conditions
|
|
set location = 'PNC'
|
|
where location = 'SFO';
|
|
ERROR: cannot update/delete rows from chunk "_hyper_1_1_chunk" as it is compressed
|
|
delete from conditions
|
|
where timec = '2019-04-01 00:00+0'::timestamp with time zone;
|
|
select location from conditions where timec = '2019-04-01 00:00+0';
|
|
location
|
|
----------
|
|
(0 rows)
|
|
|
|
CREATE VIEW v2 as select * from conditions;
|
|
select count(*) from v2;
|
|
count
|
|
-------
|
|
31
|
|
(1 row)
|
|
|
|
--should fail after revoking permissions
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
REVOKE SELECT on conditions FROM :ROLE_DEFAULT_PERM_USER_2;
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
|
select count(*) from v2;
|
|
ERROR: permission denied for table conditions
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
DROP TABLE conditions CASCADE;
|
|
NOTICE: drop cascades to 2 other objects
|
|
NOTICE: drop cascades to view v2
|
|
-- Testing that permissions propagate to compressed hypertables and to
|
|
-- compressed chunks.
|
|
-- Table is created by superuser
|
|
CREATE TABLE conditions (
|
|
timec TIMESTAMPTZ NOT NULL,
|
|
location TEXT NOT NULL,
|
|
temperature DOUBLE PRECISION NULL,
|
|
humidity DOUBLE PRECISION NULL
|
|
);
|
|
SELECT table_name FROM create_hypertable( 'conditions', 'timec',
|
|
chunk_time_interval => '1 week'::interval);
|
|
table_name
|
|
------------
|
|
conditions
|
|
(1 row)
|
|
|
|
ALTER TABLE conditions SET (
|
|
timescaledb.compress,
|
|
timescaledb.compress_segmentby = 'location',
|
|
timescaledb.compress_orderby = 'timec'
|
|
);
|
|
INSERT INTO conditions
|
|
SELECT generate_series('2018-12-01 00:00'::timestamp, '2018-12-31 00:00'::timestamp, '1 day'), 'POR', 55, 75;
|
|
SELECT compress_chunk(show_chunks('conditions'));
|
|
compress_chunk
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_3_6_chunk
|
|
_timescaledb_internal._hyper_3_7_chunk
|
|
_timescaledb_internal._hyper_3_8_chunk
|
|
_timescaledb_internal._hyper_3_9_chunk
|
|
_timescaledb_internal._hyper_3_10_chunk
|
|
(5 rows)
|
|
|
|
-- Check that ACL propagates to compressed hypertable. We could prune
|
|
-- the listing by only selecting chunks where the ACL does not match
|
|
-- the hypertable ACL, but for now we list all to make debugging easy.
|
|
\x on
|
|
SELECT * FROM hypertable_details WHERE hypertable = 'public.conditions';
|
|
-[ RECORD 1 ]--+-----------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl |
|
|
compressed | _timescaledb_internal._compressed_hypertable_4
|
|
compressed_acl |
|
|
|
|
SELECT htd.hypertable, htd.hypertable_acl, chunk, chunk_acl
|
|
FROM chunk_details chd JOIN hypertable_details htd ON chd.hypertable = htd.compressed
|
|
ORDER BY hypertable, chunk;
|
|
-[ RECORD 1 ]--+------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl |
|
|
chunk | _timescaledb_internal.compress_hyper_4_11_chunk
|
|
chunk_acl |
|
|
-[ RECORD 2 ]--+------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl |
|
|
chunk | _timescaledb_internal.compress_hyper_4_12_chunk
|
|
chunk_acl |
|
|
-[ RECORD 3 ]--+------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl |
|
|
chunk | _timescaledb_internal.compress_hyper_4_13_chunk
|
|
chunk_acl |
|
|
-[ RECORD 4 ]--+------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl |
|
|
chunk | _timescaledb_internal.compress_hyper_4_14_chunk
|
|
chunk_acl |
|
|
-[ RECORD 5 ]--+------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl |
|
|
chunk | _timescaledb_internal.compress_hyper_4_15_chunk
|
|
chunk_acl |
|
|
|
|
GRANT SELECT ON conditions TO :ROLE_DEFAULT_PERM_USER;
|
|
SELECT * FROM hypertable_details WHERE hypertable = 'public.conditions';
|
|
-[ RECORD 1 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
compressed | _timescaledb_internal._compressed_hypertable_4
|
|
compressed_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
|
|
SELECT htd.hypertable, htd.hypertable_acl, chunk, chunk_acl
|
|
FROM chunk_details chd JOIN hypertable_details htd ON chd.hypertable = htd.compressed
|
|
ORDER BY hypertable, chunk;
|
|
-[ RECORD 1 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_11_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 2 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_12_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 3 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_13_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 4 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_14_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 5 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_15_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
|
|
-- Add some new data and compress the chunks. The chunks should get
|
|
-- the permissions of the hypertable. We pick a start date to make
|
|
-- sure that we are not inserting into an already compressed chunk.
|
|
INSERT INTO conditions
|
|
SELECT generate_series('2019-01-07 00:00'::timestamp, '2019-02-07 00:00'::timestamp, '1 day'), 'XYZ', 47, 11;
|
|
SELECT compress_chunk(show_chunks('conditions', newer_than => '2019-01-01'));
|
|
-[ RECORD 1 ]--+----------------------------------------
|
|
compress_chunk | _timescaledb_internal._hyper_3_16_chunk
|
|
-[ RECORD 2 ]--+----------------------------------------
|
|
compress_chunk | _timescaledb_internal._hyper_3_17_chunk
|
|
-[ RECORD 3 ]--+----------------------------------------
|
|
compress_chunk | _timescaledb_internal._hyper_3_18_chunk
|
|
-[ RECORD 4 ]--+----------------------------------------
|
|
compress_chunk | _timescaledb_internal._hyper_3_19_chunk
|
|
-[ RECORD 5 ]--+----------------------------------------
|
|
compress_chunk | _timescaledb_internal._hyper_3_20_chunk
|
|
-[ RECORD 6 ]--+----------------------------------------
|
|
compress_chunk | _timescaledb_internal._hyper_3_21_chunk
|
|
|
|
SELECT htd.hypertable, htd.hypertable_acl, chunk, chunk_acl
|
|
FROM chunk_details chd JOIN hypertable_details htd ON chd.hypertable = htd.compressed
|
|
ORDER BY hypertable, chunk;
|
|
-[ RECORD 1 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_11_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 2 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_12_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 3 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_13_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 4 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_14_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 5 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_15_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 6 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_22_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 7 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_23_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 8 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_24_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 9 ]--+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_25_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 10 ]-+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_26_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
-[ RECORD 11 ]-+---------------------------------------------------------------
|
|
hypertable | public.conditions
|
|
hypertable_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
chunk | _timescaledb_internal.compress_hyper_4_27_chunk
|
|
chunk_acl | {super_user=arwdDxt/super_user,default_perm_user=r/super_user}
|
|
|
|
\x off
|
|
--TEST user that has insert permission can insert into a compressed chunk
|
|
GRANT INSERT ON conditions TO :ROLE_DEFAULT_PERM_USER;
|
|
SELECT count(*) FROM conditions;
|
|
count
|
|
-------
|
|
63
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM ( SELECT show_chunks('conditions'))q;
|
|
count
|
|
-------
|
|
11
|
|
(1 row)
|
|
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
--insert into a compressed chunk --
|
|
INSERT INTO conditions VALUES( '2018-12-02 00:00'::timestamp, 'NYC', 75, 95);
|
|
SELECT count(*) FROM conditions;
|
|
count
|
|
-------
|
|
64
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM ( SELECT show_chunks('conditions'))q;
|
|
count
|
|
-------
|
|
11
|
|
(1 row)
|
|
|