Skip to content

Commit 5c533a3

Browse files
committed
Add compatibility API for OSM
Add some helper function to decouple OSM from direct catalog access: _timescaledb_functions.get_hypertable_info _timescaledb_functions.get_primary_dimension _timescaledb_functions.get_chunk_info _timescaledb_functions.get_chunk_info_by_id _timescaledb_functions.get_chunk_primary_range _timescaledb_functions.get_chunk_primary_range_by_id
1 parent 18e3468 commit 5c533a3

6 files changed

Lines changed: 268 additions & 3 deletions

File tree

sql/osm_api.sql

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,65 @@ CREATE OR REPLACE FUNCTION _timescaledb_functions.lock_osm_chunk_dimension_slice
2121
htoid REGCLASS
2222
) RETURNS VOID AS '@MODULE_PATHNAME@',
2323
'ts_lock_osm_chunk_dimension_slice' LANGUAGE C VOLATILE;
24+
25+
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_hypertable_info(IN relation REGCLASS, OUT hypertable_id INTEGER, OUT schema_name name, OUT table_name name, OUT is_cagg BOOLEAN) AS $$
26+
SELECT ht.id, ht.schema_name, ht.table_name, false AS is_cagg
27+
FROM _timescaledb_catalog.hypertable ht
28+
JOIN pg_class c ON ht.table_name = c.relname AND ht.schema_name = c.relnamespace::regnamespace::name AND c.oid = relation
29+
UNION ALL
30+
SELECT ht.id, ht.schema_name, ht.table_name, true AS is_cagg
31+
FROM _timescaledb_catalog.continuous_agg cagg
32+
JOIN pg_class c ON cagg.user_view_name = c.relname AND cagg.user_view_schema = c.relnamespace::regnamespace::name AND c.oid = relation
33+
JOIN _timescaledb_catalog.hypertable ht ON ht.id=cagg.mat_hypertable_id;
34+
$$ LANGUAGE SQL STABLE SET search_path = pg_catalog, pg_temp;
35+
36+
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_primary_dimension(IN hypertable_id INTEGER, OUT column_name NAME, OUT column_type REGTYPE, OUT integer_now_func regproc) AS $$
37+
SELECT
38+
d.column_name,
39+
d.column_type,
40+
CASE WHEN integer_now_func_schema IS NOT NULL AND integer_now_func IS NOT NULL THEN to_regproc(format('%I.%I',integer_now_func_schema,integer_now_func)) END AS integer_now
41+
FROM _timescaledb_catalog.dimension d
42+
LEFT JOIN _timescaledb_catalog.continuous_agg cagg ON cagg.mat_hypertable_id = $1
43+
WHERE d.hypertable_id = COALESCE(cagg.raw_hypertable_id, $1) ORDER BY d.id LIMIT 1;
44+
$$ LANGUAGE SQL STABLE SET search_path = pg_catalog, pg_temp;
45+
46+
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_chunk_info(IN chunk REGCLASS, OUT chunk_id INTEGER, OUT hypertable_id INTEGER, OUT ht_schema_name NAME, OUT ht_table_name NAME, OUT chunk_schema NAME, OUT chunk_name NAME, OUT is_osm_chunk BOOLEAN, OUT is_frozen BOOLEAN) AS $$
47+
SELECT
48+
ch.id AS chunk_id,
49+
ch.hypertable_id, ht.schema_name AS ht_schema_name, ht.table_name AS ht_table_name,
50+
ch.schema_name AS chunk_schema, ch.table_name AS chunk_name,
51+
ch.osm_chunk AS is_osm_chunk,
52+
(ch.status & 4)::bool AS is_frozen
53+
FROM _timescaledb_catalog.chunk ch
54+
JOIN pg_class c ON c.oid=$1 AND ch.table_name=c.relname AND ch.schema_name = c.relnamespace::regnamespace::name
55+
JOIN _timescaledb_catalog.hypertable ht ON ht.id=ch.hypertable_id;
56+
$$ LANGUAGE SQL STABLE SET search_path = pg_catalog, pg_temp;
57+
58+
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_chunk_info_by_id(IN chunk_id INTEGER, OUT chunk_id INTEGER, OUT hypertable_id INTEGER, OUT ht_schema_name NAME, OUT ht_table_name NAME, OUT chunk_schema NAME, OUT chunk_name NAME, OUT is_osm_chunk BOOLEAN, OUT is_frozen BOOLEAN) AS $$
59+
SELECT
60+
ch.id AS chunk_id,
61+
ch.hypertable_id, ht.schema_name AS ht_schema_name, ht.table_name AS ht_table_name,
62+
ch.schema_name AS chunk_schema, ch.table_name AS chunk_name,
63+
ch.osm_chunk AS is_osm_chunk,
64+
(ch.status & 4)::bool AS is_frozen
65+
FROM _timescaledb_catalog.chunk ch
66+
JOIN _timescaledb_catalog.hypertable ht ON ht.id=ch.hypertable_id
67+
WHERE ch.id = $1;
68+
$$ LANGUAGE SQL STABLE SET search_path = pg_catalog, pg_temp;
69+
70+
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_chunk_primary_range(IN chunk REGCLASS, OUT range_start BIGINT, OUT range_end BIGINT)
71+
AS $$
72+
SELECT range_start, range_end
73+
FROM _timescaledb_catalog.dimension_slice d
74+
JOIN _timescaledb_catalog.chunk ch ON ch.id = d.chunk_id
75+
JOIN pg_class c ON c.oid=$1 AND ch.table_name=c.relname AND ch.schema_name = c.relnamespace::regnamespace::name
76+
ORDER BY dimension_id LIMIT 1;
77+
$$ LANGUAGE SQL STABLE SET search_path = pg_catalog, pg_temp;
78+
79+
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_chunk_primary_range_by_id(IN chunk_id INTEGER, OUT range_start BIGINT, OUT range_end BIGINT)
80+
AS $$
81+
SELECT range_start, range_end
82+
FROM _timescaledb_catalog.dimension_slice d
83+
WHERE chunk_id = $1 ORDER BY dimension_id LIMIT 1;
84+
$$ LANGUAGE SQL STABLE SET search_path = pg_catalog, pg_temp;
85+

sql/updates/reverse-dev.sql

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ $$;
2020
DROP VIEW IF EXISTS _timescaledb_catalog.chunk_constraint;
2121
DROP FUNCTION IF EXISTS _timescaledb_functions.chunk_constraint_add_table_constraint( integer, name, name);
2222

23-
DROP FUNCTION IF EXISTS _timescaledb_functions.lock_osm_chunk_dimension_slice(regclass);
24-
2523
ALTER TABLE _timescaledb_catalog.hypertable RESET (user_catalog_table);
2624
ALTER TABLE _timescaledb_catalog.chunk RESET (user_catalog_table);
2725

@@ -193,7 +191,7 @@ DROP FUNCTION IF EXISTS _timescaledb_functions.chunk_statistics_reset();
193191

194192
DROP FUNCTION IF EXISTS @extschema@.create_hypertable(relation REGCLASS, time_column_name NAME, partitioning_column NAME, number_partitions INTEGER, associated_schema_name NAME, associated_table_prefix NAME, chunk_time_interval ANYELEMENT, create_default_indexes BOOLEAN, if_not_exists BOOLEAN, partitioning_func REGPROC, migrate_data BOOLEAN, time_partitioning_func REGPROC);
195193

196-
-- Restore the chunk_target_size check constraint dropped in the forward path.
194+
-- Restore the chunk_target_size check constraint
197195
ALTER TABLE _timescaledb_catalog.hypertable
198196
ADD CONSTRAINT hypertable_chunk_target_size_check CHECK (chunk_target_size >= 0);
199197

@@ -293,3 +291,11 @@ CREATE TABLE _timescaledb_catalog.telemetry_event (
293291
);
294292
GRANT SELECT ON _timescaledb_catalog.telemetry_event TO PUBLIC;
295293

294+
DROP FUNCTION IF EXISTS _timescaledb_functions.get_hypertable_info;
295+
DROP FUNCTION IF EXISTS _timescaledb_functions.get_primary_dimension;
296+
DROP FUNCTION IF EXISTS _timescaledb_functions.get_chunk_info;
297+
DROP FUNCTION IF EXISTS _timescaledb_functions.get_chunk_info_by_id;
298+
DROP FUNCTION IF EXISTS _timescaledb_functions.get_chunk_primary_range;
299+
DROP FUNCTION IF EXISTS _timescaledb_functions.get_chunk_primary_range_by_id;
300+
DROP FUNCTION IF EXISTS _timescaledb_functions.lock_osm_chunk_dimension_slice(regclass);
301+

tsl/test/shared/expected/extension.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,15 @@ ORDER BY pronamespace::regnamespace::text COLLATE "C", p.oid::regprocedure::text
6969
_timescaledb_functions.freeze_chunk(regclass)
7070
_timescaledb_functions.generate_uuid()
7171
_timescaledb_functions.get_approx_row_count(regclass)
72+
_timescaledb_functions.get_chunk_id(name,name)
73+
_timescaledb_functions.get_chunk_id(regclass)
74+
_timescaledb_functions.get_chunk_name(integer)
7275
_timescaledb_functions.get_compressed_chunk_index_for_recompression(regclass)
7376
_timescaledb_functions.get_create_command(name)
7477
_timescaledb_functions.get_git_commit()
78+
_timescaledb_functions.get_hypertable_id(name,name)
79+
_timescaledb_functions.get_hypertable_id(regclass)
80+
_timescaledb_functions.get_hypertable_name(integer)
7581
_timescaledb_functions.get_internal_time_max(regtype)
7682
_timescaledb_functions.get_internal_time_min(regtype)
7783
_timescaledb_functions.get_orderby_defaults(regclass,text[])
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
-- This file and its contents are licensed under the Timescale License.
2+
-- Please see the included NOTICE for copyright information and
3+
-- LICENSE-TIMESCALE for a copy of the license.
4+
\pset null '<NULL>'
5+
SELECT * FROM _timescaledb_functions.get_hypertable_info('public.metrics'::regclass);
6+
hypertable_id | schema_name | table_name | is_cagg
7+
---------------+-------------+------------+---------
8+
1 | public | metrics | f
9+
10+
SELECT * FROM _timescaledb_functions.get_hypertable_info('public.hourly_device_metrics'::regclass);
11+
hypertable_id | schema_name | table_name | is_cagg
12+
---------------+-----------------------+----------------------------+---------
13+
8 | _timescaledb_internal | _materialized_hypertable_X | t
14+
15+
SELECT * FROM _timescaledb_functions.get_hypertable_info(NULL);
16+
hypertable_id | schema_name | table_name | is_cagg
17+
---------------+-------------+------------+---------
18+
<NULL> | <NULL> | <NULL> | <NULL>
19+
20+
SELECT * FROM _timescaledb_functions.get_hypertable_info(0);
21+
hypertable_id | schema_name | table_name | is_cagg
22+
---------------+-------------+------------+---------
23+
<NULL> | <NULL> | <NULL> | <NULL>
24+
25+
SELECT * FROM _timescaledb_functions.get_hypertable_info('pg_catalog.pg_class'::regclass);
26+
hypertable_id | schema_name | table_name | is_cagg
27+
---------------+-------------+------------+---------
28+
<NULL> | <NULL> | <NULL> | <NULL>
29+
30+
SELECT * FROM _timescaledb_functions.get_primary_dimension(1);
31+
column_name | column_type | integer_now_func
32+
-------------+--------------------------+------------------
33+
time | timestamp with time zone | <NULL>
34+
35+
SELECT * FROM _timescaledb_functions.get_primary_dimension(8);
36+
column_name | column_type | integer_now_func
37+
-------------+--------------------------+------------------
38+
time | timestamp with time zone | <NULL>
39+
40+
SELECT * FROM _timescaledb_functions.get_primary_dimension(0);
41+
column_name | column_type | integer_now_func
42+
-------------+-------------+------------------
43+
<NULL> | <NULL> | <NULL>
44+
45+
SELECT * FROM _timescaledb_functions.get_primary_dimension(NULL);
46+
column_name | column_type | integer_now_func
47+
-------------+-------------+------------------
48+
<NULL> | <NULL> | <NULL>
49+
50+
SELECT * FROM _timescaledb_functions.get_chunk_info('_timescaledb_internal._hyper_X_X_chunk');
51+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
52+
----------+---------------+----------------+---------------+-----------------------+------------------+--------------+-----------
53+
3 | 1 | public | metrics | _timescaledb_internal | _hyper_X_X_chunk | f | f
54+
55+
SELECT * FROM _timescaledb_functions.get_chunk_info('_timescaledb_internal._hyper_X_X_chunk'::regclass);
56+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
57+
----------+---------------+----------------+---------------+-----------------------+------------------+--------------+-----------
58+
3 | 1 | public | metrics | _timescaledb_internal | _hyper_X_X_chunk | f | f
59+
60+
SELECT * FROM _timescaledb_functions.get_chunk_info(0);
61+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
62+
----------+---------------+----------------+---------------+--------------+------------+--------------+-----------
63+
<NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL>
64+
65+
SELECT * FROM _timescaledb_functions.get_chunk_info(NULL);
66+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
67+
----------+---------------+----------------+---------------+--------------+------------+--------------+-----------
68+
<NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL>
69+
70+
SELECT * FROM _timescaledb_functions.get_chunk_info('pg_catalog.pg_class'::regclass);
71+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
72+
----------+---------------+----------------+---------------+--------------+------------+--------------+-----------
73+
<NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL>
74+
75+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(3);
76+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
77+
----------+---------------+----------------+---------------+-----------------------+------------------+--------------+-----------
78+
3 | 1 | public | metrics | _timescaledb_internal | _hyper_X_X_chunk | f | f
79+
80+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(38);
81+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
82+
----------+---------------+-----------------------+----------------------------+-----------------------+-------------------+--------------+-----------
83+
38 | 8 | _timescaledb_internal | _materialized_hypertable_X | _timescaledb_internal | _hyper_X_X_chunk | f | f
84+
85+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(0);
86+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
87+
----------+---------------+----------------+---------------+--------------+------------+--------------+-----------
88+
<NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL>
89+
90+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(-1);
91+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
92+
----------+---------------+----------------+---------------+--------------+------------+--------------+-----------
93+
<NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL>
94+
95+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(NULL);
96+
chunk_id | hypertable_id | ht_schema_name | ht_table_name | chunk_schema | chunk_name | is_osm_chunk | is_frozen
97+
----------+---------------+----------------+---------------+--------------+------------+--------------+-----------
98+
<NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL> | <NULL>
99+
100+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range('_timescaledb_internal._hyper_X_X_chunk'::regclass);
101+
range_start | range_end
102+
-----------------+-----------------
103+
947721600000000 | 948326400000000
104+
105+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range(0::regclass);
106+
range_start | range_end
107+
-------------+-----------
108+
<NULL> | <NULL>
109+
110+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range(1::regclass);
111+
range_start | range_end
112+
-------------+-----------
113+
<NULL> | <NULL>
114+
115+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range('pg_catalog.pg_class'::regclass);
116+
range_start | range_end
117+
-------------+-----------
118+
<NULL> | <NULL>
119+
120+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range(NULL::regclass);
121+
range_start | range_end
122+
-------------+-----------
123+
<NULL> | <NULL>
124+
125+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(3);
126+
range_start | range_end
127+
-----------------+-----------------
128+
947721600000000 | 948326400000000
129+
130+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(38);
131+
range_start | range_end
132+
-----------------+-----------------
133+
943488000000000 | 949536000000000
134+
135+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(0::int);
136+
range_start | range_end
137+
-------------+-----------
138+
<NULL> | <NULL>
139+
140+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(-1::int);
141+
range_start | range_end
142+
-------------+-----------
143+
<NULL> | <NULL>
144+
145+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(NULL::int);
146+
range_start | range_end
147+
-------------+-----------
148+
<NULL> | <NULL>
149+

tsl/test/shared/sql/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ set(TEST_FILES_SHARED
1313
gapfill_bug.sql
1414
generated_columns.sql
1515
memoize.sql
16+
osm_api.sql
1617
parameterized_chunkappend.sql
1718
security_barrier.sql
1819
subtract_integer_from_now.sql)

tsl/test/shared/sql/osm_api.sql

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
-- This file and its contents are licensed under the Timescale License.
2+
-- Please see the included NOTICE for copyright information and
3+
-- LICENSE-TIMESCALE for a copy of the license.
4+
5+
\pset null '<NULL>'
6+
7+
SELECT * FROM _timescaledb_functions.get_hypertable_info('public.metrics'::regclass);
8+
SELECT * FROM _timescaledb_functions.get_hypertable_info('public.hourly_device_metrics'::regclass);
9+
SELECT * FROM _timescaledb_functions.get_hypertable_info(NULL);
10+
SELECT * FROM _timescaledb_functions.get_hypertable_info(0);
11+
SELECT * FROM _timescaledb_functions.get_hypertable_info('pg_catalog.pg_class'::regclass);
12+
13+
SELECT * FROM _timescaledb_functions.get_primary_dimension(1);
14+
SELECT * FROM _timescaledb_functions.get_primary_dimension(8);
15+
SELECT * FROM _timescaledb_functions.get_primary_dimension(0);
16+
SELECT * FROM _timescaledb_functions.get_primary_dimension(NULL);
17+
18+
SELECT * FROM _timescaledb_functions.get_chunk_info('_timescaledb_internal._hyper_1_3_chunk');
19+
SELECT * FROM _timescaledb_functions.get_chunk_info('_timescaledb_internal._hyper_1_3_chunk'::regclass);
20+
SELECT * FROM _timescaledb_functions.get_chunk_info(0);
21+
SELECT * FROM _timescaledb_functions.get_chunk_info(NULL);
22+
SELECT * FROM _timescaledb_functions.get_chunk_info('pg_catalog.pg_class'::regclass);
23+
24+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(3);
25+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(38);
26+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(0);
27+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(-1);
28+
SELECT * FROM _timescaledb_functions.get_chunk_info_by_id(NULL);
29+
30+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range('_timescaledb_internal._hyper_1_3_chunk'::regclass);
31+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range(0::regclass);
32+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range(1::regclass);
33+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range('pg_catalog.pg_class'::regclass);
34+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range(NULL::regclass);
35+
36+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(3);
37+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(38);
38+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(0::int);
39+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(-1::int);
40+
SELECT * FROM _timescaledb_functions.get_chunk_primary_range_by_id(NULL::int);
41+

0 commit comments

Comments
 (0)