mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-14 09:37:00 +08:00
The new "create_hypertable" API using the dimension info inadvertantly allowed creating hypertables with hash partitioning on the primary column. Since the rest of the machinery (policies, tiering, etc.) does not support hash partitions on primary column properly, we restrict it now in the new API. The older "create_hypertable" API was disallowing it earlier anyways. Fixes #6993
560 lines
20 KiB
Plaintext
560 lines
20 KiB
Plaintext
-- This file and its contents are licensed under the Timescale License.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-TIMESCALE for a copy of the license.
|
|
CREATE OR REPLACE FUNCTION part_func(id TEXT)
|
|
RETURNS INTEGER LANGUAGE PLPGSQL IMMUTABLE AS
|
|
$BODY$
|
|
DECLARE
|
|
retval INTEGER;
|
|
BEGIN
|
|
retval := CAST(id AS INTEGER);
|
|
RETURN retval;
|
|
END
|
|
$BODY$;
|
|
-- test null handling
|
|
\set ON_ERROR_STOP 0
|
|
CREATE TABLE n();
|
|
SELECT create_hypertable('n',NULL::_timescaledb_internal.dimension_info);
|
|
ERROR: dimension cannot be NULL
|
|
SELECT add_dimension('n',NULL::_timescaledb_internal.dimension_info);
|
|
ERROR: dimension cannot be NULL
|
|
\set ON_ERROR_STOP 1
|
|
SELECT by_range('id');
|
|
by_range
|
|
-----------------
|
|
range//id//-//-
|
|
(1 row)
|
|
|
|
SELECT by_range('id', partition_func => 'part_func');
|
|
by_range
|
|
-------------------------
|
|
range//id//-//part_func
|
|
(1 row)
|
|
|
|
SELECT by_range('id', '1 week'::interval);
|
|
by_range
|
|
------------------------
|
|
range//id//@ 7 days//-
|
|
(1 row)
|
|
|
|
SELECT by_range('id', '1 week'::interval, 'part_func'::regproc);
|
|
by_range
|
|
--------------------------------
|
|
range//id//@ 7 days//part_func
|
|
(1 row)
|
|
|
|
SELECT by_hash('id', 3);
|
|
by_hash
|
|
----------------
|
|
hash//id//3//-
|
|
(1 row)
|
|
|
|
SELECT by_hash('id', 3, partition_func => 'part_func');
|
|
by_hash
|
|
------------------------
|
|
hash//id//3//part_func
|
|
(1 row)
|
|
|
|
-- Check if we handle the varlength of the datatype properly
|
|
SELECT * FROM by_range('id') WHERE by_range IS NOT NULL;
|
|
by_range
|
|
-----------------
|
|
range//id//-//-
|
|
(1 row)
|
|
|
|
SELECT * FROM by_range('id', partition_func => 'part_func') WHERE by_range IS NOT NULL;
|
|
by_range
|
|
-------------------------
|
|
range//id//-//part_func
|
|
(1 row)
|
|
|
|
SELECT * FROM by_hash('id', 3) WHERE by_hash IS NOT NULL;
|
|
by_hash
|
|
----------------
|
|
hash//id//3//-
|
|
(1 row)
|
|
|
|
SELECT * FROM by_hash('id', 3, partition_func => 'part_func') WHERE by_hash IS NOT NULL;
|
|
by_hash
|
|
------------------------
|
|
hash//id//3//part_func
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
SELECT 'hash//id//3//-'::_timescaledb_internal.dimension_info;
|
|
ERROR: cannot construct type "dimension_info" from string at character 8
|
|
SELECT by_range(NULL::name);
|
|
ERROR: column_name cannot be NULL
|
|
SELECT by_hash(NULL::name, 3);
|
|
ERROR: column_name cannot be NULL
|
|
\set ON_ERROR_STOP 1
|
|
-- Validate generalized hypertable for smallint
|
|
CREATE TABLE test_table_smallint(id SMALLINT, device INTEGER, time TIMESTAMPTZ);
|
|
SELECT create_hypertable('test_table_smallint', by_range('id'));
|
|
NOTICE: adding not-null constraint to column "id"
|
|
create_hypertable
|
|
-------------------
|
|
(1,t)
|
|
(1 row)
|
|
|
|
-- default interval
|
|
SELECT integer_interval FROM timescaledb_information.dimensions WHERE hypertable_name = 'test_table_smallint';
|
|
integer_interval
|
|
------------------
|
|
10000
|
|
(1 row)
|
|
|
|
-- Add data with default partition (10000)
|
|
INSERT INTO test_table_smallint VALUES (1, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_smallint VALUES (9999, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_smallint VALUES (10000, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_smallint VALUES (20000, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
-- Number of chunks
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name='test_table_smallint';
|
|
count
|
|
-------
|
|
3
|
|
(1 row)
|
|
|
|
-- Validate generalized hypertable for int
|
|
CREATE TABLE test_table_int(id INTEGER, device INTEGER, time TIMESTAMPTZ);
|
|
SELECT create_hypertable('test_table_int', by_range('id'));
|
|
NOTICE: adding not-null constraint to column "id"
|
|
create_hypertable
|
|
-------------------
|
|
(2,t)
|
|
(1 row)
|
|
|
|
-- Default interval
|
|
SELECT integer_interval FROM timescaledb_information.dimensions WHERE hypertable_name = 'test_table_int';
|
|
integer_interval
|
|
------------------
|
|
100000
|
|
(1 row)
|
|
|
|
-- Add data
|
|
INSERT INTO test_table_int VALUES (1, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_int VALUES (99999, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_int VALUES (100000, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_int VALUES (200000, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
-- Number of chunks
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name='test_table_int';
|
|
count
|
|
-------
|
|
3
|
|
(1 row)
|
|
|
|
-- Validate generalized hypertable for bigint
|
|
CREATE TABLE test_table_bigint(id BIGINT, device INTEGER, time TIMESTAMPTZ);
|
|
SELECT create_hypertable('test_table_bigint', by_range('id'));
|
|
NOTICE: adding not-null constraint to column "id"
|
|
create_hypertable
|
|
-------------------
|
|
(3,t)
|
|
(1 row)
|
|
|
|
-- Default interval
|
|
SELECT integer_interval FROM timescaledb_information.dimensions WHERE hypertable_name = 'test_table_bigint';
|
|
integer_interval
|
|
------------------
|
|
1000000
|
|
(1 row)
|
|
|
|
-- Add data
|
|
INSERT INTO test_table_bigint VALUES (1, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_bigint VALUES (999999, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_bigint VALUES (1000000, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_bigint VALUES (2000000, 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
-- Number of chunks
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name='test_table_bigint';
|
|
count
|
|
-------
|
|
3
|
|
(1 row)
|
|
|
|
DROP TABLE test_table_smallint;
|
|
DROP TABLE test_table_int;
|
|
DROP TABLE test_table_bigint;
|
|
-- Create hypertable with SERIAL column
|
|
CREATE TABLE jobs_serial (job_id SERIAL, device_id INTEGER, start_time TIMESTAMPTZ, end_time TIMESTAMPTZ, PRIMARY KEY (job_id));
|
|
SELECT create_hypertable('jobs_serial', by_range('job_id', partition_interval => 30));
|
|
create_hypertable
|
|
-------------------
|
|
(4,t)
|
|
(1 row)
|
|
|
|
-- Insert data
|
|
INSERT INTO jobs_serial (device_id, start_time, end_time)
|
|
SELECT abs(timestamp_hash(t::timestamp)) % 10, t, t + INTERVAL '1 day'
|
|
FROM generate_series('2018-03-02 1:00'::TIMESTAMPTZ, '2018-03-08 1:00':: TIMESTAMPTZ,'1 hour')t;
|
|
-- Verify chunk pruning
|
|
EXPLAIN VERBOSE SELECT * FROM jobs_serial WHERE job_id < 30;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------
|
|
Index Scan using "10_1_jobs_serial_pkey" on _timescaledb_internal._hyper_4_10_chunk (cost=0.15..20.30 rows=523 width=24)
|
|
Output: _hyper_4_10_chunk.job_id, _hyper_4_10_chunk.device_id, _hyper_4_10_chunk.start_time, _hyper_4_10_chunk.end_time
|
|
Index Cond: (_hyper_4_10_chunk.job_id < 30)
|
|
(3 rows)
|
|
|
|
EXPLAIN VERBOSE SELECT * FROM jobs_serial WHERE job_id >= 30 AND job_id < 90;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------
|
|
Append (cost=0.15..14.71 rows=16 width=24)
|
|
-> Index Scan using "11_2_jobs_serial_pkey" on _timescaledb_internal._hyper_4_11_chunk (cost=0.15..7.31 rows=8 width=24)
|
|
Output: _hyper_4_11_chunk.job_id, _hyper_4_11_chunk.device_id, _hyper_4_11_chunk.start_time, _hyper_4_11_chunk.end_time
|
|
Index Cond: ((_hyper_4_11_chunk.job_id >= 30) AND (_hyper_4_11_chunk.job_id < 90))
|
|
-> Index Scan using "12_3_jobs_serial_pkey" on _timescaledb_internal._hyper_4_12_chunk (cost=0.15..7.31 rows=8 width=24)
|
|
Output: _hyper_4_12_chunk.job_id, _hyper_4_12_chunk.device_id, _hyper_4_12_chunk.start_time, _hyper_4_12_chunk.end_time
|
|
Index Cond: ((_hyper_4_12_chunk.job_id >= 30) AND (_hyper_4_12_chunk.job_id < 90))
|
|
(7 rows)
|
|
|
|
EXPLAIN VERBOSE SELECT * FROM jobs_serial WHERE job_id > 90;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------
|
|
Append (cost=0.15..45.84 rows=1046 width=24)
|
|
-> Index Scan using "13_4_jobs_serial_pkey" on _timescaledb_internal._hyper_4_13_chunk (cost=0.15..20.30 rows=523 width=24)
|
|
Output: _hyper_4_13_chunk.job_id, _hyper_4_13_chunk.device_id, _hyper_4_13_chunk.start_time, _hyper_4_13_chunk.end_time
|
|
Index Cond: (_hyper_4_13_chunk.job_id > 90)
|
|
-> Index Scan using "14_5_jobs_serial_pkey" on _timescaledb_internal._hyper_4_14_chunk (cost=0.15..20.30 rows=523 width=24)
|
|
Output: _hyper_4_14_chunk.job_id, _hyper_4_14_chunk.device_id, _hyper_4_14_chunk.start_time, _hyper_4_14_chunk.end_time
|
|
Index Cond: (_hyper_4_14_chunk.job_id > 90)
|
|
(7 rows)
|
|
|
|
-- Update rows
|
|
UPDATE jobs_serial SET end_time = end_time + INTERVAL '1 hour' where job_id = 1;
|
|
UPDATE jobs_serial SET end_time = end_time + INTERVAL '1 hour' where job_id = 30;
|
|
UPDATE jobs_serial SET end_time = end_time + INTERVAL '1 hour' where job_id = 90;
|
|
SELECT start_time, end_time FROM jobs_serial WHERE job_id = 1;
|
|
start_time | end_time
|
|
------------------------------+------------------------------
|
|
Fri Mar 02 01:00:00 2018 PST | Sat Mar 03 02:00:00 2018 PST
|
|
(1 row)
|
|
|
|
SELECT start_time, end_time FROM jobs_serial WHERE job_id = 30;
|
|
start_time | end_time
|
|
------------------------------+------------------------------
|
|
Sat Mar 03 06:00:00 2018 PST | Sun Mar 04 07:00:00 2018 PST
|
|
(1 row)
|
|
|
|
SELECT start_time, end_time FROM jobs_serial WHERE job_id = 90;
|
|
start_time | end_time
|
|
------------------------------+------------------------------
|
|
Mon Mar 05 18:00:00 2018 PST | Tue Mar 06 19:00:00 2018 PST
|
|
(1 row)
|
|
|
|
-- Test delete rows
|
|
-- Existing tuple counts. We saves these and compare with the values
|
|
-- after running the delete.
|
|
CREATE TABLE counts AS SELECT
|
|
(SELECT count(*) FROM jobs_serial) AS total_count,
|
|
(SELECT count(*) FROM jobs_serial WHERE job_id < 10) AS remove_count;
|
|
-- Perform the delete
|
|
DELETE FROM jobs_serial WHERE job_id < 10;
|
|
-- Ensure only the intended tuples are deleted. The two counts should be equal.
|
|
SELECT
|
|
(SELECT total_count FROM counts) - (SELECT count(*) FROM jobs_serial) AS total_removed,
|
|
(SELECT remove_count FROM counts) - (SELECT count(*) FROM jobs_serial WHERE job_id < 10) AS matching_removed;
|
|
total_removed | matching_removed
|
|
---------------+------------------
|
|
9 | 9
|
|
(1 row)
|
|
|
|
DROP TABLE jobs_serial;
|
|
DROP TABLE counts;
|
|
-- Create and validate hypertable with BIGSERIAL column
|
|
CREATE TABLE jobs_big_serial (job_id BIGSERIAL, device_id INTEGER, start_time TIMESTAMPTZ, end_time TIMESTAMPTZ, PRIMARY KEY (job_id));
|
|
SELECT create_hypertable('jobs_big_serial', by_range('job_id', 100));
|
|
create_hypertable
|
|
-------------------
|
|
(5,t)
|
|
(1 row)
|
|
|
|
-- Insert data
|
|
INSERT INTO jobs_big_serial (device_id, start_time, end_time)
|
|
SELECT abs(timestamp_hash(t::timestamp)) % 10, t, t + INTERVAL '1 day'
|
|
FROM generate_series('2018-03-02 1:00'::TIMESTAMPTZ, '2018-03-08 1:00'::TIMESTAMPTZ,'30 mins')t;
|
|
-- Verify #chunks
|
|
SELECT count(*) FROM timescaledb_information.chunks;
|
|
count
|
|
-------
|
|
3
|
|
(1 row)
|
|
|
|
-- Get current sequence and verify updating sequence
|
|
SELECT currval(pg_get_serial_sequence('jobs_big_serial', 'job_id'));
|
|
currval
|
|
---------
|
|
289
|
|
(1 row)
|
|
|
|
-- Update sequence value to 500
|
|
SELECT setval(pg_get_serial_sequence('jobs_big_serial', 'job_id'), 500, false);
|
|
setval
|
|
--------
|
|
500
|
|
(1 row)
|
|
|
|
-- Insert few rows and verify that the next sequence starts from 500
|
|
INSERT INTO jobs_big_serial (device_id, start_time, end_time)
|
|
SELECT abs(timestamp_hash(t::timestamp)) % 10, t, t + INTERVAL '1 day'
|
|
FROM generate_series('2018-03-09 1:00'::TIMESTAMPTZ, '2018-03-10 1:00'::TIMESTAMPTZ,'30 mins')t;
|
|
-- No data should exist for job_id >= 290 to job_id < 500
|
|
SELECT count(*) FROM jobs_big_serial WHERE job_id >= 290 AND job_id < 500;
|
|
count
|
|
-------
|
|
0
|
|
(1 row)
|
|
|
|
-- The new rows should be added with job_id > 500
|
|
SELECT count(*) from jobs_big_serial WHERE job_id > 500;
|
|
count
|
|
-------
|
|
48
|
|
(1 row)
|
|
|
|
-- Verify show_chunks API
|
|
SELECT show_chunks('jobs_big_serial', older_than => 100);
|
|
show_chunks
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_5_15_chunk
|
|
(1 row)
|
|
|
|
SELECT show_chunks('jobs_big_serial', newer_than => 200, older_than => 300);
|
|
show_chunks
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_5_17_chunk
|
|
(1 row)
|
|
|
|
SELECT show_chunks('jobs_big_serial', newer_than => 500);
|
|
show_chunks
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_5_18_chunk
|
|
(1 row)
|
|
|
|
-- Verify drop_chunks API
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name = 'jobs_big_serial';
|
|
count
|
|
-------
|
|
4
|
|
(1 row)
|
|
|
|
SELECT drop_chunks('jobs_big_serial', newer_than => 500);
|
|
drop_chunks
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_5_18_chunk
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name = 'jobs_big_serial';
|
|
count
|
|
-------
|
|
3
|
|
(1 row)
|
|
|
|
SELECT drop_chunks('jobs_big_serial', newer_than => 200, older_than => 300);
|
|
drop_chunks
|
|
-----------------------------------------
|
|
_timescaledb_internal._hyper_5_17_chunk
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name = 'jobs_big_serial';
|
|
count
|
|
-------
|
|
2
|
|
(1 row)
|
|
|
|
DROP TABLE jobs_big_serial;
|
|
-- Verify partition function
|
|
CREATE TABLE test_table_int(id TEXT, device INTEGER, time TIMESTAMPTZ);
|
|
SELECT create_hypertable('test_table_int', by_range('id', 10, partition_func => 'part_func'));
|
|
NOTICE: adding not-null constraint to column "id"
|
|
create_hypertable
|
|
-------------------
|
|
(6,t)
|
|
(1 row)
|
|
|
|
INSERT INTO test_table_int VALUES('1', 1, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_int VALUES('10', 10, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
INSERT INTO test_table_int VALUES('29', 100, '01-01-2023 11:00'::TIMESTAMPTZ);
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name = 'test_table_int';
|
|
count
|
|
-------
|
|
3
|
|
(1 row)
|
|
|
|
DROP TABLE test_table_int;
|
|
DROP FUNCTION part_func;
|
|
-- Migrate data
|
|
CREATE TABLE test_table_int(id INTEGER, device INTEGER, time TIMESTAMPTZ);
|
|
INSERT INTO test_table_int SELECT t, t%10, '01-01-2023 11:00'::TIMESTAMPTZ FROM generate_series(1, 50, 1) t;
|
|
SELECT create_hypertable('test_table_int', by_range('id', 10), migrate_data => true);
|
|
NOTICE: adding not-null constraint to column "id"
|
|
NOTICE: migrating data to chunks
|
|
create_hypertable
|
|
-------------------
|
|
(7,t)
|
|
(1 row)
|
|
|
|
-- Show default indexes created for hypertables.
|
|
SELECT indexname FROM pg_indexes WHERE tablename = 'test_table_int';
|
|
indexname
|
|
-----------------------
|
|
test_table_int_id_idx
|
|
(1 row)
|
|
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name = 'test_table_int';
|
|
count
|
|
-------
|
|
6
|
|
(1 row)
|
|
|
|
DROP TABLE test_table_int;
|
|
-- create_hypertable without default indexes
|
|
CREATE TABLE test_table_int(id INTEGER, device INTEGER, time TIMESTAMPTZ);
|
|
SELECT create_hypertable('test_table_int', by_range('id', 10), create_default_indexes => false);
|
|
NOTICE: adding not-null constraint to column "id"
|
|
create_hypertable
|
|
-------------------
|
|
(8,t)
|
|
(1 row)
|
|
|
|
SELECT indexname FROM pg_indexes WHERE tablename = 'test_table_int';
|
|
indexname
|
|
-----------
|
|
(0 rows)
|
|
|
|
DROP TABLE test_table_int;
|
|
-- if_not_exists
|
|
CREATE TABLE test_table_int(id INTEGER, device INTEGER, time TIMESTAMPTZ);
|
|
SELECT create_hypertable('test_table_int', by_range('id', 10));
|
|
NOTICE: adding not-null constraint to column "id"
|
|
create_hypertable
|
|
-------------------
|
|
(9,t)
|
|
(1 row)
|
|
|
|
-- No error when if_not_exists => true
|
|
SELECT create_hypertable('test_table_int', by_range('id', 10), if_not_exists => true);
|
|
NOTICE: table "test_table_int" is already a hypertable, skipping
|
|
create_hypertable
|
|
-------------------
|
|
(9,f)
|
|
(1 row)
|
|
|
|
SELECT * FROM _timescaledb_functions.get_create_command('test_table_int');
|
|
get_create_command
|
|
--------------------------------------------------------------------------------------------------------------------
|
|
SELECT create_hypertable('public.test_table_int', 'id', chunk_time_interval => 10, create_default_indexes=>FALSE);
|
|
(1 row)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
-- Should throw an error when if_not_exists is not set
|
|
SELECT create_hypertable('test_table_int', by_range('id', 10));
|
|
ERROR: table "test_table_int" is already a hypertable
|
|
-- Should error out when hash partitioning is used as the main partitioning scheme
|
|
SELECT create_hypertable('test_table_int', by_hash('device', number_partitions => 2));
|
|
ERROR: cannot partition using a closed dimension on primary column
|
|
\set ON_ERROR_STOP 1
|
|
DROP TABLE test_table_int;
|
|
-- Add dimension
|
|
CREATE TABLE test_table_int(id INTEGER, device INTEGER, time TIMESTAMPTZ);
|
|
SELECT create_hypertable('test_table_int', by_range('id', 10), migrate_data => true);
|
|
NOTICE: adding not-null constraint to column "id"
|
|
create_hypertable
|
|
-------------------
|
|
(10,t)
|
|
(1 row)
|
|
|
|
INSERT INTO test_table_int SELECT t, t%10, '01-01-2023 11:00'::TIMESTAMPTZ FROM generate_series(1, 50, 1) t;
|
|
-- adding a space dimension via "by_hash" should work
|
|
SELECT add_dimension('test_table_int', by_hash('device', number_partitions => 2));
|
|
add_dimension
|
|
---------------
|
|
(11,t)
|
|
(1 row)
|
|
|
|
SELECT hypertable_name, dimension_number, column_name FROM timescaledb_information.dimensions WHERE hypertable_name = 'test_table_int';
|
|
hypertable_name | dimension_number | column_name
|
|
-----------------+------------------+-------------
|
|
test_table_int | 1 | id
|
|
test_table_int | 2 | device
|
|
(2 rows)
|
|
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name='test_table_int';
|
|
count
|
|
-------
|
|
6
|
|
(1 row)
|
|
|
|
SELECT set_partitioning_interval('test_table_int', 5, 'id');
|
|
set_partitioning_interval
|
|
---------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT set_number_partitions('test_table_int', 3, 'device');
|
|
set_number_partitions
|
|
-----------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT integer_interval, num_partitions
|
|
FROM timescaledb_information.dimensions
|
|
WHERE column_name in ('id', 'device');
|
|
integer_interval | num_partitions
|
|
------------------+----------------
|
|
5 |
|
|
| 3
|
|
(2 rows)
|
|
|
|
DROP TABLE test_table_int;
|
|
-- Hypertable with time dimension using new API
|
|
CREATE TABLE test_time(time TIMESTAMP NOT NULL, device INT, temp FLOAT);
|
|
SELECT create_hypertable('test_time', by_range('time'));
|
|
WARNING: column type "timestamp without time zone" used for "time" does not follow best practices
|
|
create_hypertable
|
|
-------------------
|
|
(11,t)
|
|
(1 row)
|
|
|
|
-- Default interval
|
|
SELECT time_interval FROM timescaledb_information.dimensions WHERE hypertable_name = 'test_time';
|
|
time_interval
|
|
---------------
|
|
@ 7 days
|
|
(1 row)
|
|
|
|
INSERT INTO test_time SELECT t, (abs(timestamp_hash(t::timestamp)) % 10) + 1, 0.10 FROM generate_series('2018-03-02 1:00'::TIMESTAMPTZ, '2018-03-08 1:00', '1 hour') t;
|
|
SELECT count(*) FROM timescaledb_information.chunks WHERE hypertable_name='test_time';
|
|
count
|
|
-------
|
|
2
|
|
(1 row)
|
|
|
|
SELECT add_dimension('test_time', by_range('device', partition_interval => 2));
|
|
NOTICE: adding not-null constraint to column "device"
|
|
add_dimension
|
|
---------------
|
|
(13,t)
|
|
(1 row)
|
|
|
|
SELECT hypertable_name, dimension_number, column_name FROM timescaledb_information.dimensions WHERE hypertable_name = 'test_time';
|
|
hypertable_name | dimension_number | column_name
|
|
-----------------+------------------+-------------
|
|
test_time | 1 | time
|
|
test_time | 2 | device
|
|
(2 rows)
|
|
|
|
SELECT set_partitioning_interval('test_time', INTERVAL '1 day', 'time');
|
|
set_partitioning_interval
|
|
---------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT time_interval FROM timescaledb_information.dimensions WHERE hypertable_name = 'test_time' AND column_name = 'time';
|
|
time_interval
|
|
---------------
|
|
@ 1 day
|
|
(1 row)
|
|
|
|
DROP TABLE test_time;
|