diff --git a/sql/views.sql b/sql/views.sql index af3bd144d..8e205741b 100644 --- a/sql/views.sql +++ b/sql/views.sql @@ -259,6 +259,125 @@ CREATE OR REPLACE VIEW timescaledb_information.data_node AS LEFT OUTER JOIN LATERAL @extschema@.data_node_hypertable_info(CASE WHEN s.node_up THEN s.node_name ELSE NULL END) size ON TRUE GROUP BY s.node_name, s.node_up, s.owner, s.options; +-- chunks metadata view, shows information about the primary dimension column +-- query plans with CTEs are not always optimized by PG. So use in-line +-- tables. +CREATE OR REPLACE VIEW timescaledb_information.chunks +AS +SELECT + hypertable_schema, hypertable_name, + schema_name as chunk_schema , chunk_name , + primary_dimension, primary_dimension_type, + range_start, range_end, + integer_range_start as range_start_integer, + integer_range_end as range_end_integer, + is_compressed, + chunk_table_space as chunk_tablespace, + node_list as data_nodes + from +( +SELECT + ht.schema_name as hypertable_schema, + ht.table_name as hypertable_name, + srcch.schema_name as schema_name, + srcch.table_name as chunk_name, + dim.column_name as primary_dimension, + dim.column_type as primary_dimension_type, + row_number() over(partition by chcons.chunk_id order by chcons.dimension_slice_id) as chunk_dimension_num, + CASE + WHEN ( dim.column_type = 'TIMESTAMP'::regtype OR + dim.column_type = 'TIMESTAMPTZ'::regtype OR + dim.column_type = 'DATE'::regtype ) + THEN _timescaledb_internal.to_timestamp(dimsl.range_start) + ELSE NULL + END as range_start, + CASE + WHEN ( dim.column_type = 'TIMESTAMP'::regtype OR + dim.column_type = 'TIMESTAMPTZ'::regtype OR + dim.column_type = 'DATE'::regtype ) + THEN _timescaledb_internal.to_timestamp(dimsl.range_end) + ELSE NULL + END as range_end, + CASE + WHEN ( dim.column_type = 'TIMESTAMP'::regtype OR + dim.column_type = 'TIMESTAMPTZ'::regtype OR + dim.column_type = 'DATE'::regtype ) + THEN NULL + ELSE dimsl.range_start + END as integer_range_start, + CASE + WHEN ( dim.column_type = 'TIMESTAMP'::regtype OR + dim.column_type = 'TIMESTAMPTZ'::regtype OR + dim.column_type = 'DATE'::regtype ) + THEN NULL + ELSE dimsl.range_end + END as integer_range_end, + CASE WHEN srcch.compressed_chunk_id is not null THEN 'true' + ELSE 'false' + END as is_compressed, + pgtab.spcname as chunk_table_space, + chdn.node_list +FROM _timescaledb_catalog.chunk srcch + INNER JOIN _timescaledb_catalog.hypertable ht ON ht.id = srcch.hypertable_id + INNER JOIN _timescaledb_catalog.chunk_constraint chcons ON srcch.id = chcons.chunk_id + INNER JOIN _timescaledb_catalog.dimension dim ON srcch.hypertable_id = dim.hypertable_id + INNER JOIN _timescaledb_catalog.dimension_slice dimsl ON dim.id = dimsl.dimension_id + and chcons.dimension_slice_id = dimsl.id + INNER JOIN + ( SELECT relname, reltablespace, nspname as schema_name + FROM pg_class , pg_namespace WHERE + pg_class.relnamespace = pg_namespace.oid) cl + ON srcch.table_name = cl.relname and srcch.schema_name = cl.schema_name + LEFT OUTER JOIN pg_tablespace pgtab ON pgtab.oid = reltablespace + left outer join ( + SELECT chunk_id, array_agg(node_name ORDER BY node_name) as node_list + FROM _timescaledb_catalog.chunk_data_node + GROUP BY chunk_id) chdn + ON srcch.id = chdn.chunk_id + WHERE srcch.dropped is false + and ht.compressed = false ) finalq +WHERE chunk_dimension_num = 1 +; + +-- hypertable's dimension information +-- CTEs aren't used in the query as PG does not always optimize them +-- as expected. +CREATE OR REPLACE VIEW timescaledb_information.dimensions +AS +SELECT + ht.schema_name as hypertable_schema, + ht.table_name as hypertable_name, + rank() over(partition by hypertable_id order by dim.id) as dimension_number, + dim.column_name, + dim.column_type, + CASE WHEN dim.interval_length is NULL + THEN 'Space' + ELSE 'Time' + END as dimension_type, + CASE WHEN dim.interval_length is NOT NULL THEN + CASE + WHEN dim.column_type = 'TIMESTAMP'::regtype OR + dim.column_type = 'TIMESTAMPTZ'::regtype OR + dim.column_type = 'DATE'::regtype + THEN _timescaledb_internal.to_interval(dim.interval_length) + ELSE NULL + END + END as time_interval, + CASE WHEN dim.interval_length is NOT NULL THEN + CASE + WHEN dim.column_type = 'TIMESTAMP'::regtype OR + dim.column_type = 'TIMESTAMPTZ'::regtype OR + dim.column_type = 'DATE'::regtype + THEN NULL + ELSE dim.interval_length + END + END as integer_interval, + dim.integer_now_func, + dim.num_slices as num_partitions +FROM _timescaledb_catalog.hypertable ht, _timescaledb_catalog.dimension dim +WHERE dim.hypertable_id = ht.id +; + ---compression parameters information --- CREATE VIEW timescaledb_information.compression_settings AS @@ -284,3 +403,5 @@ ORDER BY GRANT USAGE ON SCHEMA timescaledb_information TO PUBLIC; GRANT SELECT ON ALL TABLES IN SCHEMA timescaledb_information TO PUBLIC; + + diff --git a/test/expected/pg_dump.out b/test/expected/pg_dump.out index c5255cd3e..70a58b538 100644 --- a/test/expected/pg_dump.out +++ b/test/expected/pg_dump.out @@ -536,6 +536,8 @@ WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND objid ----------------------------------------------------- timescaledb_information.compression_settings + timescaledb_information.dimensions + timescaledb_information.chunks timescaledb_information.data_node timescaledb_information.compressed_hypertable_stats timescaledb_information.compressed_chunk_stats @@ -551,7 +553,7 @@ WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND _timescaledb_internal.bgw_policy_chunk_stats _timescaledb_internal.bgw_job_stat _timescaledb_catalog.tablespace_id_seq -(16 rows) +(18 rows) -- Make sure we can't run our restoring functions as a normal perm user as that would disable functionality for the whole db \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER diff --git a/test/expected/views.out b/test/expected/views.out index 19e44e94a..c2c527719 100644 --- a/test/expected/views.out +++ b/test/expected/views.out @@ -96,3 +96,93 @@ SELECT * FROM timescaledb_information.hypertable WHERE table_owner = 'super_user open | open_ht | super_user | 1 | 3 | 24 kB | 48 kB | | 72 kB | f (2 rows) +---Add integer table -- +CREATE TABLE test_table_int(time bigint, junk int); +SELECT create_hypertable('test_table_int', 'time', chunk_time_interval => 10); +NOTICE: adding not-null constraint to column "time" + create_hypertable +----------------------------- + (5,public,test_table_int,t) +(1 row) + +CREATE OR REPLACE function table_int_now() returns BIGINT LANGUAGE SQL IMMUTABLE as 'SELECT 1::BIGINT'; +SELECT set_integer_now_func('test_table_int', 'table_int_now'); + set_integer_now_func +---------------------- + +(1 row) + +INSERT into test_table_int SELECT generate_series( 1, 20), 100; + SELECT * FROM timescaledb_information.chunks WHERE hypertable_name = 'ht1' ORDER BY chunk_name; + hypertable_schema | hypertable_name | chunk_schema | chunk_name | primary_dimension | primary_dimension_type | range_start | range_end | range_start_integer | range_end_integer | is_compressed | chunk_tablespace | data_nodes +-------------------+-----------------+-----------------------+------------------+-------------------+--------------------------+------------------------------+------------------------------+---------------------+-------------------+---------------+------------------+------------ + public | ht1 | _timescaledb_internal | _hyper_1_1_chunk | time | timestamp with time zone | Wed Dec 29 16:00:00 1999 PST | Wed Jan 05 16:00:00 2000 PST | | | false | | +(1 row) + + SELECT * FROM timescaledb_information.chunks WHERE hypertable_name = 'test_table_int' ORDER BY chunk_name; + hypertable_schema | hypertable_name | chunk_schema | chunk_name | primary_dimension | primary_dimension_type | range_start | range_end | range_start_integer | range_end_integer | is_compressed | chunk_tablespace | data_nodes +-------------------+-----------------+-----------------------+------------------+-------------------+------------------------+-------------+-----------+---------------------+-------------------+---------------+------------------+------------ + public | test_table_int | _timescaledb_internal | _hyper_5_7_chunk | time | bigint | | | 0 | 10 | false | | + public | test_table_int | _timescaledb_internal | _hyper_5_8_chunk | time | bigint | | | 10 | 20 | false | | + public | test_table_int | _timescaledb_internal | _hyper_5_9_chunk | time | bigint | | | 20 | 30 | false | | +(3 rows) + +\x +SELECT * FROM timescaledb_information.dimensions ORDER BY hypertable_name, dimension_number; +-[ RECORD 1 ]-----+------------------------- +hypertable_schema | closed +hypertable_name | closed_ht +dimension_number | 1 +column_name | time +column_type | timestamp with time zone +dimension_type | Time +time_interval | @ 7 days +integer_interval | +integer_now_func | +num_partitions | +-[ RECORD 2 ]-----+------------------------- +hypertable_schema | public +hypertable_name | ht1 +dimension_number | 1 +column_name | time +column_type | timestamp with time zone +dimension_type | Time +time_interval | @ 7 days +integer_interval | +integer_now_func | +num_partitions | +-[ RECORD 3 ]-----+------------------------- +hypertable_schema | public +hypertable_name | ht2 +dimension_number | 1 +column_name | time +column_type | timestamp with time zone +dimension_type | Time +time_interval | @ 7 days +integer_interval | +integer_now_func | +num_partitions | +-[ RECORD 4 ]-----+------------------------- +hypertable_schema | open +hypertable_name | open_ht +dimension_number | 1 +column_name | time +column_type | timestamp with time zone +dimension_type | Time +time_interval | @ 7 days +integer_interval | +integer_now_func | +num_partitions | +-[ RECORD 5 ]-----+------------------------- +hypertable_schema | public +hypertable_name | test_table_int +dimension_number | 1 +column_name | time +column_type | bigint +dimension_type | Time +time_interval | +integer_interval | 10 +integer_now_func | table_int_now +num_partitions | + +\x diff --git a/test/sql/views.sql b/test/sql/views.sql index 5a43c22b2..e54bb9bdb 100644 --- a/test/sql/views.sql +++ b/test/sql/views.sql @@ -46,3 +46,17 @@ SELECT * FROM timescaledb_information.hypertable WHERE table_name = 'ht1' ORDER -- filter by owner SELECT * FROM timescaledb_information.hypertable WHERE table_owner = 'super_user' ORDER BY table_schema,table_name; + +---Add integer table -- +CREATE TABLE test_table_int(time bigint, junk int); +SELECT create_hypertable('test_table_int', 'time', chunk_time_interval => 10); +CREATE OR REPLACE function table_int_now() returns BIGINT LANGUAGE SQL IMMUTABLE as 'SELECT 1::BIGINT'; +SELECT set_integer_now_func('test_table_int', 'table_int_now'); +INSERT into test_table_int SELECT generate_series( 1, 20), 100; + + SELECT * FROM timescaledb_information.chunks WHERE hypertable_name = 'ht1' ORDER BY chunk_name; + SELECT * FROM timescaledb_information.chunks WHERE hypertable_name = 'test_table_int' ORDER BY chunk_name; + +\x +SELECT * FROM timescaledb_information.dimensions ORDER BY hypertable_name, dimension_number; +\x diff --git a/tsl/test/expected/dist_compression.out b/tsl/test/expected/dist_compression.out index 4f669bf7e..8906a707a 100644 --- a/tsl/test/expected/dist_compression.out +++ b/tsl/test/expected/dist_compression.out @@ -394,3 +394,74 @@ NOTICE: chunk "_dist_hyper_1_1_chunk" is not compressed (1 row) +\x +SELECT * from timescaledb_information.chunks +ORDER BY hypertable_name, chunk_name; +-[ RECORD 1 ]----------+----------------------------- +hypertable_schema | public +hypertable_name | compressed +chunk_schema | _timescaledb_internal +chunk_name | _dist_hyper_1_1_chunk +primary_dimension | time +primary_dimension_type | timestamp with time zone +range_start | Wed Feb 28 16:00:00 2018 PST +range_end | Wed Mar 07 16:00:00 2018 PST +range_start_integer | +range_end_integer | +is_compressed | false +chunk_tablespace | +data_nodes | {data_node_1,data_node_2} +-[ RECORD 2 ]----------+----------------------------- +hypertable_schema | public +hypertable_name | compressed +chunk_schema | _timescaledb_internal +chunk_name | _dist_hyper_1_2_chunk +primary_dimension | time +primary_dimension_type | timestamp with time zone +range_start | Wed Feb 28 16:00:00 2018 PST +range_end | Wed Mar 07 16:00:00 2018 PST +range_start_integer | +range_end_integer | +is_compressed | false +chunk_tablespace | +data_nodes | {data_node_2,data_node_3} +-[ RECORD 3 ]----------+----------------------------- +hypertable_schema | public +hypertable_name | compressed +chunk_schema | _timescaledb_internal +chunk_name | _dist_hyper_1_3_chunk +primary_dimension | time +primary_dimension_type | timestamp with time zone +range_start | Wed Feb 28 16:00:00 2018 PST +range_end | Wed Mar 07 16:00:00 2018 PST +range_start_integer | +range_end_integer | +is_compressed | false +chunk_tablespace | +data_nodes | {data_node_1,data_node_3} + +SELECT * from timescaledb_information.dimensions +ORDER BY hypertable_name, dimension_number; +-[ RECORD 1 ]-----+------------------------- +hypertable_schema | public +hypertable_name | compressed +dimension_number | 1 +column_name | time +column_type | timestamp with time zone +dimension_type | Time +time_interval | @ 7 days +integer_interval | +integer_now_func | +num_partitions | +-[ RECORD 2 ]-----+------------------------- +hypertable_schema | public +hypertable_name | compressed +dimension_number | 2 +column_name | device +column_type | integer +dimension_type | Space +time_interval | +integer_interval | +integer_now_func | +num_partitions | 3 + diff --git a/tsl/test/sql/dist_compression.sql b/tsl/test/sql/dist_compression.sql index 0aefa798f..64d8b58c0 100644 --- a/tsl/test/sql/dist_compression.sql +++ b/tsl/test/sql/dist_compression.sql @@ -106,3 +106,9 @@ SELECT decompress_chunk(chunk, if_compressed => true) FROM show_chunks('compressed') AS chunk ORDER BY chunk LIMIT 1; + +\x +SELECT * from timescaledb_information.chunks +ORDER BY hypertable_name, chunk_name; +SELECT * from timescaledb_information.dimensions +ORDER BY hypertable_name, dimension_number;