mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-15 18:13:18 +08:00
When TidRangeScan is child of ChunkAppend or ConstraintAwareAppend node, an error is reported as "invalid child of chunk append: Node (26)". This patch fixes the issue by recognising TidRangeScan as a valid child. Fixes: #4872
1009 lines
55 KiB
Plaintext
1009 lines
55 KiB
Plaintext
-- This file and its contents are licensed under the Apache License 2.0.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-APACHE for a copy of the license.
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
create schema test_schema AUTHORIZATION :ROLE_DEFAULT_PERM_USER;
|
|
create schema chunk_schema AUTHORIZATION :ROLE_DEFAULT_PERM_USER_2;
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
create table test_schema.test_table(time BIGINT, temp float8, device_id text, device_type text, location text, id int, id2 int);
|
|
\set ON_ERROR_STOP 0
|
|
-- get_create_command should fail since hypertable isn't made yet
|
|
SELECT * FROM _timescaledb_internal.get_create_command('test_table');
|
|
ERROR: hypertable "test_table" not found
|
|
\set ON_ERROR_STOP 1
|
|
\dt "test_schema".*
|
|
List of relations
|
|
Schema | Name | Type | Owner
|
|
-------------+------------+-------+-------------------
|
|
test_schema | test_table | table | default_perm_user
|
|
(1 row)
|
|
|
|
create table test_schema.test_table_no_not_null(time BIGINT, device_id text);
|
|
\set ON_ERROR_STOP 0
|
|
-- Permission denied with unprivileged role
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
|
select * from create_hypertable('test_schema.test_table_no_not_null', 'time', 'device_id', 2, chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'));
|
|
ERROR: permission denied for schema test_schema at character 33
|
|
-- CREATE on schema is not enough
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
GRANT ALL ON SCHEMA test_schema TO :ROLE_DEFAULT_PERM_USER_2;
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
|
select * from create_hypertable('test_schema.test_table_no_not_null', 'time', 'device_id', 2, chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'));
|
|
ERROR: must be owner of hypertable "test_table_no_not_null"
|
|
\set ON_ERROR_STOP 1
|
|
-- Should work with when granted table owner role
|
|
RESET ROLE;
|
|
GRANT :ROLE_DEFAULT_PERM_USER TO :ROLE_DEFAULT_PERM_USER_2;
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
|
select * from create_hypertable('test_schema.test_table_no_not_null', 'time', 'device_id', 2, chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'));
|
|
NOTICE: adding not-null constraint to column "time"
|
|
hypertable_id | schema_name | table_name | created
|
|
---------------+-------------+------------------------+---------
|
|
1 | test_schema | test_table_no_not_null | t
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
insert into test_schema.test_table_no_not_null (device_id) VALUES('foo');
|
|
ERROR: NULL value in column "time" violates not-null constraint
|
|
\set ON_ERROR_STOP 1
|
|
insert into test_schema.test_table_no_not_null (time, device_id) VALUES(1, 'foo');
|
|
RESET ROLE;
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
\set ON_ERROR_STOP 0
|
|
-- No permissions on associated schema should fail
|
|
select * from create_hypertable('test_schema.test_table', 'time', 'device_id', 2, chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'), associated_schema_name => 'chunk_schema');
|
|
ERROR: permissions denied: cannot create chunks in schema "chunk_schema"
|
|
\set ON_ERROR_STOP 1
|
|
-- Granting permissions on chunk_schema should make things work
|
|
RESET ROLE;
|
|
GRANT CREATE ON SCHEMA chunk_schema TO :ROLE_DEFAULT_PERM_USER;
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
select * from create_hypertable('test_schema.test_table', 'time', 'device_id', 2, chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'), associated_schema_name => 'chunk_schema');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
hypertable_id | schema_name | table_name | created
|
|
---------------+-------------+------------+---------
|
|
2 | test_schema | test_table | t
|
|
(1 row)
|
|
|
|
-- Check that the insert block trigger exists
|
|
SELECT * FROM test.show_triggers('test_schema.test_table');
|
|
Trigger | Type | Function
|
|
-------------------+------+--------------------------------------
|
|
ts_insert_blocker | 7 | _timescaledb_internal.insert_blocker
|
|
(1 row)
|
|
|
|
SELECT * FROM _timescaledb_internal.get_create_command('test_table');
|
|
get_create_command
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------
|
|
SELECT create_hypertable('test_schema.test_table', 'time', 'device_id', 2, chunk_time_interval => 2592000000000, create_default_indexes=>FALSE);
|
|
(1 row)
|
|
|
|
--test adding one more closed dimension
|
|
select add_dimension('test_schema.test_table', 'location', 4);
|
|
add_dimension
|
|
---------------------------------------
|
|
(5,test_schema,test_table,location,t)
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.hypertable where table_name = 'test_table';
|
|
id | schema_name | table_name | associated_schema_name | associated_table_prefix | num_dimensions | chunk_sizing_func_schema | chunk_sizing_func_name | chunk_target_size | compression_state | compressed_hypertable_id | replication_factor
|
|
----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------
|
|
2 | test_schema | test_table | chunk_schema | _hyper_2 | 3 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.dimension;
|
|
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func
|
|
----+---------------+-------------+-------------+---------+------------+--------------------------+--------------------+-----------------+--------------------------+-------------------------+------------------
|
|
1 | 1 | time | bigint | t | | | | 2592000000000 | | |
|
|
2 | 1 | device_id | text | f | 2 | _timescaledb_internal | get_partition_hash | | | |
|
|
3 | 2 | time | bigint | t | | | | 2592000000000 | | |
|
|
4 | 2 | device_id | text | f | 2 | _timescaledb_internal | get_partition_hash | | | |
|
|
5 | 2 | location | text | f | 4 | _timescaledb_internal | get_partition_hash | | | |
|
|
(5 rows)
|
|
|
|
--test that we can change the number of partitions and that 1 is allowed
|
|
SELECT set_number_partitions('test_schema.test_table', 1, 'location');
|
|
set_number_partitions
|
|
-----------------------
|
|
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.dimension WHERE column_name = 'location';
|
|
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func
|
|
----+---------------+-------------+-------------+---------+------------+--------------------------+--------------------+-----------------+--------------------------+-------------------------+------------------
|
|
5 | 2 | location | text | f | 1 | _timescaledb_internal | get_partition_hash | | | |
|
|
(1 row)
|
|
|
|
SELECT set_number_partitions('test_schema.test_table', 2, 'location');
|
|
set_number_partitions
|
|
-----------------------
|
|
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.dimension WHERE column_name = 'location';
|
|
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func
|
|
----+---------------+-------------+-------------+---------+------------+--------------------------+--------------------+-----------------+--------------------------+-------------------------+------------------
|
|
5 | 2 | location | text | f | 2 | _timescaledb_internal | get_partition_hash | | | |
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
--must give an explicit dimension when there are multiple space dimensions
|
|
SELECT set_number_partitions('test_schema.test_table', 3);
|
|
ERROR: hypertable "test_table" has multiple space dimensions
|
|
--too few
|
|
SELECT set_number_partitions('test_schema.test_table', 0, 'location');
|
|
ERROR: invalid number of partitions: must be between 1 and 32767
|
|
-- Too many
|
|
SELECT set_number_partitions('test_schema.test_table', 32768, 'location');
|
|
ERROR: invalid number of partitions: must be between 1 and 32767
|
|
-- get_create_command only works on tables w/ 1 or 2 dimensions
|
|
SELECT * FROM _timescaledb_internal.get_create_command('test_table');
|
|
ERROR: get_create_command only supports hypertables with up to 2 dimensions
|
|
\set ON_ERROR_STOP 1
|
|
--test adding one more open dimension
|
|
select add_dimension('test_schema.test_table', 'id', chunk_time_interval => 1000);
|
|
NOTICE: adding not-null constraint to column "id"
|
|
add_dimension
|
|
---------------------------------
|
|
(6,test_schema,test_table,id,t)
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.hypertable where table_name = 'test_table';
|
|
id | schema_name | table_name | associated_schema_name | associated_table_prefix | num_dimensions | chunk_sizing_func_schema | chunk_sizing_func_name | chunk_target_size | compression_state | compressed_hypertable_id | replication_factor
|
|
----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------
|
|
2 | test_schema | test_table | chunk_schema | _hyper_2 | 4 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.dimension;
|
|
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func
|
|
----+---------------+-------------+-------------+---------+------------+--------------------------+--------------------+-----------------+--------------------------+-------------------------+------------------
|
|
1 | 1 | time | bigint | t | | | | 2592000000000 | | |
|
|
2 | 1 | device_id | text | f | 2 | _timescaledb_internal | get_partition_hash | | | |
|
|
3 | 2 | time | bigint | t | | | | 2592000000000 | | |
|
|
4 | 2 | device_id | text | f | 2 | _timescaledb_internal | get_partition_hash | | | |
|
|
5 | 2 | location | text | f | 2 | _timescaledb_internal | get_partition_hash | | | |
|
|
6 | 2 | id | integer | t | | | | 1000 | | |
|
|
(6 rows)
|
|
|
|
-- Test add_dimension: can use interval types for TIMESTAMPTZ columns
|
|
CREATE TABLE dim_test_time(time TIMESTAMPTZ, time2 TIMESTAMPTZ, time3 BIGINT, temp float8, device int, location int);
|
|
SELECT create_hypertable('dim_test_time', 'time');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
----------------------------
|
|
(3,public,dim_test_time,t)
|
|
(1 row)
|
|
|
|
SELECT add_dimension('dim_test_time', 'time2', chunk_time_interval => INTERVAL '1 day');
|
|
NOTICE: adding not-null constraint to column "time2"
|
|
add_dimension
|
|
----------------------------------
|
|
(8,public,dim_test_time,time2,t)
|
|
(1 row)
|
|
|
|
-- Test add_dimension: only integral should work on BIGINT columns
|
|
\set ON_ERROR_STOP 0
|
|
SELECT add_dimension('dim_test_time', 'time3', chunk_time_interval => INTERVAL '1 day');
|
|
ERROR: invalid interval type for bigint dimension
|
|
-- string is not a valid type
|
|
SELECT add_dimension('dim_test_time', 'time3', chunk_time_interval => 'foo'::TEXT);
|
|
ERROR: invalid interval type for bigint dimension
|
|
\set ON_ERROR_STOP 1
|
|
SELECT add_dimension('dim_test_time', 'time3', chunk_time_interval => 500);
|
|
NOTICE: adding not-null constraint to column "time3"
|
|
add_dimension
|
|
----------------------------------
|
|
(9,public,dim_test_time,time3,t)
|
|
(1 row)
|
|
|
|
-- Test add_dimension: integrals should work on TIMESTAMPTZ columns
|
|
CREATE TABLE dim_test_time2(time TIMESTAMPTZ, time2 TIMESTAMPTZ, temp float8, device int, location int);
|
|
SELECT create_hypertable('dim_test_time2', 'time');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
-----------------------------
|
|
(4,public,dim_test_time2,t)
|
|
(1 row)
|
|
|
|
SELECT add_dimension('dim_test_time2', 'time2', chunk_time_interval => 500);
|
|
WARNING: unexpected interval: smaller than one second
|
|
NOTICE: adding not-null constraint to column "time2"
|
|
add_dimension
|
|
------------------------------------
|
|
(11,public,dim_test_time2,time2,t)
|
|
(1 row)
|
|
|
|
--adding a dimension twice should not fail with 'if_not_exists'
|
|
SELECT add_dimension('dim_test_time2', 'time2', chunk_time_interval => 500, if_not_exists => true);
|
|
NOTICE: column "time2" is already a dimension, skipping
|
|
add_dimension
|
|
------------------------------------
|
|
(11,public,dim_test_time2,time2,f)
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
--adding on a non-hypertable
|
|
CREATE TABLE not_hypertable(time TIMESTAMPTZ, temp float8, device int, location int);
|
|
SELECT add_dimension('not_hypertable', 'time', chunk_time_interval => 500);
|
|
ERROR: table "not_hypertable" is not a hypertable
|
|
--adding a non-exist column
|
|
SELECT add_dimension('test_schema.test_table', 'nope', 2);
|
|
ERROR: column "nope" does not exist
|
|
--adding the same dimension twice should fail
|
|
select add_dimension('test_schema.test_table', 'location', 2);
|
|
ERROR: column "location" is already a dimension
|
|
--adding dimension with both number_partitions and chunk_time_interval should fail
|
|
select add_dimension('test_schema.test_table', 'id2', number_partitions => 2, chunk_time_interval => 1000);
|
|
ERROR: cannot specify both the number of partitions and an interval
|
|
\set ON_ERROR_STOP 1
|
|
-- test adding a new dimension on a non-empty table
|
|
CREATE TABLE dim_test(time TIMESTAMPTZ, device int);
|
|
SELECT create_hypertable('dim_test', 'time', chunk_time_interval => INTERVAL '1 day');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
-----------------------
|
|
(5,public,dim_test,t)
|
|
(1 row)
|
|
|
|
CREATE VIEW dim_test_slices AS
|
|
SELECT c.id AS chunk_id, c.hypertable_id, ds.dimension_id, cc.dimension_slice_id, c.schema_name AS chunk_schema, c.table_name AS chunk_table, ds.range_start, ds.range_end
|
|
FROM _timescaledb_catalog.chunk c
|
|
INNER JOIN _timescaledb_catalog.hypertable h ON (c.hypertable_id = h.id)
|
|
INNER JOIN _timescaledb_catalog.dimension td ON (h.id = td.hypertable_id)
|
|
INNER JOIN _timescaledb_catalog.dimension_slice ds ON (ds.dimension_id = td.id)
|
|
INNER JOIN _timescaledb_catalog.chunk_constraint cc ON (cc.dimension_slice_id = ds.id AND cc.chunk_id = c.id)
|
|
WHERE h.table_name = 'dim_test'
|
|
ORDER BY c.id, ds.dimension_id;
|
|
INSERT INTO dim_test VALUES ('2004-10-10 00:00:00+00', 1);
|
|
INSERT INTO dim_test VALUES ('2004-10-20 00:00:00+00', 2);
|
|
SELECT * FROM dim_test_slices;
|
|
chunk_id | hypertable_id | dimension_id | dimension_slice_id | chunk_schema | chunk_table | range_start | range_end
|
|
----------+---------------+--------------+--------------------+-----------------------+------------------+------------------+------------------
|
|
2 | 5 | 12 | 3 | _timescaledb_internal | _hyper_5_2_chunk | 1097366400000000 | 1097452800000000
|
|
3 | 5 | 12 | 4 | _timescaledb_internal | _hyper_5_3_chunk | 1098230400000000 | 1098316800000000
|
|
(2 rows)
|
|
|
|
SELECT * FROM test.show_constraints('_timescaledb_internal._hyper_5_2_chunk');
|
|
Constraint | Type | Columns | Index | Expr | Deferrable | Deferred | Validated
|
|
--------------+------+---------+-------+------------------------------------------------------------------------------------------------------------------------------------------------+------------+----------+-----------
|
|
constraint_3 | c | {time} | - | (("time" >= 'Sat Oct 09 17:00:00 2004 PDT'::timestamp with time zone) AND ("time" < 'Sun Oct 10 17:00:00 2004 PDT'::timestamp with time zone)) | f | f | t
|
|
(1 row)
|
|
|
|
SELECT * FROM test.show_constraints('_timescaledb_internal._hyper_5_3_chunk');
|
|
Constraint | Type | Columns | Index | Expr | Deferrable | Deferred | Validated
|
|
--------------+------+---------+-------+------------------------------------------------------------------------------------------------------------------------------------------------+------------+----------+-----------
|
|
constraint_4 | c | {time} | - | (("time" >= 'Tue Oct 19 17:00:00 2004 PDT'::timestamp with time zone) AND ("time" < 'Wed Oct 20 17:00:00 2004 PDT'::timestamp with time zone)) | f | f | t
|
|
(1 row)
|
|
|
|
-- add dimension to the existing chunks by adding -inf/inf dimension slices
|
|
SELECT add_dimension('dim_test', 'device', 2);
|
|
add_dimension
|
|
-------------------------------
|
|
(13,public,dim_test,device,t)
|
|
(1 row)
|
|
|
|
SELECT * FROM test.show_constraints('_timescaledb_internal._hyper_5_2_chunk');
|
|
Constraint | Type | Columns | Index | Expr | Deferrable | Deferred | Validated
|
|
--------------+------+---------+-------+------------------------------------------------------------------------------------------------------------------------------------------------+------------+----------+-----------
|
|
constraint_3 | c | {time} | - | (("time" >= 'Sat Oct 09 17:00:00 2004 PDT'::timestamp with time zone) AND ("time" < 'Sun Oct 10 17:00:00 2004 PDT'::timestamp with time zone)) | f | f | t
|
|
(1 row)
|
|
|
|
SELECT * FROM test.show_constraints('_timescaledb_internal._hyper_5_3_chunk');
|
|
Constraint | Type | Columns | Index | Expr | Deferrable | Deferred | Validated
|
|
--------------+------+---------+-------+------------------------------------------------------------------------------------------------------------------------------------------------+------------+----------+-----------
|
|
constraint_4 | c | {time} | - | (("time" >= 'Tue Oct 19 17:00:00 2004 PDT'::timestamp with time zone) AND ("time" < 'Wed Oct 20 17:00:00 2004 PDT'::timestamp with time zone)) | f | f | t
|
|
(1 row)
|
|
|
|
SELECT * FROM dim_test_slices;
|
|
chunk_id | hypertable_id | dimension_id | dimension_slice_id | chunk_schema | chunk_table | range_start | range_end
|
|
----------+---------------+--------------+--------------------+-----------------------+------------------+----------------------+---------------------
|
|
2 | 5 | 12 | 3 | _timescaledb_internal | _hyper_5_2_chunk | 1097366400000000 | 1097452800000000
|
|
2 | 5 | 13 | 5 | _timescaledb_internal | _hyper_5_2_chunk | -9223372036854775808 | 9223372036854775807
|
|
3 | 5 | 12 | 4 | _timescaledb_internal | _hyper_5_3_chunk | 1098230400000000 | 1098316800000000
|
|
3 | 5 | 13 | 5 | _timescaledb_internal | _hyper_5_3_chunk | -9223372036854775808 | 9223372036854775807
|
|
(4 rows)
|
|
|
|
-- newer chunks have proper dimension slices range
|
|
INSERT INTO dim_test VALUES ('2004-10-30 00:00:00+00', 3);
|
|
SELECT * FROM dim_test_slices;
|
|
chunk_id | hypertable_id | dimension_id | dimension_slice_id | chunk_schema | chunk_table | range_start | range_end
|
|
----------+---------------+--------------+--------------------+-----------------------+------------------+----------------------+---------------------
|
|
2 | 5 | 12 | 3 | _timescaledb_internal | _hyper_5_2_chunk | 1097366400000000 | 1097452800000000
|
|
2 | 5 | 13 | 5 | _timescaledb_internal | _hyper_5_2_chunk | -9223372036854775808 | 9223372036854775807
|
|
3 | 5 | 12 | 4 | _timescaledb_internal | _hyper_5_3_chunk | 1098230400000000 | 1098316800000000
|
|
3 | 5 | 13 | 5 | _timescaledb_internal | _hyper_5_3_chunk | -9223372036854775808 | 9223372036854775807
|
|
4 | 5 | 12 | 6 | _timescaledb_internal | _hyper_5_4_chunk | 1099094400000000 | 1099180800000000
|
|
4 | 5 | 13 | 7 | _timescaledb_internal | _hyper_5_4_chunk | 1073741823 | 9223372036854775807
|
|
(6 rows)
|
|
|
|
SELECT * FROM dim_test ORDER BY time;
|
|
time | device
|
|
------------------------------+--------
|
|
Sat Oct 09 17:00:00 2004 PDT | 1
|
|
Tue Oct 19 17:00:00 2004 PDT | 2
|
|
Fri Oct 29 17:00:00 2004 PDT | 3
|
|
(3 rows)
|
|
|
|
DROP VIEW dim_test_slices;
|
|
DROP TABLE dim_test;
|
|
-- test add_dimension() with existing data on table with space partitioning
|
|
CREATE TABLE dim_test(time TIMESTAMPTZ, device int, data int);
|
|
SELECT create_hypertable('dim_test', 'time', 'device', 2, chunk_time_interval => INTERVAL '1 day');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
-----------------------
|
|
(6,public,dim_test,t)
|
|
(1 row)
|
|
|
|
CREATE VIEW dim_test_slices AS
|
|
SELECT c.id AS chunk_id, c.hypertable_id, ds.dimension_id, cc.dimension_slice_id, c.schema_name AS chunk_schema, c.table_name AS chunk_table, ds.range_start, ds.range_end
|
|
FROM _timescaledb_catalog.chunk c
|
|
INNER JOIN _timescaledb_catalog.hypertable h ON (c.hypertable_id = h.id)
|
|
INNER JOIN _timescaledb_catalog.dimension td ON (h.id = td.hypertable_id)
|
|
INNER JOIN _timescaledb_catalog.dimension_slice ds ON (ds.dimension_id = td.id)
|
|
INNER JOIN _timescaledb_catalog.chunk_constraint cc ON (cc.dimension_slice_id = ds.id AND cc.chunk_id = c.id)
|
|
WHERE h.table_name = 'dim_test'
|
|
ORDER BY c.id, ds.dimension_id;
|
|
INSERT INTO dim_test VALUES ('2004-10-10 00:00:00+00', 1, 3);
|
|
INSERT INTO dim_test VALUES ('2004-10-20 00:00:00+00', 2, 2);
|
|
SELECT * FROM dim_test_slices;
|
|
chunk_id | hypertable_id | dimension_id | dimension_slice_id | chunk_schema | chunk_table | range_start | range_end
|
|
----------+---------------+--------------+--------------------+-----------------------+------------------+----------------------+---------------------
|
|
5 | 6 | 14 | 8 | _timescaledb_internal | _hyper_6_5_chunk | 1097366400000000 | 1097452800000000
|
|
5 | 6 | 15 | 9 | _timescaledb_internal | _hyper_6_5_chunk | -9223372036854775808 | 1073741823
|
|
6 | 6 | 14 | 10 | _timescaledb_internal | _hyper_6_6_chunk | 1098230400000000 | 1098316800000000
|
|
6 | 6 | 15 | 11 | _timescaledb_internal | _hyper_6_6_chunk | 1073741823 | 9223372036854775807
|
|
(4 rows)
|
|
|
|
-- new dimension slice will cover full range on existing chunks
|
|
SELECT add_dimension('dim_test', 'data', 1);
|
|
add_dimension
|
|
-----------------------------
|
|
(16,public,dim_test,data,t)
|
|
(1 row)
|
|
|
|
SELECT * FROM dim_test_slices;
|
|
chunk_id | hypertable_id | dimension_id | dimension_slice_id | chunk_schema | chunk_table | range_start | range_end
|
|
----------+---------------+--------------+--------------------+-----------------------+------------------+----------------------+---------------------
|
|
5 | 6 | 14 | 8 | _timescaledb_internal | _hyper_6_5_chunk | 1097366400000000 | 1097452800000000
|
|
5 | 6 | 15 | 9 | _timescaledb_internal | _hyper_6_5_chunk | -9223372036854775808 | 1073741823
|
|
5 | 6 | 16 | 12 | _timescaledb_internal | _hyper_6_5_chunk | -9223372036854775808 | 9223372036854775807
|
|
6 | 6 | 14 | 10 | _timescaledb_internal | _hyper_6_6_chunk | 1098230400000000 | 1098316800000000
|
|
6 | 6 | 15 | 11 | _timescaledb_internal | _hyper_6_6_chunk | 1073741823 | 9223372036854775807
|
|
6 | 6 | 16 | 12 | _timescaledb_internal | _hyper_6_6_chunk | -9223372036854775808 | 9223372036854775807
|
|
(6 rows)
|
|
|
|
INSERT INTO dim_test VALUES ('2004-10-30 00:00:00+00', 3, 1);
|
|
SELECT * FROM dim_test_slices;
|
|
chunk_id | hypertable_id | dimension_id | dimension_slice_id | chunk_schema | chunk_table | range_start | range_end
|
|
----------+---------------+--------------+--------------------+-----------------------+------------------+----------------------+---------------------
|
|
5 | 6 | 14 | 8 | _timescaledb_internal | _hyper_6_5_chunk | 1097366400000000 | 1097452800000000
|
|
5 | 6 | 15 | 9 | _timescaledb_internal | _hyper_6_5_chunk | -9223372036854775808 | 1073741823
|
|
5 | 6 | 16 | 12 | _timescaledb_internal | _hyper_6_5_chunk | -9223372036854775808 | 9223372036854775807
|
|
6 | 6 | 14 | 10 | _timescaledb_internal | _hyper_6_6_chunk | 1098230400000000 | 1098316800000000
|
|
6 | 6 | 15 | 11 | _timescaledb_internal | _hyper_6_6_chunk | 1073741823 | 9223372036854775807
|
|
6 | 6 | 16 | 12 | _timescaledb_internal | _hyper_6_6_chunk | -9223372036854775808 | 9223372036854775807
|
|
7 | 6 | 14 | 13 | _timescaledb_internal | _hyper_6_7_chunk | 1099094400000000 | 1099180800000000
|
|
7 | 6 | 15 | 11 | _timescaledb_internal | _hyper_6_7_chunk | 1073741823 | 9223372036854775807
|
|
7 | 6 | 16 | 12 | _timescaledb_internal | _hyper_6_7_chunk | -9223372036854775808 | 9223372036854775807
|
|
(9 rows)
|
|
|
|
SELECT * FROM dim_test ORDER BY time;
|
|
time | device | data
|
|
------------------------------+--------+------
|
|
Sat Oct 09 17:00:00 2004 PDT | 1 | 3
|
|
Tue Oct 19 17:00:00 2004 PDT | 2 | 2
|
|
Fri Oct 29 17:00:00 2004 PDT | 3 | 1
|
|
(3 rows)
|
|
|
|
DROP VIEW dim_test_slices;
|
|
DROP TABLE dim_test;
|
|
-- should not fail on non-empty table with 'if_not_exists' in case the dimension exists
|
|
select add_dimension('test_schema.test_table', 'location', 2, if_not_exists => true);
|
|
NOTICE: column "location" is already a dimension, skipping
|
|
add_dimension
|
|
---------------------------------------
|
|
(5,test_schema,test_table,location,f)
|
|
(1 row)
|
|
|
|
--test partitioning in only time dimension
|
|
create table test_schema.test_1dim(time timestamp, temp float);
|
|
select create_hypertable('test_schema.test_1dim', 'time');
|
|
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
-----------------------------
|
|
(7,test_schema,test_1dim,t)
|
|
(1 row)
|
|
|
|
SELECT * FROM _timescaledb_internal.get_create_command('test_1dim');
|
|
get_create_command
|
|
--------------------------------------------------------------------------------------------------------------------------------
|
|
SELECT create_hypertable('test_schema.test_1dim', 'time', chunk_time_interval => 604800000000, create_default_indexes=>FALSE);
|
|
(1 row)
|
|
|
|
\dt "test_schema".*
|
|
List of relations
|
|
Schema | Name | Type | Owner
|
|
-------------+------------------------+-------+-------------------
|
|
test_schema | test_1dim | table | default_perm_user
|
|
test_schema | test_table | table | default_perm_user
|
|
test_schema | test_table_no_not_null | table | default_perm_user
|
|
(3 rows)
|
|
|
|
select create_hypertable('test_schema.test_1dim', 'time', if_not_exists => true);
|
|
NOTICE: table "test_1dim" is already a hypertable, skipping
|
|
create_hypertable
|
|
-----------------------------
|
|
(7,test_schema,test_1dim,f)
|
|
(1 row)
|
|
|
|
-- Should error when creating again without if_not_exists set to true
|
|
\set ON_ERROR_STOP 0
|
|
select create_hypertable('test_schema.test_1dim', 'time');
|
|
ERROR: table "test_1dim" is already a hypertable
|
|
\set ON_ERROR_STOP 1
|
|
-- if_not_exist should also work with data in the hypertable
|
|
insert into test_schema.test_1dim VALUES ('2004-10-19 10:23:54+02', 1.0);
|
|
select create_hypertable('test_schema.test_1dim', 'time', if_not_exists => true);
|
|
NOTICE: table "test_1dim" is already a hypertable, skipping
|
|
create_hypertable
|
|
-----------------------------
|
|
(7,test_schema,test_1dim,f)
|
|
(1 row)
|
|
|
|
-- Should error when creating again without if_not_exists set to true
|
|
\set ON_ERROR_STOP 0
|
|
select create_hypertable('test_schema.test_1dim', 'time');
|
|
ERROR: table "test_1dim" is already a hypertable
|
|
\set ON_ERROR_STOP 1
|
|
-- Test partitioning functions
|
|
CREATE OR REPLACE FUNCTION invalid_partfunc(source integer)
|
|
RETURNS INTEGER LANGUAGE PLPGSQL IMMUTABLE AS
|
|
$BODY$
|
|
BEGIN
|
|
RETURN NULL;
|
|
END
|
|
$BODY$;
|
|
CREATE OR REPLACE FUNCTION time_partfunc(source text)
|
|
RETURNS TIMESTAMPTZ LANGUAGE PLPGSQL IMMUTABLE AS
|
|
$BODY$
|
|
BEGIN
|
|
RETURN timezone('UTC', to_timestamp(source));
|
|
END
|
|
$BODY$;
|
|
CREATE TABLE test_schema.test_invalid_func(time timestamptz, temp float8, device text);
|
|
\set ON_ERROR_STOP 0
|
|
-- should fail due to invalid signature
|
|
SELECT create_hypertable('test_schema.test_invalid_func', 'time', 'device', 2, partitioning_func => 'invalid_partfunc');
|
|
ERROR: invalid partitioning function
|
|
SELECT create_hypertable('test_schema.test_invalid_func', 'time');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
-------------------------------------
|
|
(8,test_schema,test_invalid_func,t)
|
|
(1 row)
|
|
|
|
-- should also fail due to invalid signature
|
|
SELECT add_dimension('test_schema.test_invalid_func', 'device', 2, partitioning_func => 'invalid_partfunc');
|
|
ERROR: invalid partitioning function
|
|
\set ON_ERROR_STOP 1
|
|
-- Test open-dimension function
|
|
CREATE TABLE test_schema.open_dim_part_func(time text, temp float8, device text, event_time text);
|
|
\set ON_ERROR_STOP 0
|
|
-- should fail due to invalid signature
|
|
SELECT create_hypertable('test_schema.open_dim_part_func', 'time', time_partitioning_func => 'invalid_partfunc');
|
|
ERROR: invalid partitioning function
|
|
\set ON_ERROR_STOP 1
|
|
SELECT create_hypertable('test_schema.open_dim_part_func', 'time', time_partitioning_func => 'time_partfunc');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
--------------------------------------
|
|
(9,test_schema,open_dim_part_func,t)
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
-- should fail due to invalid signature
|
|
SELECT add_dimension('test_schema.open_dim_part_func', 'event_time', chunk_time_interval => interval '1 day', partitioning_func => 'invalid_partfunc');
|
|
ERROR: invalid partitioning function
|
|
\set ON_ERROR_STOP 1
|
|
SELECT add_dimension('test_schema.open_dim_part_func', 'event_time', chunk_time_interval => interval '1 day', partitioning_func => 'time_partfunc');
|
|
NOTICE: adding not-null constraint to column "event_time"
|
|
add_dimension
|
|
--------------------------------------------------
|
|
(20,test_schema,open_dim_part_func,event_time,t)
|
|
(1 row)
|
|
|
|
--test data migration
|
|
create table test_schema.test_migrate(time timestamp, temp float);
|
|
insert into test_schema.test_migrate VALUES ('2004-10-19 10:23:54+02', 1.0), ('2004-12-19 10:23:54+02', 2.0);
|
|
select * from only test_schema.test_migrate;
|
|
time | temp
|
|
--------------------------+------
|
|
Tue Oct 19 10:23:54 2004 | 1
|
|
Sun Dec 19 10:23:54 2004 | 2
|
|
(2 rows)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
--should fail without migrate_data => true
|
|
select create_hypertable('test_schema.test_migrate', 'time');
|
|
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
|
|
ERROR: table "test_migrate" is not empty
|
|
\set ON_ERROR_STOP 1
|
|
select create_hypertable('test_schema.test_migrate', 'time', migrate_data => true);
|
|
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
|
|
NOTICE: adding not-null constraint to column "time"
|
|
NOTICE: migrating data to chunks
|
|
create_hypertable
|
|
---------------------------------
|
|
(10,test_schema,test_migrate,t)
|
|
(1 row)
|
|
|
|
--there should be two new chunks
|
|
select * from _timescaledb_catalog.hypertable where table_name = 'test_migrate';
|
|
id | schema_name | table_name | associated_schema_name | associated_table_prefix | num_dimensions | chunk_sizing_func_schema | chunk_sizing_func_name | chunk_target_size | compression_state | compressed_hypertable_id | replication_factor
|
|
----+-------------+--------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------
|
|
10 | test_schema | test_migrate | _timescaledb_internal | _hyper_10 | 1 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.chunk;
|
|
id | hypertable_id | schema_name | table_name | compressed_chunk_id | dropped | status | osm_chunk
|
|
----+---------------+-----------------------+--------------------+---------------------+---------+--------+-----------
|
|
1 | 1 | _timescaledb_internal | _hyper_1_1_chunk | | f | 0 | f
|
|
8 | 7 | _timescaledb_internal | _hyper_7_8_chunk | | f | 0 | f
|
|
9 | 10 | _timescaledb_internal | _hyper_10_9_chunk | | f | 0 | f
|
|
10 | 10 | _timescaledb_internal | _hyper_10_10_chunk | | f | 0 | f
|
|
(4 rows)
|
|
|
|
select * from test_schema.test_migrate;
|
|
time | temp
|
|
--------------------------+------
|
|
Tue Oct 19 10:23:54 2004 | 1
|
|
Sun Dec 19 10:23:54 2004 | 2
|
|
(2 rows)
|
|
|
|
--main table should now be empty
|
|
select * from only test_schema.test_migrate;
|
|
time | temp
|
|
------+------
|
|
(0 rows)
|
|
|
|
select * from only _timescaledb_internal._hyper_10_9_chunk;
|
|
time | temp
|
|
--------------------------+------
|
|
Tue Oct 19 10:23:54 2004 | 1
|
|
(1 row)
|
|
|
|
select * from only _timescaledb_internal._hyper_10_10_chunk;
|
|
time | temp
|
|
--------------------------+------
|
|
Sun Dec 19 10:23:54 2004 | 2
|
|
(1 row)
|
|
|
|
create table test_schema.test_migrate_empty(time timestamp, temp float);
|
|
select create_hypertable('test_schema.test_migrate_empty', 'time', migrate_data => true);
|
|
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
---------------------------------------
|
|
(11,test_schema,test_migrate_empty,t)
|
|
(1 row)
|
|
|
|
CREATE TYPE test_type AS (time timestamp, temp float);
|
|
CREATE TABLE test_table_of_type OF test_type;
|
|
SELECT create_hypertable('test_table_of_type', 'time');
|
|
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
----------------------------------
|
|
(12,public,test_table_of_type,t)
|
|
(1 row)
|
|
|
|
INSERT INTO test_table_of_type VALUES ('2004-10-19 10:23:54+02', 1.0), ('2004-12-19 10:23:54+02', 2.0);
|
|
\set ON_ERROR_STOP 0
|
|
DROP TYPE test_type;
|
|
ERROR: cannot drop type test_type because other objects depend on it
|
|
\set ON_ERROR_STOP 1
|
|
DROP TYPE test_type CASCADE;
|
|
NOTICE: drop cascades to 3 other objects
|
|
CREATE TABLE test_table_of_type (time timestamp, temp float);
|
|
SELECT create_hypertable('test_table_of_type', 'time');
|
|
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
----------------------------------
|
|
(13,public,test_table_of_type,t)
|
|
(1 row)
|
|
|
|
INSERT INTO test_table_of_type VALUES ('2004-10-19 10:23:54+02', 1.0), ('2004-12-19 10:23:54+02', 2.0);
|
|
CREATE TYPE test_type AS (time timestamp, temp float);
|
|
ALTER TABLE test_table_of_type OF test_type;
|
|
\set ON_ERROR_STOP 0
|
|
DROP TYPE test_type;
|
|
ERROR: cannot drop type test_type because other objects depend on it
|
|
\set ON_ERROR_STOP 1
|
|
BEGIN;
|
|
DROP TYPE test_type CASCADE;
|
|
NOTICE: drop cascades to 3 other objects
|
|
ROLLBACK;
|
|
ALTER TABLE test_table_of_type NOT OF;
|
|
DROP TYPE test_type;
|
|
-- Reset GRANTS
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
REVOKE :ROLE_DEFAULT_PERM_USER FROM :ROLE_DEFAULT_PERM_USER_2;
|
|
-- Test custom partitioning functions
|
|
CREATE OR REPLACE FUNCTION partfunc_not_immutable(source anyelement)
|
|
RETURNS INTEGER LANGUAGE PLPGSQL AS
|
|
$BODY$
|
|
BEGIN
|
|
RETURN _timescaledb_internal.get_partition_hash(source);
|
|
END
|
|
$BODY$;
|
|
CREATE OR REPLACE FUNCTION partfunc_bad_return_type(source anyelement)
|
|
RETURNS BIGINT LANGUAGE PLPGSQL IMMUTABLE AS
|
|
$BODY$
|
|
BEGIN
|
|
RETURN _timescaledb_internal.get_partition_hash(source);
|
|
END
|
|
$BODY$;
|
|
CREATE OR REPLACE FUNCTION partfunc_bad_arg_type(source text)
|
|
RETURNS INTEGER LANGUAGE PLPGSQL IMMUTABLE AS
|
|
$BODY$
|
|
BEGIN
|
|
RETURN _timescaledb_internal.get_partition_hash(source);
|
|
END
|
|
$BODY$;
|
|
CREATE OR REPLACE FUNCTION partfunc_bad_multi_arg(source anyelement, extra_arg integer)
|
|
RETURNS INTEGER LANGUAGE PLPGSQL IMMUTABLE AS
|
|
$BODY$
|
|
BEGIN
|
|
RETURN _timescaledb_internal.get_partition_hash(source);
|
|
END
|
|
$BODY$;
|
|
CREATE OR REPLACE FUNCTION partfunc_valid(source anyelement)
|
|
RETURNS INTEGER LANGUAGE PLPGSQL IMMUTABLE AS
|
|
$BODY$
|
|
BEGIN
|
|
RETURN _timescaledb_internal.get_partition_hash(source);
|
|
END
|
|
$BODY$;
|
|
create table test_schema.test_partfunc(time timestamptz, temp float, device int);
|
|
-- Test that create_hypertable fails due to invalid partitioning function
|
|
\set ON_ERROR_STOP 0
|
|
select create_hypertable('test_schema.test_partfunc', 'time', 'device', 2, partitioning_func => 'partfunc_not_immutable');
|
|
ERROR: invalid partitioning function
|
|
select create_hypertable('test_schema.test_partfunc', 'time', 'device', 2, partitioning_func => 'partfunc_bad_return_type');
|
|
ERROR: invalid partitioning function
|
|
select create_hypertable('test_schema.test_partfunc', 'time', 'device', 2, partitioning_func => 'partfunc_bad_arg_type');
|
|
ERROR: invalid partitioning function
|
|
select create_hypertable('test_schema.test_partfunc', 'time', 'device', 2, partitioning_func => 'partfunc_bad_multi_arg');
|
|
ERROR: invalid partitioning function
|
|
\set ON_ERROR_STOP 1
|
|
-- Test that add_dimension fails due to invalid partitioning function
|
|
select create_hypertable('test_schema.test_partfunc', 'time');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
----------------------------------
|
|
(14,test_schema,test_partfunc,t)
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
select add_dimension('test_schema.test_partfunc', 'device', 2, partitioning_func => 'partfunc_not_immutable');
|
|
ERROR: invalid partitioning function
|
|
select add_dimension('test_schema.test_partfunc', 'device', 2, partitioning_func => 'partfunc_bad_return_type');
|
|
ERROR: invalid partitioning function
|
|
select add_dimension('test_schema.test_partfunc', 'device', 2, partitioning_func => 'partfunc_bad_arg_type');
|
|
ERROR: invalid partitioning function
|
|
select add_dimension('test_schema.test_partfunc', 'device', 2, partitioning_func => 'partfunc_bad_multi_arg');
|
|
ERROR: invalid partitioning function
|
|
\set ON_ERROR_STOP 1
|
|
-- A valid function should work:
|
|
select add_dimension('test_schema.test_partfunc', 'device', 2, partitioning_func => 'partfunc_valid');
|
|
add_dimension
|
|
-----------------------------------------
|
|
(26,test_schema,test_partfunc,device,t)
|
|
(1 row)
|
|
|
|
-- check get_create_command produces valid command
|
|
CREATE TABLE test_schema.test_sql_cmd(time TIMESTAMPTZ, temp FLOAT8, device_id TEXT, device_type TEXT, location TEXT, id INT, id2 INT);
|
|
SELECT create_hypertable('test_schema.test_sql_cmd','time');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
---------------------------------
|
|
(15,test_schema,test_sql_cmd,t)
|
|
(1 row)
|
|
|
|
SELECT * FROM _timescaledb_internal.get_create_command('test_sql_cmd');
|
|
get_create_command
|
|
-----------------------------------------------------------------------------------------------------------------------------------
|
|
SELECT create_hypertable('test_schema.test_sql_cmd', 'time', chunk_time_interval => 604800000000, create_default_indexes=>FALSE);
|
|
(1 row)
|
|
|
|
SELECT _timescaledb_internal.get_create_command('test_sql_cmd') AS create_cmd; \gset
|
|
create_cmd
|
|
-----------------------------------------------------------------------------------------------------------------------------------
|
|
SELECT create_hypertable('test_schema.test_sql_cmd', 'time', chunk_time_interval => 604800000000, create_default_indexes=>FALSE);
|
|
(1 row)
|
|
|
|
DROP TABLE test_schema.test_sql_cmd CASCADE;
|
|
CREATE TABLE test_schema.test_sql_cmd(time TIMESTAMPTZ, temp FLOAT8, device_id TEXT, device_type TEXT, location TEXT, id INT, id2 INT);
|
|
SELECT test.execute_sql(:'create_cmd');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
execute_sql
|
|
-----------------------------------------------------------------------------------------------------------------------------------
|
|
SELECT create_hypertable('test_schema.test_sql_cmd', 'time', chunk_time_interval => 604800000000, create_default_indexes=>FALSE);
|
|
(1 row)
|
|
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
CREATE TABLE test_table_int(time bigint, junk int);
|
|
SELECT hypertable_id AS "TEST_TABLE_INT_HYPERTABLE_ID" FROM create_hypertable('test_table_int', 'time', chunk_time_interval => 1) \gset
|
|
NOTICE: adding not-null constraint to column "time"
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
CREATE SCHEMA IF NOT EXISTS my_schema;
|
|
create or replace function my_schema.dummy_now2() returns BIGINT LANGUAGE SQL IMMUTABLE as 'SELECT 1::BIGINT';
|
|
grant execute on ALL FUNCTIONS IN SCHEMA my_schema to public;
|
|
create or replace function dummy_now3() returns BIGINT LANGUAGE SQL IMMUTABLE as 'SELECT 1::BIGINT';
|
|
grant execute on ALL FUNCTIONS IN SCHEMA my_schema to public;
|
|
REVOKE execute ON function dummy_now3() FROM PUBLIC;
|
|
CREATE SCHEMA IF NOT EXISTS my_user_schema;
|
|
GRANT ALL ON SCHEMA my_user_schema to PUBLIC;
|
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
|
create or replace function dummy_now() returns BIGINT LANGUAGE SQL IMMUTABLE as 'SELECT 1::BIGINT';
|
|
create or replace function my_user_schema.dummy_now4() returns BIGINT LANGUAGE SQL IMMUTABLE as 'SELECT 1::BIGINT';
|
|
select set_integer_now_func('test_table_int', 'dummy_now');
|
|
set_integer_now_func
|
|
----------------------
|
|
|
|
(1 row)
|
|
|
|
select * from _timescaledb_catalog.dimension WHERE hypertable_id = :TEST_TABLE_INT_HYPERTABLE_ID;
|
|
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func
|
|
----+---------------+-------------+-------------+---------+------------+--------------------------+-------------------+-----------------+--------------------------+-------------------------+------------------
|
|
29 | 17 | time | bigint | t | | | | 1 | | public | dummy_now
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
select set_integer_now_func('test_table_int', 'dummy_now');
|
|
ERROR: custom time function already set for hypertable "test_table_int"
|
|
select set_integer_now_func('test_table_int', 'my_schema.dummy_now2', replace_if_exists => TRUE);
|
|
ERROR: permission denied for schema my_schema at character 47
|
|
select set_integer_now_func('test_table_int', 'dummy_now3', replace_if_exists => TRUE);
|
|
ERROR: permission denied for function dummy_now3
|
|
\set ON_ERROR_STOP
|
|
select set_integer_now_func('test_table_int', 'my_user_schema.dummy_now4', replace_if_exists => TRUE);
|
|
set_integer_now_func
|
|
----------------------
|
|
|
|
(1 row)
|
|
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
ALTER SCHEMA my_user_schema RENAME TO my_new_schema;
|
|
select * from _timescaledb_catalog.dimension WHERE hypertable_id = :TEST_TABLE_INT_HYPERTABLE_ID;
|
|
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func
|
|
----+---------------+-------------+-------------+---------+------------+--------------------------+-------------------+-----------------+--------------------------+-------------------------+------------------
|
|
29 | 17 | time | bigint | t | | | | 1 | | my_new_schema | dummy_now4
|
|
(1 row)
|
|
|
|
-- github issue #4650
|
|
CREATE TABLE sample_table (
|
|
cpu double precision null,
|
|
time TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
sensor_id INTEGER NOT NULL,
|
|
name varchar(100) default 'this is a default string value',
|
|
UNIQUE(sensor_id, time)
|
|
);
|
|
ALTER TABLE sample_table DROP COLUMN name;
|
|
-- below creation should not report any warnings.
|
|
SELECT * FROM create_hypertable('sample_table', 'time');
|
|
hypertable_id | schema_name | table_name | created
|
|
---------------+-------------+--------------+---------
|
|
18 | public | sample_table | t
|
|
(1 row)
|
|
|
|
-- cleanup
|
|
DROP TABLE sample_table CASCADE;
|
|
-- github issue 4684
|
|
-- test PARTITION BY HASH
|
|
CREATE TABLE regular(
|
|
id INT NOT NULL,
|
|
dev INT NOT NULL,
|
|
value INT,
|
|
CONSTRAINT cstr_regular_pky PRIMARY KEY (id)
|
|
) PARTITION BY HASH (id);
|
|
DO $$
|
|
BEGIN
|
|
FOR i IN 1..2
|
|
LOOP
|
|
EXECUTE format('
|
|
CREATE TABLE %I
|
|
PARTITION OF regular
|
|
FOR VALUES WITH (MODULUS 2, REMAINDER %s)',
|
|
'regular_' || i, i - 1
|
|
);
|
|
END LOOP;
|
|
END;
|
|
$$;
|
|
INSERT INTO regular SELECT generate_series(1,1000), 44,55;
|
|
CREATE TABLE timescale (
|
|
ts TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
id INT NOT NULL,
|
|
dev INT NOT NULL,
|
|
FOREIGN KEY (id) REFERENCES regular(id) ON DELETE CASCADE
|
|
);
|
|
SELECT create_hypertable(
|
|
relation => 'timescale',
|
|
time_column_name => 'ts'
|
|
);
|
|
create_hypertable
|
|
-------------------------
|
|
(19,public,timescale,t)
|
|
(1 row)
|
|
|
|
-- creates chunk1
|
|
INSERT INTO timescale SELECT now(), generate_series(1,200), 43;
|
|
-- creates chunk2
|
|
INSERT INTO timescale SELECT now() + interval '20' day, generate_series(1,200), 43;
|
|
-- creates chunk3
|
|
INSERT INTO timescale SELECT now() + interval '40' day, generate_series(1,200), 43;
|
|
-- show chunks
|
|
SELECT SHOW_CHUNKS('timescale');
|
|
show_chunks
|
|
------------------------------------------
|
|
_timescaledb_internal._hyper_19_15_chunk
|
|
_timescaledb_internal._hyper_19_16_chunk
|
|
_timescaledb_internal._hyper_19_17_chunk
|
|
(3 rows)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
-- record goes into chunk1 violating FK constraint as value 1001 is not present in regular table
|
|
INSERT INTO timescale SELECT now(), 1001, 43;
|
|
ERROR: insert or update on table "_hyper_19_15_chunk" violates foreign key constraint "15_1_timescale_id_fkey"
|
|
-- record goes into chunk2 violating FK constraint as value 1002 is not present in regular table
|
|
INSERT INTO timescale SELECT now() + interval '20' day, 1002, 43;
|
|
ERROR: insert or update on table "_hyper_19_16_chunk" violates foreign key constraint "16_2_timescale_id_fkey"
|
|
-- record goes into chunk3 violating FK constraint as value 1003 is not present in regular table
|
|
INSERT INTO timescale SELECT now() + interval '40' day, 1003, 43;
|
|
ERROR: insert or update on table "_hyper_19_17_chunk" violates foreign key constraint "17_3_timescale_id_fkey"
|
|
\set ON_ERROR_STOP 1
|
|
-- cleanup
|
|
DROP TABLE regular cascade;
|
|
NOTICE: drop cascades to 4 other objects
|
|
DROP TABLE timescale cascade;
|
|
-- test PARTITION BY RANGE
|
|
CREATE TABLE regular(
|
|
id INT NOT NULL,
|
|
dev INT NOT NULL,
|
|
value INT,
|
|
CONSTRAINT cstr_regular_pky PRIMARY KEY (id)
|
|
) PARTITION BY RANGE (id);
|
|
CREATE TABLE regular_1_500 PARTITION OF regular
|
|
FOR VALUES FROM (1) TO (500);
|
|
CREATE TABLE regular_500_1000 PARTITION OF regular
|
|
FOR VALUES FROM (500) TO (801);
|
|
INSERT INTO regular SELECT generate_series(1,800), 44,55;
|
|
CREATE TABLE timescale (
|
|
ts TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
id INT NOT NULL,
|
|
dev INT NOT NULL,
|
|
FOREIGN KEY (id) REFERENCES regular(id) ON DELETE CASCADE
|
|
);
|
|
SELECT create_hypertable(
|
|
relation => 'timescale',
|
|
time_column_name => 'ts'
|
|
);
|
|
create_hypertable
|
|
-------------------------
|
|
(20,public,timescale,t)
|
|
(1 row)
|
|
|
|
-- creates chunk1
|
|
INSERT INTO timescale SELECT now(), generate_series(1,200), 43;
|
|
-- creates chunk2
|
|
INSERT INTO timescale SELECT now() + interval '20' day, generate_series(200,400), 43;
|
|
-- creates chunk3
|
|
INSERT INTO timescale SELECT now() + interval '40' day, generate_series(400,600), 43;
|
|
-- show chunks
|
|
SELECT SHOW_CHUNKS('timescale');
|
|
show_chunks
|
|
------------------------------------------
|
|
_timescaledb_internal._hyper_20_18_chunk
|
|
_timescaledb_internal._hyper_20_19_chunk
|
|
_timescaledb_internal._hyper_20_20_chunk
|
|
(3 rows)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
-- FK constraint violation as value 801 is not present in regular table
|
|
INSERT INTO timescale SELECT now(), 801, 43;
|
|
ERROR: insert or update on table "_hyper_20_18_chunk" violates foreign key constraint "18_4_timescale_id_fkey"
|
|
-- FK constraint violation as value 902 is not present in regular table
|
|
INSERT INTO timescale SELECT now() + interval '20' day, 902, 43;
|
|
ERROR: insert or update on table "_hyper_20_19_chunk" violates foreign key constraint "19_5_timescale_id_fkey"
|
|
-- FK constraint violation as value 1003 is not present in regular table
|
|
INSERT INTO timescale SELECT now() + interval '40' day, 1003, 43;
|
|
ERROR: insert or update on table "_hyper_20_20_chunk" violates foreign key constraint "20_6_timescale_id_fkey"
|
|
\set ON_ERROR_STOP 1
|
|
-- cleanup
|
|
DROP TABLE regular cascade;
|
|
NOTICE: drop cascades to 4 other objects
|
|
DROP TABLE timescale cascade;
|
|
-- test PARTITION BY LIST
|
|
CREATE TABLE regular(
|
|
id INT NOT NULL,
|
|
dev INT NOT NULL,
|
|
value INT,
|
|
CONSTRAINT cstr_regular_pky PRIMARY KEY (id)
|
|
) PARTITION BY LIST (id);
|
|
CREATE TABLE regular_1_2_3_4 PARTITION OF regular FOR VALUES IN (1,2,3,4);
|
|
CREATE TABLE regular_5_6_7_8 PARTITION OF regular FOR VALUES IN (5,6,7,8);
|
|
INSERT INTO regular SELECT generate_series(1,8), 44,55;
|
|
CREATE TABLE timescale (
|
|
ts TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
id INT NOT NULL,
|
|
dev INT NOT NULL,
|
|
FOREIGN KEY (id) REFERENCES regular(id) ON DELETE CASCADE
|
|
);
|
|
SELECT create_hypertable(
|
|
relation => 'timescale',
|
|
time_column_name => 'ts'
|
|
);
|
|
create_hypertable
|
|
-------------------------
|
|
(21,public,timescale,t)
|
|
(1 row)
|
|
|
|
insert into timescale values (now(), 1,2);
|
|
insert into timescale values (now(), 2,2);
|
|
insert into timescale values (now(), 3,2);
|
|
insert into timescale values (now(), 4,2);
|
|
insert into timescale values (now(), 5,2);
|
|
insert into timescale values (now(), 6,2);
|
|
insert into timescale values (now(), 7,2);
|
|
insert into timescale values (now(), 8,2);
|
|
\set ON_ERROR_STOP 0
|
|
-- FK constraint violation as value 9 is not present in regular table
|
|
insert into timescale values (now(), 9,2);
|
|
ERROR: insert or update on table "_hyper_21_21_chunk" violates foreign key constraint "21_7_timescale_id_fkey"
|
|
-- FK constraint violation as value 10 is not present in regular table
|
|
insert into timescale values (now(), 10,2);
|
|
ERROR: insert or update on table "_hyper_21_21_chunk" violates foreign key constraint "21_7_timescale_id_fkey"
|
|
-- FK constraint violation as value 111 is not present in regular table
|
|
insert into timescale values (now(), 111,2);
|
|
ERROR: insert or update on table "_hyper_21_21_chunk" violates foreign key constraint "21_7_timescale_id_fkey"
|
|
\set ON_ERROR_STOP 1
|
|
-- cleanup
|
|
DROP TABLE regular cascade;
|
|
NOTICE: drop cascades to 2 other objects
|
|
DROP TABLE timescale cascade;
|
|
-- github issue 4872
|
|
-- If subplan of ChunkAppend is TidRangeScan, then SELECT on
|
|
-- hypertable fails with error "invalid child of chunk append: Node (26)"
|
|
create table tidrangescan_test (
|
|
time timestamp with time zone,
|
|
some_column bigint
|
|
);
|
|
select create_hypertable('tidrangescan_test', 'time');
|
|
NOTICE: adding not-null constraint to column "time"
|
|
create_hypertable
|
|
---------------------------------
|
|
(22,public,tidrangescan_test,t)
|
|
(1 row)
|
|
|
|
insert into tidrangescan_test (time, some_column) values ('2023-02-12 00:00:00+02:40', 1);
|
|
insert into tidrangescan_test (time, some_column) values ('2023-02-12 00:00:10+02:40', 2);
|
|
insert into tidrangescan_test (time, some_column) values ('2023-02-12 00:00:20+02:40', 3);
|
|
-- Below query will generate plan as
|
|
-- Custom Scan (ChunkAppend)
|
|
-- -> Tid Range Scan
|
|
-- However when traversing ChunkAppend node, Tid Range Scan node is not
|
|
-- recognised as a valid child node of ChunkAppend which causes error
|
|
-- "invalid child of chunk append: Node (26)" when below query is executed
|
|
select * from tidrangescan_test where time > '2023-02-12 00:00:00+02:40'::timestamp with time zone - interval '5 years' and ctid < '(1,1)'::tid ORDER BY time;
|
|
time | some_column
|
|
------------------------------+-------------
|
|
Sat Feb 11 13:20:00 2023 PST | 1
|
|
Sat Feb 11 13:20:10 2023 PST | 2
|
|
Sat Feb 11 13:20:20 2023 PST | 3
|
|
(3 rows)
|
|
|
|
drop table tidrangescan_test;
|