mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 11:03:36 +08:00
Change how permissions work with continuous aggs
To create a continuous agg you now only need SELECT and TRIGGER permission on the raw table. To continue refreshing the continuous agg the owner of the continuous agg needs only SELECT permission. This commit adds tests to make sure that removing the SELECT permission removes ability to refresh using both REFRESH MATERIALIZED VIEW and also through a background worker. This work also uncovered divergence in permission logic for creating triggers by a CREATE TRIGGER on chunks and when new chunks are created. This has now been unified: there is a check to make sure you can create the trigger on the main table and then there is a check that the owner of the main table can create triggers on chunks. Alter view for continuous aggregates is allowed for the owner of the view.
This commit is contained in:
parent
d3e582fd23
commit
d580abf04f
@ -433,6 +433,10 @@ ts_hypertable_create_trigger(Hypertable *ht, CreateTrigStmt *stmt, const char *q
|
||||
ObjectAddress root_trigger_addr;
|
||||
List *chunks;
|
||||
ListCell *lc;
|
||||
int sec_ctx;
|
||||
Oid saved_uid;
|
||||
Oid owner;
|
||||
|
||||
Assert(ht != NULL);
|
||||
#if !PG96
|
||||
if (stmt->transitionRels != NIL)
|
||||
@ -451,6 +455,13 @@ ts_hypertable_create_trigger(Hypertable *ht, CreateTrigStmt *stmt, const char *q
|
||||
if (!stmt->row)
|
||||
return root_trigger_addr;
|
||||
|
||||
/* switch to the hypertable owner's role -- note that this logic must be the same as
|
||||
* `ts_trigger_create_all_on_chunk` */
|
||||
owner = ts_rel_get_owner(ht->main_table_relid);
|
||||
GetUserIdAndSecContext(&saved_uid, &sec_ctx);
|
||||
if (saved_uid != owner)
|
||||
SetUserIdAndSecContext(owner, sec_ctx | SECURITY_LOCAL_USERID_CHANGE);
|
||||
|
||||
chunks = find_inheritance_children(ht->main_table_relid, NoLock);
|
||||
foreach (lc, chunks)
|
||||
{
|
||||
@ -461,6 +472,9 @@ ts_hypertable_create_trigger(Hypertable *ht, CreateTrigStmt *stmt, const char *q
|
||||
ts_trigger_create_on_chunk(root_trigger_addr.objectId, relschema, relname);
|
||||
}
|
||||
|
||||
if (saved_uid != owner)
|
||||
SetUserIdAndSecContext(saved_uid, sec_ctx);
|
||||
|
||||
return root_trigger_addr;
|
||||
}
|
||||
|
||||
|
@ -2251,12 +2251,23 @@ process_altertable_start_table(ProcessUtilityArgs *args)
|
||||
}
|
||||
|
||||
static void
|
||||
process_altercontinuousagg_set_with(ContinuousAgg *cagg, const List *defelems)
|
||||
continuous_agg_with_clause_perm_check(ContinuousAgg *cagg, Oid view_relid)
|
||||
{
|
||||
Oid ownerid = ts_rel_get_owner(view_relid);
|
||||
|
||||
if (!has_privs_of_role(GetUserId(), ownerid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be owner of continuous aggregate \"%s\"", get_rel_name(view_relid))));
|
||||
}
|
||||
|
||||
static void
|
||||
process_altercontinuousagg_set_with(ContinuousAgg *cagg, Oid view_relid, const List *defelems)
|
||||
{
|
||||
WithClauseResult *parse_results;
|
||||
List *pg_options = NIL, *cagg_options = NIL;
|
||||
|
||||
ts_hypertable_permissions_check_by_id(cagg->data.raw_hypertable_id);
|
||||
continuous_agg_with_clause_perm_check(cagg, view_relid);
|
||||
|
||||
ts_with_clause_filter(defelems, &cagg_options, &pg_options);
|
||||
if (list_length(pg_options) > 0)
|
||||
@ -2293,7 +2304,7 @@ process_altertable_start_view(ProcessUtilityArgs *args)
|
||||
if (cagg == NULL)
|
||||
return false;
|
||||
|
||||
ts_hypertable_permissions_check_by_id(cagg->data.raw_hypertable_id);
|
||||
continuous_agg_with_clause_perm_check(cagg, view_relid);
|
||||
|
||||
vtyp = ts_continuous_agg_view_type(&cagg->data, NameStr(view_schema), NameStr(view_name));
|
||||
if (vtyp == ContinuousAggPartialView || vtyp == ContinuousAggDirectView)
|
||||
@ -2312,7 +2323,7 @@ process_altertable_start_view(ProcessUtilityArgs *args)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("expected set options to contain a list")));
|
||||
process_altercontinuousagg_set_with(cagg, (List *) cmd->def);
|
||||
process_altercontinuousagg_set_with(cagg, view_relid, (List *) cmd->def);
|
||||
break;
|
||||
default:
|
||||
ereport(ERROR,
|
||||
@ -2329,7 +2340,6 @@ static bool
|
||||
process_altertable_start(ProcessUtilityArgs *args)
|
||||
{
|
||||
AlterTableStmt *stmt = (AlterTableStmt *) args->parsetree;
|
||||
|
||||
switch (stmt->relkind)
|
||||
{
|
||||
case OBJECT_TABLE:
|
||||
|
@ -133,27 +133,17 @@ ts_trigger_create_all_on_chunk(Hypertable *ht, Chunk *chunk)
|
||||
{
|
||||
int sec_ctx;
|
||||
Oid saved_uid;
|
||||
HeapTuple tuple;
|
||||
Form_pg_class form;
|
||||
|
||||
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(ht->main_table_relid));
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "cache lookup failed for relation ID %u", ht->main_table_relid);
|
||||
|
||||
form = (Form_pg_class) GETSTRUCT(tuple);
|
||||
Oid owner = ts_rel_get_owner(ht->main_table_relid);
|
||||
|
||||
GetUserIdAndSecContext(&saved_uid, &sec_ctx);
|
||||
|
||||
if (saved_uid != form->relowner)
|
||||
SetUserIdAndSecContext(form->relowner, sec_ctx | SECURITY_LOCAL_USERID_CHANGE);
|
||||
if (saved_uid != owner)
|
||||
SetUserIdAndSecContext(owner, sec_ctx | SECURITY_LOCAL_USERID_CHANGE);
|
||||
|
||||
for_each_trigger(ht->main_table_relid, create_trigger_handler, chunk);
|
||||
|
||||
if (saved_uid != form->relowner)
|
||||
if (saved_uid != owner)
|
||||
SetUserIdAndSecContext(saved_uid, sec_ctx);
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
}
|
||||
|
||||
#if !PG96
|
||||
|
@ -794,8 +794,6 @@ cagg_validate_query(Query *query)
|
||||
errmsg("can create continuous aggregate only on hypertables")));
|
||||
}
|
||||
|
||||
ts_hypertable_permissions_check_by_id(ht->fd.id);
|
||||
|
||||
/*check row security settings for the table */
|
||||
if (has_row_security(rte->relid))
|
||||
{
|
||||
|
@ -1185,37 +1185,3 @@ SELECT * FROM mat_refresh_test order by 1,2 ;
|
||||
POR | 75
|
||||
(4 rows)
|
||||
|
||||
SELECT id as cagg_job_id FROM _timescaledb_config.bgw_job \gset
|
||||
CREATE TABLE conditions_for_perm_check (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable('conditions_for_perm_check', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
---------------------------
|
||||
conditions_for_perm_check
|
||||
(1 row)
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
\set ON_ERROR_STOP 0
|
||||
select from alter_job_schedule(:cagg_job_id, max_runtime => NULL);
|
||||
WARNING: Timescale License expired
|
||||
ERROR: permission denied for hypertable "conditions"
|
||||
ALTER VIEW mat_refresh_test SET(timescaledb.refresh_lag = '6 h', timescaledb.refresh_interval = '2h');
|
||||
ERROR: must be owner of view mat_refresh_test
|
||||
DROP VIEW mat_refresh_test CASCADE;
|
||||
ERROR: must be owner of view mat_refresh_test
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
ERROR: permission denied for table conditions
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check
|
||||
group by time_bucket(100, timec), location;
|
||||
ERROR: permission denied for hypertable "conditions_for_perm_check"
|
||||
|
@ -320,3 +320,77 @@ invalidation_threshold | 6
|
||||
job_status | scheduled
|
||||
last_run_duration |
|
||||
|
||||
\x
|
||||
--
|
||||
-- Test creating continuous aggregate with a user that is the non-owner of the raw table
|
||||
--
|
||||
CREATE TABLE test_continuous_agg_table_w_grant(time int, data int);
|
||||
SELECT create_hypertable('test_continuous_agg_table_w_grant', 'time', chunk_time_interval => 10);
|
||||
NOTICE: adding not-null constraint to column "time"
|
||||
create_hypertable
|
||||
------------------------------------------------
|
||||
(4,public,test_continuous_agg_table_w_grant,t)
|
||||
(1 row)
|
||||
|
||||
GRANT SELECT, TRIGGER ON test_continuous_agg_table_w_grant TO public;
|
||||
INSERT INTO test_continuous_agg_table_w_grant
|
||||
SELECT i, i FROM
|
||||
(SELECT generate_series(0, 10) as i) AS j;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
-- make sure view can be created
|
||||
CREATE VIEW test_continuous_agg_view_user_2
|
||||
WITH ( timescaledb.continuous,
|
||||
timescaledb.max_interval_per_job='2',
|
||||
timescaledb.refresh_lag='-2')
|
||||
AS SELECT time_bucket('2', time), SUM(data) as value
|
||||
FROM test_continuous_agg_table_w_grant
|
||||
GROUP BY 1;
|
||||
SELECT job_id FROM _timescaledb_catalog.continuous_agg ORDER BY job_id desc limit 1 \gset
|
||||
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25);
|
||||
ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish
|
||||
------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
|
||||
FROM _timescaledb_internal.bgw_job_stat
|
||||
where job_id=:job_id;
|
||||
job_id | next_start | until_next | last_run_success | total_runs | total_successes | total_failures | total_crashes
|
||||
--------+----------------------------------+----------------------------------+------------------+------------+-----------------+----------------+---------------
|
||||
1002 | Fri Dec 31 16:00:00.075 1999 PST | Fri Dec 31 16:00:00.075 1999 PST | t | 1 | 1 | 0 | 0
|
||||
(1 row)
|
||||
|
||||
--view is populated
|
||||
SELECT * FROM test_continuous_agg_view_user_2;
|
||||
time_bucket | value
|
||||
-------------+-------
|
||||
0 | 1
|
||||
(1 row)
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
--revoke permissions from the continuous agg view owner to select from raw table
|
||||
--no further updates to cont agg should happen
|
||||
REVOKE SELECT ON test_continuous_agg_table_w_grant FROM public;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25, 25);
|
||||
ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish
|
||||
------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
--should show a failing execution because no longer has permissions (due to lack of permission on partial view owner's part)
|
||||
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
|
||||
FROM _timescaledb_internal.bgw_job_stat
|
||||
where job_id=:job_id;
|
||||
job_id | next_start | until_next | last_run_success | total_runs | total_successes | total_failures | total_crashes
|
||||
--------+--------------------------------+--------------------------------+------------------+------------+-----------------+----------------+---------------
|
||||
1002 | Sat Jan 01 04:00:00.1 2000 PST | Fri Dec 31 16:00:00.1 1999 PST | f | 2 | 1 | 1 | 0
|
||||
(1 row)
|
||||
|
||||
--view was NOT updated; but the old stuff is still there
|
||||
SELECT * FROM test_continuous_agg_view_user_2;
|
||||
time_bucket | value
|
||||
-------------+-------
|
||||
0 | 1
|
||||
(1 row)
|
||||
|
||||
|
150
tsl/test/expected/continuous_aggs_permissions-10.out
Normal file
150
tsl/test/expected/continuous_aggs_permissions-10.out
Normal file
@ -0,0 +1,150 @@
|
||||
-- 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.
|
||||
-- initialize the bgw mock state to prevent the materialization workers from running
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_bgw_params_create() RETURNS VOID
|
||||
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set WAIT_ON_JOB 0
|
||||
\set IMMEDIATELY_SET_UNTIL 1
|
||||
\set WAIT_FOR_OTHER_TO_ADVANCE 2
|
||||
-- stop the background workers from locking up the tables,
|
||||
-- and remove any default jobs, e.g., telemetry so bgw_job isn't polluted
|
||||
SELECT _timescaledb_internal.stop_background_workers();
|
||||
stop_background_workers
|
||||
-------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
DELETE FROM _timescaledb_config.bgw_job WHERE TRUE;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
CREATE TABLE conditions (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable( 'conditions', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
------------
|
||||
conditions
|
||||
(1 row)
|
||||
|
||||
create or replace view mat_refresh_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_2_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_2 USING BTREE(location, time_partition_col)
|
||||
insert into conditions
|
||||
select generate_series(0, 50, 10), 'NYC', 55, 75, 40, 70, NULL;
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
INFO: new materialization range for public.conditions (time column timec) (200)
|
||||
INFO: materializing continuous aggregate public.mat_refresh_test: new range up to 200
|
||||
SELECT id as cagg_job_id FROM _timescaledb_config.bgw_job order by id desc limit 1 \gset
|
||||
SELECT materialization_hypertable FROM timescaledb_information.continuous_aggregates WHERE view_name = 'mat_refresh_test'::regclass \gset
|
||||
SELECT mat_hypertable_id FROM _timescaledb_catalog.continuous_agg WHERE user_view_name = 'mat_refresh_test' \gset
|
||||
SELECT schema_name as mat_chunk_schema, table_name as mat_chunk_table
|
||||
FROM _timescaledb_catalog.chunk
|
||||
WHERE hypertable_id = :mat_hypertable_id
|
||||
ORDER BY id desc
|
||||
LIMIT 1 \gset
|
||||
CREATE TABLE conditions_for_perm_check (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable('conditions_for_perm_check', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
---------------------------
|
||||
conditions_for_perm_check
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE conditions_for_perm_check_w_grant (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable('conditions_for_perm_check_w_grant', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
-----------------------------------
|
||||
conditions_for_perm_check_w_grant
|
||||
(1 row)
|
||||
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(0, 30, 10), 'POR', 55, 75, 40, 70, NULL;
|
||||
--need both select and trigger permissions to create a materialized view on top of it.
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
\set ON_ERROR_STOP 0
|
||||
select from alter_job_schedule(:cagg_job_id, max_runtime => NULL);
|
||||
WARNING: Timescale License expired
|
||||
ERROR: permission denied for hypertable "conditions"
|
||||
--make sure that commands fail
|
||||
ALTER VIEW mat_refresh_test SET(timescaledb.refresh_lag = '6 h', timescaledb.refresh_interval = '2h');
|
||||
ERROR: must be owner of relation mat_refresh_test
|
||||
DROP VIEW mat_refresh_test CASCADE;
|
||||
ERROR: must be owner of relation mat_refresh_test
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
ERROR: permission denied for relation conditions
|
||||
SELECT * FROM mat_refresh_test;
|
||||
ERROR: permission denied for relation mat_refresh_test
|
||||
SELECT * FROM :materialization_hypertable;
|
||||
ERROR: permission denied for relation _materialized_hypertable_2
|
||||
SELECT * FROM :"mat_chunk_schema".:"mat_chunk_table";
|
||||
ERROR: permission denied for relation _hyper_2_2_chunk
|
||||
--cannot create a mat view without select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_5_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_5 USING BTREE(location, time_partition_col)
|
||||
ERROR: permission denied for relation conditions_for_perm_check
|
||||
--can create a mat view on something with select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check_w_grant
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_6_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_6 USING BTREE(location, time_partition_col)
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
INFO: new materialization range for public.conditions_for_perm_check_w_grant (time column timec) (200)
|
||||
INFO: materializing continuous aggregate public.mat_perm_view_test: new range up to 200
|
||||
SELECT * FROM mat_perm_view_test;
|
||||
location | max
|
||||
----------+-----
|
||||
POR | 75
|
||||
(1 row)
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
--revoke select permissions from role with mat view
|
||||
REVOKE SELECT ON conditions_for_perm_check_w_grant FROM public;
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(100, 130, 10), 'POR', 65, 85, 30, 90, NULL;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
--refresh mat view should now fail due to lack of permissions
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
ERROR: permission denied for relation conditions_for_perm_check_w_grant
|
||||
--but the old data will still be there
|
||||
SELECT * FROM mat_perm_view_test;
|
||||
location | max
|
||||
----------+-----
|
||||
POR | 75
|
||||
(1 row)
|
||||
|
150
tsl/test/expected/continuous_aggs_permissions-11.out
Normal file
150
tsl/test/expected/continuous_aggs_permissions-11.out
Normal file
@ -0,0 +1,150 @@
|
||||
-- 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.
|
||||
-- initialize the bgw mock state to prevent the materialization workers from running
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_bgw_params_create() RETURNS VOID
|
||||
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set WAIT_ON_JOB 0
|
||||
\set IMMEDIATELY_SET_UNTIL 1
|
||||
\set WAIT_FOR_OTHER_TO_ADVANCE 2
|
||||
-- stop the background workers from locking up the tables,
|
||||
-- and remove any default jobs, e.g., telemetry so bgw_job isn't polluted
|
||||
SELECT _timescaledb_internal.stop_background_workers();
|
||||
stop_background_workers
|
||||
-------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
DELETE FROM _timescaledb_config.bgw_job WHERE TRUE;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
CREATE TABLE conditions (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable( 'conditions', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
------------
|
||||
conditions
|
||||
(1 row)
|
||||
|
||||
create or replace view mat_refresh_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_2_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_2 USING BTREE(location, time_partition_col)
|
||||
insert into conditions
|
||||
select generate_series(0, 50, 10), 'NYC', 55, 75, 40, 70, NULL;
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
INFO: new materialization range for public.conditions (time column timec) (200)
|
||||
INFO: materializing continuous aggregate public.mat_refresh_test: new range up to 200
|
||||
SELECT id as cagg_job_id FROM _timescaledb_config.bgw_job order by id desc limit 1 \gset
|
||||
SELECT materialization_hypertable FROM timescaledb_information.continuous_aggregates WHERE view_name = 'mat_refresh_test'::regclass \gset
|
||||
SELECT mat_hypertable_id FROM _timescaledb_catalog.continuous_agg WHERE user_view_name = 'mat_refresh_test' \gset
|
||||
SELECT schema_name as mat_chunk_schema, table_name as mat_chunk_table
|
||||
FROM _timescaledb_catalog.chunk
|
||||
WHERE hypertable_id = :mat_hypertable_id
|
||||
ORDER BY id desc
|
||||
LIMIT 1 \gset
|
||||
CREATE TABLE conditions_for_perm_check (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable('conditions_for_perm_check', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
---------------------------
|
||||
conditions_for_perm_check
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE conditions_for_perm_check_w_grant (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable('conditions_for_perm_check_w_grant', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
-----------------------------------
|
||||
conditions_for_perm_check_w_grant
|
||||
(1 row)
|
||||
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(0, 30, 10), 'POR', 55, 75, 40, 70, NULL;
|
||||
--need both select and trigger permissions to create a materialized view on top of it.
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
\set ON_ERROR_STOP 0
|
||||
select from alter_job_schedule(:cagg_job_id, max_runtime => NULL);
|
||||
WARNING: Timescale License expired
|
||||
ERROR: permission denied for hypertable "conditions"
|
||||
--make sure that commands fail
|
||||
ALTER VIEW mat_refresh_test SET(timescaledb.refresh_lag = '6 h', timescaledb.refresh_interval = '2h');
|
||||
ERROR: must be owner of view mat_refresh_test
|
||||
DROP VIEW mat_refresh_test CASCADE;
|
||||
ERROR: must be owner of view mat_refresh_test
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
ERROR: permission denied for table conditions
|
||||
SELECT * FROM mat_refresh_test;
|
||||
ERROR: permission denied for view mat_refresh_test
|
||||
SELECT * FROM :materialization_hypertable;
|
||||
ERROR: permission denied for table _materialized_hypertable_2
|
||||
SELECT * FROM :"mat_chunk_schema".:"mat_chunk_table";
|
||||
ERROR: permission denied for table _hyper_2_2_chunk
|
||||
--cannot create a mat view without select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_5_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_5 USING BTREE(location, time_partition_col)
|
||||
ERROR: permission denied for table conditions_for_perm_check
|
||||
--can create a mat view on something with select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check_w_grant
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_6_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_6 USING BTREE(location, time_partition_col)
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
INFO: new materialization range for public.conditions_for_perm_check_w_grant (time column timec) (200)
|
||||
INFO: materializing continuous aggregate public.mat_perm_view_test: new range up to 200
|
||||
SELECT * FROM mat_perm_view_test;
|
||||
location | max
|
||||
----------+-----
|
||||
POR | 75
|
||||
(1 row)
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
--revoke select permissions from role with mat view
|
||||
REVOKE SELECT ON conditions_for_perm_check_w_grant FROM public;
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(100, 130, 10), 'POR', 65, 85, 30, 90, NULL;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
--refresh mat view should now fail due to lack of permissions
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
ERROR: permission denied for table conditions_for_perm_check_w_grant
|
||||
--but the old data will still be there
|
||||
SELECT * FROM mat_perm_view_test;
|
||||
location | max
|
||||
----------+-----
|
||||
POR | 75
|
||||
(1 row)
|
||||
|
150
tsl/test/expected/continuous_aggs_permissions-9.6.out
Normal file
150
tsl/test/expected/continuous_aggs_permissions-9.6.out
Normal file
@ -0,0 +1,150 @@
|
||||
-- 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.
|
||||
-- initialize the bgw mock state to prevent the materialization workers from running
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_bgw_params_create() RETURNS VOID
|
||||
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set WAIT_ON_JOB 0
|
||||
\set IMMEDIATELY_SET_UNTIL 1
|
||||
\set WAIT_FOR_OTHER_TO_ADVANCE 2
|
||||
-- stop the background workers from locking up the tables,
|
||||
-- and remove any default jobs, e.g., telemetry so bgw_job isn't polluted
|
||||
SELECT _timescaledb_internal.stop_background_workers();
|
||||
stop_background_workers
|
||||
-------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
DELETE FROM _timescaledb_config.bgw_job WHERE TRUE;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
CREATE TABLE conditions (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable( 'conditions', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
------------
|
||||
conditions
|
||||
(1 row)
|
||||
|
||||
create or replace view mat_refresh_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_2_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_2 USING BTREE(location, time_partition_col)
|
||||
insert into conditions
|
||||
select generate_series(0, 50, 10), 'NYC', 55, 75, 40, 70, NULL;
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
INFO: new materialization range for public.conditions (time column timec) (200)
|
||||
INFO: materializing continuous aggregate public.mat_refresh_test: new range up to 200
|
||||
SELECT id as cagg_job_id FROM _timescaledb_config.bgw_job order by id desc limit 1 \gset
|
||||
SELECT materialization_hypertable FROM timescaledb_information.continuous_aggregates WHERE view_name = 'mat_refresh_test'::regclass \gset
|
||||
SELECT mat_hypertable_id FROM _timescaledb_catalog.continuous_agg WHERE user_view_name = 'mat_refresh_test' \gset
|
||||
SELECT schema_name as mat_chunk_schema, table_name as mat_chunk_table
|
||||
FROM _timescaledb_catalog.chunk
|
||||
WHERE hypertable_id = :mat_hypertable_id
|
||||
ORDER BY id desc
|
||||
LIMIT 1 \gset
|
||||
CREATE TABLE conditions_for_perm_check (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable('conditions_for_perm_check', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
---------------------------
|
||||
conditions_for_perm_check
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE conditions_for_perm_check_w_grant (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
select table_name from create_hypertable('conditions_for_perm_check_w_grant', 'timec', chunk_time_interval=> 100);
|
||||
table_name
|
||||
-----------------------------------
|
||||
conditions_for_perm_check_w_grant
|
||||
(1 row)
|
||||
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(0, 30, 10), 'POR', 55, 75, 40, 70, NULL;
|
||||
--need both select and trigger permissions to create a materialized view on top of it.
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
\set ON_ERROR_STOP 0
|
||||
select from alter_job_schedule(:cagg_job_id, max_runtime => NULL);
|
||||
WARNING: Timescale License expired
|
||||
ERROR: permission denied for hypertable "conditions"
|
||||
--make sure that commands fail
|
||||
ALTER VIEW mat_refresh_test SET(timescaledb.refresh_lag = '6 h', timescaledb.refresh_interval = '2h');
|
||||
ERROR: must be owner of relation mat_refresh_test
|
||||
DROP VIEW mat_refresh_test CASCADE;
|
||||
ERROR: must be owner of relation mat_refresh_test
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
ERROR: permission denied for relation conditions
|
||||
SELECT * FROM mat_refresh_test;
|
||||
ERROR: permission denied for relation mat_refresh_test
|
||||
SELECT * FROM :materialization_hypertable;
|
||||
ERROR: permission denied for relation _materialized_hypertable_2
|
||||
SELECT * FROM :"mat_chunk_schema".:"mat_chunk_table";
|
||||
ERROR: permission denied for relation _hyper_2_2_chunk
|
||||
--cannot create a mat view without select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_5_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_5 USING BTREE(location, time_partition_col)
|
||||
ERROR: permission denied for relation conditions_for_perm_check
|
||||
--can create a mat view on something with select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check_w_grant
|
||||
group by time_bucket(100, timec), location;
|
||||
NOTICE: adding index _materialized_hypertable_6_location_time_partition_col_idx ON _timescaledb_internal._materialized_hypertable_6 USING BTREE(location, time_partition_col)
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
INFO: new materialization range for public.conditions_for_perm_check_w_grant (time column timec) (200)
|
||||
INFO: materializing continuous aggregate public.mat_perm_view_test: new range up to 200
|
||||
SELECT * FROM mat_perm_view_test;
|
||||
location | max
|
||||
----------+-----
|
||||
POR | 75
|
||||
(1 row)
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
--revoke select permissions from role with mat view
|
||||
REVOKE SELECT ON conditions_for_perm_check_w_grant FROM public;
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(100, 130, 10), 'POR', 65, 85, 30, 90, NULL;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
--refresh mat view should now fail due to lack of permissions
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
ERROR: permission denied for relation conditions_for_perm_check_w_grant
|
||||
--but the old data will still be there
|
||||
SELECT * FROM mat_perm_view_test;
|
||||
location | max
|
||||
----------+-----
|
||||
POR | 75
|
||||
(1 row)
|
||||
|
1
tsl/test/sql/.gitignore
vendored
1
tsl/test/sql/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/plan_gapfill-*.sql
|
||||
/continuous_aggs_ddl-*.sql
|
||||
/continuous_aggs_permissions-*.sql
|
||||
|
@ -23,6 +23,7 @@ set(TEST_TEMPLATES
|
||||
# parallel plans are different between postgres versions
|
||||
plan_gapfill.sql.in
|
||||
continuous_aggs_ddl.sql.in
|
||||
continuous_aggs_permissions.sql.in
|
||||
)
|
||||
|
||||
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
@ -857,32 +857,3 @@ select generate_series(0, 50, 10), 'NYC', 55, 75, 40, 70, NULL;
|
||||
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
SELECT * FROM mat_refresh_test order by 1,2 ;
|
||||
|
||||
|
||||
SELECT id as cagg_job_id FROM _timescaledb_config.bgw_job \gset
|
||||
|
||||
CREATE TABLE conditions_for_perm_check (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
|
||||
select table_name from create_hypertable('conditions_for_perm_check', 'timec', chunk_time_interval=> 100);
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
\set ON_ERROR_STOP 0
|
||||
select from alter_job_schedule(:cagg_job_id, max_runtime => NULL);
|
||||
ALTER VIEW mat_refresh_test SET(timescaledb.refresh_lag = '6 h', timescaledb.refresh_interval = '2h');
|
||||
DROP VIEW mat_refresh_test CASCADE;
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check
|
||||
group by time_bucket(100, timec), location;
|
||||
|
@ -174,3 +174,54 @@ select view_name, view_definition from timescaledb_information.continuous_aggreg
|
||||
where view_name::text like '%test_continuous_agg_view';
|
||||
|
||||
select view_name, completed_threshold, invalidation_threshold, job_status, last_run_duration from timescaledb_information.continuous_aggregate_stats where view_name::text like '%test_continuous_agg_view';
|
||||
|
||||
\x
|
||||
|
||||
--
|
||||
-- Test creating continuous aggregate with a user that is the non-owner of the raw table
|
||||
--
|
||||
CREATE TABLE test_continuous_agg_table_w_grant(time int, data int);
|
||||
SELECT create_hypertable('test_continuous_agg_table_w_grant', 'time', chunk_time_interval => 10);
|
||||
GRANT SELECT, TRIGGER ON test_continuous_agg_table_w_grant TO public;
|
||||
INSERT INTO test_continuous_agg_table_w_grant
|
||||
SELECT i, i FROM
|
||||
(SELECT generate_series(0, 10) as i) AS j;
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
|
||||
-- make sure view can be created
|
||||
CREATE VIEW test_continuous_agg_view_user_2
|
||||
WITH ( timescaledb.continuous,
|
||||
timescaledb.max_interval_per_job='2',
|
||||
timescaledb.refresh_lag='-2')
|
||||
AS SELECT time_bucket('2', time), SUM(data) as value
|
||||
FROM test_continuous_agg_table_w_grant
|
||||
GROUP BY 1;
|
||||
|
||||
SELECT job_id FROM _timescaledb_catalog.continuous_agg ORDER BY job_id desc limit 1 \gset
|
||||
|
||||
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25);
|
||||
|
||||
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
|
||||
FROM _timescaledb_internal.bgw_job_stat
|
||||
where job_id=:job_id;
|
||||
|
||||
--view is populated
|
||||
SELECT * FROM test_continuous_agg_view_user_2;
|
||||
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
--revoke permissions from the continuous agg view owner to select from raw table
|
||||
--no further updates to cont agg should happen
|
||||
REVOKE SELECT ON test_continuous_agg_table_w_grant FROM public;
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25, 25);
|
||||
|
||||
--should show a failing execution because no longer has permissions (due to lack of permission on partial view owner's part)
|
||||
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
|
||||
FROM _timescaledb_internal.bgw_job_stat
|
||||
where job_id=:job_id;
|
||||
|
||||
--view was NOT updated; but the old stuff is still there
|
||||
SELECT * FROM test_continuous_agg_view_user_2;
|
||||
|
134
tsl/test/sql/continuous_aggs_permissions.sql.in
Normal file
134
tsl/test/sql/continuous_aggs_permissions.sql.in
Normal file
@ -0,0 +1,134 @@
|
||||
-- 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.
|
||||
|
||||
-- initialize the bgw mock state to prevent the materialization workers from running
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
|
||||
CREATE OR REPLACE FUNCTION ts_bgw_params_create() RETURNS VOID
|
||||
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
|
||||
\set WAIT_ON_JOB 0
|
||||
\set IMMEDIATELY_SET_UNTIL 1
|
||||
\set WAIT_FOR_OTHER_TO_ADVANCE 2
|
||||
|
||||
-- stop the background workers from locking up the tables,
|
||||
-- and remove any default jobs, e.g., telemetry so bgw_job isn't polluted
|
||||
SELECT _timescaledb_internal.stop_background_workers();
|
||||
DELETE FROM _timescaledb_config.bgw_job WHERE TRUE;
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
|
||||
CREATE TABLE conditions (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
|
||||
select table_name from create_hypertable( 'conditions', 'timec', chunk_time_interval=> 100);
|
||||
|
||||
create or replace view mat_refresh_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions
|
||||
group by time_bucket(100, timec), location;
|
||||
|
||||
insert into conditions
|
||||
select generate_series(0, 50, 10), 'NYC', 55, 75, 40, 70, NULL;
|
||||
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
|
||||
SELECT id as cagg_job_id FROM _timescaledb_config.bgw_job order by id desc limit 1 \gset
|
||||
SELECT materialization_hypertable FROM timescaledb_information.continuous_aggregates WHERE view_name = 'mat_refresh_test'::regclass \gset
|
||||
|
||||
SELECT mat_hypertable_id FROM _timescaledb_catalog.continuous_agg WHERE user_view_name = 'mat_refresh_test' \gset
|
||||
|
||||
SELECT schema_name as mat_chunk_schema, table_name as mat_chunk_table
|
||||
FROM _timescaledb_catalog.chunk
|
||||
WHERE hypertable_id = :mat_hypertable_id
|
||||
ORDER BY id desc
|
||||
LIMIT 1 \gset
|
||||
|
||||
CREATE TABLE conditions_for_perm_check (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
|
||||
select table_name from create_hypertable('conditions_for_perm_check', 'timec', chunk_time_interval=> 100);
|
||||
|
||||
CREATE TABLE conditions_for_perm_check_w_grant (
|
||||
timec INT NOT NULL,
|
||||
location TEXT NOT NULL,
|
||||
temperature DOUBLE PRECISION NULL,
|
||||
humidity DOUBLE PRECISION NULL,
|
||||
lowp double precision NULL,
|
||||
highp double precision null,
|
||||
allnull double precision null
|
||||
);
|
||||
|
||||
select table_name from create_hypertable('conditions_for_perm_check_w_grant', 'timec', chunk_time_interval=> 100);
|
||||
|
||||
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(0, 30, 10), 'POR', 55, 75, 40, 70, NULL;
|
||||
|
||||
--need both select and trigger permissions to create a materialized view on top of it.
|
||||
GRANT SELECT, TRIGGER ON conditions_for_perm_check_w_grant TO public;
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
\set ON_ERROR_STOP 0
|
||||
select from alter_job_schedule(:cagg_job_id, max_runtime => NULL);
|
||||
|
||||
--make sure that commands fail
|
||||
|
||||
ALTER VIEW mat_refresh_test SET(timescaledb.refresh_lag = '6 h', timescaledb.refresh_interval = '2h');
|
||||
DROP VIEW mat_refresh_test CASCADE;
|
||||
REFRESH MATERIALIZED VIEW mat_refresh_test;
|
||||
SELECT * FROM mat_refresh_test;
|
||||
SELECT * FROM :materialization_hypertable;
|
||||
SELECT * FROM :"mat_chunk_schema".:"mat_chunk_table";
|
||||
|
||||
--cannot create a mat view without select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check
|
||||
group by time_bucket(100, timec), location;
|
||||
|
||||
--can create a mat view on something with select and trigger grants
|
||||
create or replace view mat_perm_view_test
|
||||
WITH ( timescaledb.continuous, timescaledb.refresh_lag = '-200')
|
||||
as
|
||||
select location, max(humidity)
|
||||
from conditions_for_perm_check_w_grant
|
||||
group by time_bucket(100, timec), location;
|
||||
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
SELECT * FROM mat_perm_view_test;
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
--revoke select permissions from role with mat view
|
||||
REVOKE SELECT ON conditions_for_perm_check_w_grant FROM public;
|
||||
|
||||
insert into conditions_for_perm_check_w_grant
|
||||
select generate_series(100, 130, 10), 'POR', 65, 85, 30, 90, NULL;
|
||||
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
|
||||
--refresh mat view should now fail due to lack of permissions
|
||||
REFRESH MATERIALIZED VIEW mat_perm_view_test;
|
||||
|
||||
--but the old data will still be there
|
||||
SELECT * FROM mat_perm_view_test;
|
Loading…
x
Reference in New Issue
Block a user