Skip to content

Commit 9a34028

Browse files
Ngalstyan4cevian
authored andcommitted
Implement show_chunks in C and have drop_chunks use it
Timescale provides an efficient and easy to use api to drop individual chunks from timescale database through drop_chunks. This PR builds on that functionality and through a new show_chunks function gives the opportunity to see the chunks that would be dropped if drop_chunks was run. Additionally, it adds a newer_than option to drop_chunks (also supported by show_chunks) that allows to see/drop chunks in an interval or newer than a point in time. This commit includes: - Implementation of show_chunks in C - Additional helper functions to work with chunks - New version of drop_chunks in sql that uses show_chunks. This also adds a newer_than option to drop_chunks - More enhanced tests of drop_chunks and new tests for show_chunks Among other reasons, show_chunks was implemented in C in order to be able to have both older_than and newer_than arguments be null. This was not possible in SQL because the arguments had to have polymorphic types and whether they are used in function body or not, PL/pgSQL requires these arguments to typecheck.
1 parent d461959 commit 9a34028

24 files changed

+1214
-161
lines changed

sql/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ set(MOD_FILES
8383
updates/1.0.0-rc2--1.0.0-rc3.sql
8484
updates/1.0.0-rc3--1.0.0.sql
8585
updates/1.0.0--1.0.1-dev.sql
86+
updates/1.0.1--1.1.0.sql
8687
)
8788

8889
set(MODULE_PATHNAME "$libdir/timescaledb-${PROJECT_VERSION_MOD}")

sql/ddl_api.sql

Lines changed: 25 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ CREATE OR REPLACE FUNCTION create_hypertable(
2727
number_partitions INTEGER = NULL,
2828
associated_schema_name NAME = NULL,
2929
associated_table_prefix NAME = NULL,
30-
chunk_time_interval anyelement = NULL::bigint,
30+
chunk_time_interval ANYELEMENT = NULL::bigint,
3131
create_default_indexes BOOLEAN = TRUE,
3232
if_not_exists BOOLEAN = FALSE,
3333
partitioning_func REGPROC = NULL,
@@ -64,69 +64,43 @@ CREATE OR REPLACE FUNCTION set_number_partitions(
6464
dimension_name NAME = NULL
6565
) RETURNS VOID AS '@MODULE_PATHNAME@', 'ts_dimension_set_num_slices' LANGUAGE C VOLATILE;
6666

67-
-- Drop chunks that are older than a timestamp.
67+
-- Drop chunks that are older than a timestamp or newer than a timestamp.
6868
CREATE OR REPLACE FUNCTION drop_chunks(
69-
older_than anyelement,
69+
older_than ANYELEMENT = NULL,
7070
table_name NAME = NULL,
7171
schema_name NAME = NULL,
72-
cascade BOOLEAN = FALSE
72+
cascade BOOLEAN = FALSE,
73+
newer_than ANYELEMENT = NULL
7374
)
7475
RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS
7576
$BODY$
7677
DECLARE
7778
older_than_internal BIGINT;
79+
newer_than_internal BIGINT;
7880
BEGIN
79-
IF older_than IS NULL THEN
80-
RAISE 'the timestamp provided to drop_chunks cannot be NULL';
81+
IF older_than IS NULL AND newer_than IS NULL THEN
82+
RAISE 'older_than and newer_than timestamps provided to drop_chunks cannot both be NULL';
8183
END IF;
82-
83-
PERFORM _timescaledb_internal.drop_chunks_type_check(pg_typeof(older_than), table_name, schema_name);
84-
SELECT _timescaledb_internal.time_to_internal(older_than) INTO older_than_internal;
85-
PERFORM _timescaledb_internal.drop_chunks_impl(older_than_internal, table_name, schema_name, cascade);
84+
PERFORM _timescaledb_internal.drop_chunks_impl(older_than, table_name, schema_name, cascade,
85+
newer_than_time => newer_than);
8686
END
8787
$BODY$;
8888

89-
-- Drop chunks older than an interval.
90-
CREATE OR REPLACE FUNCTION drop_chunks(
91-
older_than INTERVAL,
92-
table_name NAME = NULL,
93-
schema_name NAME = NULL,
94-
cascade BOOLEAN = false
95-
)
96-
RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS
97-
$BODY$
98-
DECLARE
99-
time_type REGTYPE;
100-
BEGIN
101-
102-
BEGIN
103-
WITH hypertable_ids AS (
104-
SELECT id
105-
FROM _timescaledb_catalog.hypertable h
106-
WHERE (drop_chunks.schema_name IS NULL OR h.schema_name = drop_chunks.schema_name) AND
107-
(drop_chunks.table_name IS NULL OR h.table_name = drop_chunks.table_name)
108-
)
109-
SELECT DISTINCT time_dim.column_type INTO STRICT time_type
110-
FROM hypertable_ids INNER JOIN LATERAL _timescaledb_internal.dimension_get_time(hypertable_ids.id) time_dim ON (true);
111-
EXCEPTION
112-
WHEN NO_DATA_FOUND THEN
113-
RAISE EXCEPTION 'no hypertables found';
114-
WHEN TOO_MANY_ROWS THEN
115-
RAISE EXCEPTION 'cannot use drop_chunks on multiple tables with different time types';
116-
END;
117-
118-
119-
IF time_type = 'TIMESTAMP'::regtype THEN
120-
PERFORM @[email protected]_chunks((now() - older_than)::timestamp, table_name, schema_name, cascade);
121-
ELSIF time_type = 'DATE'::regtype THEN
122-
PERFORM @[email protected]_chunks((now() - older_than)::date, table_name, schema_name, cascade);
123-
ELSIF time_type = 'TIMESTAMPTZ'::regtype THEN
124-
PERFORM @[email protected]_chunks(now() - older_than, table_name, schema_name, cascade);
125-
ELSE
126-
RAISE 'can only use drop_chunks with an INTERVAL for TIMESTAMP, TIMESTAMPTZ, and DATE types';
127-
END IF;
128-
END
129-
$BODY$;
89+
-- show chunks older than or newer than a specific time.
90+
-- `hypertable` argument can be a valid hypertable or NULL.
91+
-- In the latter case the function will try to list all
92+
-- the chunks from all of the hypertables in the database.
93+
-- older_than or newer_than or both can be NULL.
94+
-- if `hypertable` argument is null but a time constraint is specified
95+
-- through older_than or newer_than, the call will succeed
96+
-- if and only if all the hypertables in the database
97+
-- have the same type as the given time constraint argument
98+
CREATE OR REPLACE FUNCTION show_chunks(
99+
hypertable REGCLASS = NULL,
100+
older_than "any" = NULL,
101+
newer_than "any" = NULL
102+
) RETURNS SETOF REGCLASS AS '@MODULE_PATHNAME@', 'ts_chunk_show_chunks'
103+
LANGUAGE C STABLE PARALLEL SAFE;
130104

131105
-- Add a dimension (of partitioning) to a hypertable
132106
--

sql/ddl_internal.sql

Lines changed: 26 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,35 @@
33
-- This file is licensed under the Apache License, see LICENSE-APACHE
44
-- at the top level directory of the TimescaleDB distribution.
55

6-
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_get_time(
7-
hypertable_id INT
8-
)
9-
RETURNS _timescaledb_catalog.dimension LANGUAGE SQL STABLE AS
10-
$BODY$
11-
SELECT *
12-
FROM _timescaledb_catalog.dimension d
13-
WHERE d.hypertable_id = dimension_get_time.hypertable_id AND
14-
d.interval_length IS NOT NULL
15-
$BODY$;
6+
-- show_chunks for internal use only. The only difference
7+
-- from user-facing API is that this one takes a 4th argument
8+
-- specifying the caller name. This makes it easier to taylor
9+
-- error messages to the caller function context.
10+
CREATE OR REPLACE FUNCTION _timescaledb_internal.show_chunks_impl(
11+
hypertable REGCLASS = NULL,
12+
older_than "any" = NULL,
13+
newer_than "any" = NULL,
14+
caller_name NAME = NULL
15+
) RETURNS SETOF REGCLASS AS '@MODULE_PATHNAME@', 'ts_chunk_show_chunks'
16+
LANGUAGE C STABLE PARALLEL SAFE;
1617

1718
-- Drop chunks older than the given timestamp. If a hypertable name is given,
1819
-- drop only chunks associated with this table. Any of the first three arguments
1920
-- can be NULL meaning "all values".
2021
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunks_impl(
21-
older_than_time BIGINT,
22+
older_than_time ANYELEMENT = NULL,
2223
table_name NAME = NULL,
2324
schema_name NAME = NULL,
2425
cascade BOOLEAN = FALSE,
25-
truncate_before BOOLEAN = FALSE
26+
newer_than_time ANYELEMENT = NULL
2627
)
2728
RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS
2829
$BODY$
2930
DECLARE
30-
chunk_row _timescaledb_catalog.chunk;
31+
chunk_row REGCLASS;
3132
cascade_mod TEXT = '';
3233
exist_count INT = 0;
3334
BEGIN
34-
IF older_than_time IS NULL AND table_name IS NULL AND schema_name IS NULL THEN
35-
RAISE 'cannot have all 3 arguments to drop_chunks_older_than be NULL';
36-
END IF;
3735

3836
IF cascade THEN
3937
cascade_mod = 'CASCADE';
@@ -52,71 +50,25 @@ BEGIN
5250
END IF;
5351
END IF;
5452

55-
FOR chunk_row IN SELECT *
56-
FROM _timescaledb_catalog.chunk c
57-
INNER JOIN _timescaledb_catalog.hypertable h ON (h.id = c.hypertable_id)
58-
INNER JOIN _timescaledb_internal.dimension_get_time(h.id) time_dimension ON(true)
59-
INNER JOIN _timescaledb_catalog.dimension_slice ds
60-
ON (ds.dimension_id = time_dimension.id)
61-
INNER JOIN _timescaledb_catalog.chunk_constraint cc
62-
ON (cc.dimension_slice_id = ds.id AND cc.chunk_id = c.id)
63-
WHERE (older_than_time IS NULL OR ds.range_end <= older_than_time)
64-
AND (drop_chunks_impl.schema_name IS NULL OR h.schema_name = drop_chunks_impl.schema_name)
65-
AND (drop_chunks_impl.table_name IS NULL OR h.table_name = drop_chunks_impl.table_name)
53+
FOR schema_name, table_name IN
54+
SELECT hyper.schema_name, hyper.table_name
55+
FROM _timescaledb_catalog.hypertable hyper
56+
WHERE
57+
(drop_chunks_impl.schema_name IS NULL OR hyper.schema_name = drop_chunks_impl.schema_name) AND
58+
(drop_chunks_impl.table_name IS NULL OR hyper.table_name = drop_chunks_impl.table_name)
6659
LOOP
67-
IF truncate_before THEN
60+
FOR chunk_row IN SELECT _timescaledb_internal.show_chunks_impl(schema_name || '.' || table_name, older_than_time, newer_than_time, 'drop_chunks')
61+
LOOP
6862
EXECUTE format(
69-
$$
70-
TRUNCATE %I.%I %s
71-
$$, chunk_row.schema_name, chunk_row.table_name, cascade_mod
63+
$$
64+
DROP TABLE %s %s
65+
$$, chunk_row, cascade_mod
7266
);
73-
END IF;
74-
EXECUTE format(
75-
$$
76-
DROP TABLE %I.%I %s
77-
$$, chunk_row.schema_name, chunk_row.table_name, cascade_mod
78-
);
67+
END LOOP;
7968
END LOOP;
8069
END
8170
$BODY$;
8271

83-
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunks_type_check(
84-
given_type REGTYPE,
85-
table_name NAME,
86-
schema_name NAME
87-
)
88-
RETURNS VOID LANGUAGE PLPGSQL STABLE AS
89-
$BODY$
90-
DECLARE
91-
actual_type regtype;
92-
BEGIN
93-
BEGIN
94-
WITH hypertable_ids AS (
95-
SELECT id
96-
FROM _timescaledb_catalog.hypertable h
97-
WHERE (drop_chunks_type_check.schema_name IS NULL OR h.schema_name = drop_chunks_type_check.schema_name) AND
98-
(drop_chunks_type_check.table_name IS NULL OR h.table_name = drop_chunks_type_check.table_name)
99-
)
100-
SELECT DISTINCT time_dim.column_type INTO STRICT actual_type
101-
FROM hypertable_ids INNER JOIN LATERAL _timescaledb_internal.dimension_get_time(hypertable_ids.id) time_dim ON (true);
102-
EXCEPTION
103-
WHEN NO_DATA_FOUND THEN
104-
RAISE EXCEPTION 'no hypertables found';
105-
WHEN TOO_MANY_ROWS THEN
106-
RAISE EXCEPTION 'cannot use drop_chunks on multiple tables with different time types';
107-
END;
108-
109-
IF given_type IN ('int'::regtype, 'smallint'::regtype, 'bigint'::regtype ) THEN
110-
IF actual_type IN ('int'::regtype, 'smallint'::regtype, 'bigint'::regtype ) THEN
111-
RETURN;
112-
END IF;
113-
END IF;
114-
IF actual_type != given_type THEN
115-
RAISE EXCEPTION 'cannot call drop_chunks with a % on hypertables with a time type of: %', given_type, actual_type;
116-
END IF;
117-
END
118-
$BODY$;
119-
12072
--documentation of these function located in chunk_index.h
12173
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_clone(chunk_index_oid OID) RETURNS OID
12274
AS '@MODULE_PATHNAME@', 'ts_chunk_index_clone' LANGUAGE C VOLATILE STRICT;

sql/updates/1.0.1--1.1.0.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DROP FUNCTION IF EXISTS drop_chunks(INTERVAL, NAME, NAME, BOOLEAN);
2+
DROP FUNCTION IF EXISTS drop_chunks(ANYELEMENT, NAME, NAME, BOOLEAN);
3+
DROP FUNCTION IF EXISTS _timescaledb_internal.drop_chunks_impl(BIGINT, NAME, NAME, BOOLEAN, BOOLEAN);
4+
DROP FUNCTION IF EXISTS _timescaledb_internal.drop_chunks_type_check(REGTYPE, NAME, NAME);
5+
DROP FUNCTION IF EXISTS _timescaledb_internal.dimension_get_time(INTEGER);

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(SOURCES
1212
chunk_dispatch_state.c
1313
chunk_index.c
1414
chunk_insert_state.c
15+
compat.c
1516
constraint_aware_append.c
1617
copy.c
1718
dimension.c

src/catalog.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <miscadmin.h>
1818
#include <commands/dbcommands.h>
1919
#include <commands/sequence.h>
20-
#include <access/xact.h>
2120

2221
#include "compat.h"
2322
#include "catalog.h"

0 commit comments

Comments
 (0)