Skip to content

Commit

Permalink
Move chunk functions to _timescaledb_functions schema
Browse files Browse the repository at this point in the history
To increase schema security we do not want to mix our own internal
objects with user objects. Since chunks are created in the
_timescaledb_internal schema our internal functions should live in
a different dedicated schema. This patch make the necessary
adjustments for the following functions:

- calculate_chunk_interval(int, bigint, bigint)
- chunk_status(regclass)
- chunks_in(record, integer[])
- chunk_id_from_relid(oid)
- show_chunk(regclass)
- create_chunk(regclass, jsonb, name, name, regclass)
- set_chunk_default_data_node(regclass, name)
- get_chunk_relstats(regclass)
- get_chunk_colstats(regclass)
- create_chunk_table(regclass, jsonb, name, name)
- freeze_chunk(regclass)
- unfreeze_chunk(regclass)
- drop_chunk(regclass)
- attach_osm_table_chunk(regclass, regclass)
  • Loading branch information
svenklemm committed Aug 24, 2023
1 parent 5bba74a commit 0da18a9
Show file tree
Hide file tree
Showing 73 changed files with 4,392 additions and 4,337 deletions.
30 changes: 15 additions & 15 deletions sql/chunk.sql
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,32 @@
--
-- The function should return the new interval in dimension-specific
-- time (ususally microseconds).
CREATE OR REPLACE FUNCTION _timescaledb_internal.calculate_chunk_interval(
CREATE OR REPLACE FUNCTION _timescaledb_functions.calculate_chunk_interval(
dimension_id INTEGER,
dimension_coord BIGINT,
chunk_target_size BIGINT
) RETURNS BIGINT AS '@MODULE_PATHNAME@', 'ts_calculate_chunk_interval' LANGUAGE C;

-- Get the status of the chunk
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_status(REGCLASS) RETURNS INT
CREATE OR REPLACE FUNCTION _timescaledb_functions.chunk_status(REGCLASS) RETURNS INT
AS '@MODULE_PATHNAME@', 'ts_chunk_status' LANGUAGE C;

-- Function for explicit chunk exclusion. Supply a record and an array
-- of chunk ids as input.
-- Intended to be used in WHERE clause.
-- An example: SELECT * FROM hypertable WHERE _timescaledb_internal.chunks_in(hypertable, ARRAY[1,2]);
-- An example: SELECT * FROM hypertable WHERE _timescaledb_functions.chunks_in(hypertable, ARRAY[1,2]);
--
-- Use it with care as this function directly affects what chunks are being scanned for data.
-- This is a marker function and should never be executed (we remove it from the plan)
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunks_in(record RECORD, chunks INTEGER[]) RETURNS BOOL
CREATE OR REPLACE FUNCTION _timescaledb_functions.chunks_in(record RECORD, chunks INTEGER[]) RETURNS BOOL
AS '@MODULE_PATHNAME@', 'ts_chunks_in' LANGUAGE C STABLE STRICT PARALLEL SAFE;

--given a chunk's relid, return the id. Error out if not a chunk relid.
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_id_from_relid(relid OID) RETURNS INTEGER
CREATE OR REPLACE FUNCTION _timescaledb_functions.chunk_id_from_relid(relid OID) RETURNS INTEGER
AS '@MODULE_PATHNAME@', 'ts_chunk_id_from_relid' LANGUAGE C STABLE STRICT PARALLEL SAFE;

-- Show the definition of a chunk.
CREATE OR REPLACE FUNCTION _timescaledb_internal.show_chunk(chunk REGCLASS)
CREATE OR REPLACE FUNCTION _timescaledb_functions.show_chunk(chunk REGCLASS)
RETURNS TABLE(chunk_id INTEGER, hypertable_id INTEGER, schema_name NAME, table_name NAME, relkind "char", slices JSONB)
AS '@MODULE_PATHNAME@', 'ts_chunk_show' LANGUAGE C VOLATILE;

Expand All @@ -50,7 +50,7 @@ AS '@MODULE_PATHNAME@', 'ts_chunk_show' LANGUAGE C VOLATILE;
-- chunk. Note that schema_name and table_name need not be the same as
-- the existing schema and name for chunk_table. The provided chunk
-- table will be renamed and/or moved as necessary.
CREATE OR REPLACE FUNCTION _timescaledb_internal.create_chunk(
CREATE OR REPLACE FUNCTION _timescaledb_functions.create_chunk(
hypertable REGCLASS,
slices JSONB,
schema_name NAME = NULL,
Expand All @@ -60,43 +60,43 @@ RETURNS TABLE(chunk_id INTEGER, hypertable_id INTEGER, schema_name NAME, table_n
AS '@MODULE_PATHNAME@', 'ts_chunk_create' LANGUAGE C VOLATILE;

-- change default data node for a chunk
CREATE OR REPLACE FUNCTION _timescaledb_internal.set_chunk_default_data_node(chunk REGCLASS, node_name NAME) RETURNS BOOLEAN
CREATE OR REPLACE FUNCTION _timescaledb_functions.set_chunk_default_data_node(chunk REGCLASS, node_name NAME) RETURNS BOOLEAN
AS '@MODULE_PATHNAME@', 'ts_chunk_set_default_data_node' LANGUAGE C VOLATILE;

-- Get chunk stats.
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_chunk_relstats(relid REGCLASS)
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_chunk_relstats(relid REGCLASS)
RETURNS TABLE(chunk_id INTEGER, hypertable_id INTEGER, num_pages INTEGER, num_tuples REAL, num_allvisible INTEGER)
AS '@MODULE_PATHNAME@', 'ts_chunk_get_relstats' LANGUAGE C VOLATILE;

CREATE OR REPLACE FUNCTION _timescaledb_internal.get_chunk_colstats(relid REGCLASS)
CREATE OR REPLACE FUNCTION _timescaledb_functions.get_chunk_colstats(relid REGCLASS)
RETURNS TABLE(chunk_id INTEGER, hypertable_id INTEGER, att_num INTEGER, nullfrac REAL, width INTEGER, distinctval REAL, slotkind INTEGER[], slotopstrings CSTRING[], slotcollations OID[],
slot1numbers FLOAT4[], slot2numbers FLOAT4[], slot3numbers FLOAT4[], slot4numbers FLOAT4[], slot5numbers FLOAT4[],
slotvaluetypetrings CSTRING[], slot1values CSTRING[], slot2values CSTRING[], slot3values CSTRING[], slot4values CSTRING[], slot5values CSTRING[])
AS '@MODULE_PATHNAME@', 'ts_chunk_get_colstats' LANGUAGE C VOLATILE;

CREATE OR REPLACE FUNCTION _timescaledb_internal.create_chunk_table(
CREATE OR REPLACE FUNCTION _timescaledb_functions.create_chunk_table(
hypertable REGCLASS,
slices JSONB,
schema_name NAME,
table_name NAME)
RETURNS BOOL AS '@MODULE_PATHNAME@', 'ts_chunk_create_empty_table' LANGUAGE C VOLATILE;

CREATE OR REPLACE FUNCTION _timescaledb_internal.freeze_chunk(
CREATE OR REPLACE FUNCTION _timescaledb_functions.freeze_chunk(
chunk REGCLASS)
RETURNS BOOL AS '@MODULE_PATHNAME@', 'ts_chunk_freeze_chunk' LANGUAGE C VOLATILE;

CREATE OR REPLACE FUNCTION _timescaledb_internal.unfreeze_chunk(
CREATE OR REPLACE FUNCTION _timescaledb_functions.unfreeze_chunk(
chunk REGCLASS)
RETURNS BOOL AS '@MODULE_PATHNAME@', 'ts_chunk_unfreeze_chunk' LANGUAGE C VOLATILE;

--wrapper for ts_chunk_drop
--drops the chunk table and its entry in the chunk catalog
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk(
CREATE OR REPLACE FUNCTION _timescaledb_functions.drop_chunk(
chunk REGCLASS)
RETURNS BOOL AS '@MODULE_PATHNAME@', 'ts_chunk_drop_single_chunk' LANGUAGE C VOLATILE;

-- internal API used by OSM extension to attach a table as a chunk of the hypertable
CREATE OR REPLACE FUNCTION _timescaledb_internal.attach_osm_table_chunk(
CREATE OR REPLACE FUNCTION _timescaledb_functions.attach_osm_table_chunk(
hypertable REGCLASS,
chunk REGCLASS)
RETURNS BOOL AS '@MODULE_PATHNAME@', 'ts_chunk_attach_osm_table_chunk' LANGUAGE C VOLATILE;
6 changes: 3 additions & 3 deletions sql/ddl_api.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ CREATE OR REPLACE FUNCTION @[email protected]_hypertable(
partitioning_func REGPROC = NULL,
migrate_data BOOLEAN = FALSE,
chunk_target_size TEXT = NULL,
chunk_sizing_func REGPROC = '_timescaledb_internal.calculate_chunk_interval'::regproc,
chunk_sizing_func REGPROC = '_timescaledb_functions.calculate_chunk_interval'::regproc,
time_partitioning_func REGPROC = NULL,
replication_factor INTEGER = NULL,
data_nodes NAME[] = NULL,
Expand All @@ -56,7 +56,7 @@ CREATE OR REPLACE FUNCTION @[email protected]_distributed_hypertable(
partitioning_func REGPROC = NULL,
migrate_data BOOLEAN = FALSE,
chunk_target_size TEXT = NULL,
chunk_sizing_func REGPROC = '_timescaledb_internal.calculate_chunk_interval'::regproc,
chunk_sizing_func REGPROC = '_timescaledb_functions.calculate_chunk_interval'::regproc,
time_partitioning_func REGPROC = NULL,
replication_factor INTEGER = NULL,
data_nodes NAME[] = NULL
Expand All @@ -66,7 +66,7 @@ CREATE OR REPLACE FUNCTION @[email protected]_distributed_hypertable(
CREATE OR REPLACE FUNCTION @[email protected]_adaptive_chunking(
hypertable REGCLASS,
chunk_target_size TEXT,
INOUT chunk_sizing_func REGPROC = '_timescaledb_internal.calculate_chunk_interval'::regproc,
INOUT chunk_sizing_func REGPROC = '_timescaledb_functions.calculate_chunk_interval'::regproc,
OUT chunk_target_size BIGINT
) RETURNS RECORD AS '@MODULE_PATHNAME@', 'ts_chunk_adaptive_set' LANGUAGE C VOLATILE;

Expand Down
2 changes: 1 addition & 1 deletion sql/maintenance_utils.sql
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ BEGIN
-- control so we adjust search_path in procedure body
SET LOCAL search_path TO pg_catalog, pg_temp;

status := _timescaledb_internal.chunk_status(chunk);
status := _timescaledb_functions.chunk_status(chunk);

-- Chunk names are in the internal catalog, but we only care about
-- the chunk name here.
Expand Down
40 changes: 39 additions & 1 deletion sql/updates/latest-dev.sql
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,39 @@ BEGIN
THEN
ALTER FUNCTION _timescaledb_internal.get_approx_row_count(regclass) SET SCHEMA _timescaledb_functions;
END IF;
IF (EXISTS (SELECT FROM pg_proc WHERE proname = 'chunk_status' AND pronamespace='_timescaledb_internal'::regnamespace))
THEN
ALTER FUNCTION _timescaledb_internal.chunk_status(regclass) SET SCHEMA _timescaledb_functions;
END IF;
IF (EXISTS (SELECT FROM pg_proc WHERE proname = 'create_chunk' AND pronamespace='_timescaledb_internal'::regnamespace))
THEN
ALTER FUNCTION _timescaledb_internal.create_chunk(regclass, jsonb, name, name, regclass) SET SCHEMA _timescaledb_functions;
END IF;
IF (EXISTS (SELECT FROM pg_proc WHERE proname = 'create_chunk_table' AND pronamespace='_timescaledb_internal'::regnamespace))
THEN
ALTER FUNCTION _timescaledb_internal.create_chunk_table(regclass, jsonb, name, name) SET SCHEMA _timescaledb_functions;
END IF;
IF (EXISTS (SELECT FROM pg_proc WHERE proname = 'freeze_chunk' AND pronamespace='_timescaledb_internal'::regnamespace))
THEN
ALTER FUNCTION _timescaledb_internal.freeze_chunk(regclass) SET SCHEMA _timescaledb_functions;
END IF;
IF (EXISTS (SELECT FROM pg_proc WHERE proname = 'unfreeze_chunk' AND pronamespace='_timescaledb_internal'::regnamespace))
THEN
ALTER FUNCTION _timescaledb_internal.unfreeze_chunk(regclass) SET SCHEMA _timescaledb_functions;
END IF;
IF (EXISTS (SELECT FROM pg_proc WHERE proname = 'drop_chunk' AND pronamespace='_timescaledb_internal'::regnamespace))
THEN
ALTER FUNCTION _timescaledb_internal.drop_chunk(regclass) SET SCHEMA _timescaledb_functions;
END IF;
IF (EXISTS (SELECT FROM pg_proc WHERE proname = 'attach_osm_table_chunk' AND pronamespace='_timescaledb_internal'::regnamespace))
THEN
ALTER FUNCTION _timescaledb_internal.attach_osm_table_chunk(regclass, regclass) SET SCHEMA _timescaledb_functions;
END IF;
END;
$$;

DROP FUNCTION IF EXISTS _timescaledb_internal.get_time_type(integer);

ALTER FUNCTION _timescaledb_internal.insert_blocker() SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.continuous_agg_invalidation_trigger() SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.get_create_command(name) SET SCHEMA _timescaledb_functions;
Expand Down Expand Up @@ -89,5 +119,13 @@ ALTER FUNCTION _timescaledb_internal.get_git_commit() SET SCHEMA _timescaledb_fu
ALTER FUNCTION _timescaledb_internal.get_os_info() SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.tsl_loaded() SET SCHEMA _timescaledb_functions;

DROP FUNCTION IF EXISTS _timescaledb_internal.get_time_type(integer);
ALTER FUNCTION _timescaledb_internal.calculate_chunk_interval(int, bigint, bigint) SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.chunks_in(record, integer[]) SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.chunk_id_from_relid(oid) SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.show_chunk(regclass) SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.set_chunk_default_data_node(regclass, name) SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.get_chunk_relstats(regclass) SET SCHEMA _timescaledb_functions;
ALTER FUNCTION _timescaledb_internal.get_chunk_colstats(regclass) SET SCHEMA _timescaledb_functions;

UPDATE _timescaledb_catalog.hypertable SET chunk_sizing_func_schema = '_timescaledb_functions' WHERE chunk_sizing_func_schema = '_timescaledb_internal' AND chunk_sizing_func_name = 'calculate_chunk_interval';

17 changes: 17 additions & 0 deletions sql/updates/reverse-dev.sql
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,20 @@ ALTER FUNCTION _timescaledb_functions.get_git_commit() SET SCHEMA _timescaledb_i
ALTER FUNCTION _timescaledb_functions.get_os_info() SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.tsl_loaded() SET SCHEMA _timescaledb_internal;

ALTER FUNCTION _timescaledb_functions.calculate_chunk_interval(int, bigint, bigint) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.chunk_status(regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.chunks_in(record, integer[]) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.chunk_id_from_relid(oid) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.show_chunk(regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.create_chunk(regclass, jsonb, name, name, regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.set_chunk_default_data_node(regclass, name) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.get_chunk_relstats(regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.get_chunk_colstats(regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.create_chunk_table(regclass, jsonb, name, name) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.freeze_chunk(regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.unfreeze_chunk(regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.drop_chunk(regclass) SET SCHEMA _timescaledb_internal;
ALTER FUNCTION _timescaledb_functions.attach_osm_table_chunk(regclass, regclass) SET SCHEMA _timescaledb_internal;

UPDATE _timescaledb_catalog.hypertable SET chunk_sizing_func_schema = '_timescaledb_internal' WHERE chunk_sizing_func_schema = '_timescaledb_functions' AND chunk_sizing_func_name = 'calculate_chunk_interval';

2 changes: 1 addition & 1 deletion src/chunk_adaptive.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ get_default_chunk_sizing_fn_oid()
{
Oid chunkfnargtypes[] = { INT4OID, INT8OID, INT8OID };
List *funcname =
list_make2(makeString(INTERNAL_SCHEMA_NAME), makeString(DEFAULT_CHUNK_SIZING_FN_NAME));
list_make2(makeString(FUNCTIONS_SCHEMA_NAME), makeString(DEFAULT_CHUNK_SIZING_FN_NAME));
int nargs = sizeof(chunkfnargtypes) / sizeof(chunkfnargtypes[0]);
Oid chunkfnoid = LookupFuncName(funcname, nargs, chunkfnargtypes, false);
return chunkfnoid;
Expand Down
2 changes: 1 addition & 1 deletion src/planner/expand_hypertable.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ init_chunk_exclusion_func()
{
if (!OidIsValid(chunk_exclusion_func))
{
List *l = list_make2(makeString(INTERNAL_SCHEMA_NAME), makeString(CHUNK_EXCL_FUNC_NAME));
List *l = list_make2(makeString(FUNCTIONS_SCHEMA_NAME), makeString(CHUNK_EXCL_FUNC_NAME));
chunk_exclusion_func =
LookupFuncName(l, lengthof(ts_chunks_arg_types), ts_chunks_arg_types, false);
}
Expand Down
2 changes: 1 addition & 1 deletion test/expected/alter.out
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ INSERT INTO my_table (date, quantity) VALUES ('2018-08-10T23:00:00+00:00', 20);
SELECT * from _timescaledb_catalog.hypertable;
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
----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------
12 | public | my_table | new_associated_schema | _hyper_12 | 1 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
12 | public | my_table | new_associated_schema | _hyper_12 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | |
(1 row)

SELECT * from _timescaledb_catalog.chunk;
Expand Down
8 changes: 4 additions & 4 deletions test/expected/alternate_users.out
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ SELECT * FROM create_hypertable('"customSchema"."Hypertable_1"', 'time', NULL, 1
SELECT * FROM _timescaledb_catalog.hypertable;
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
----+--------------+---------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------
1 | public | one_Partition | one_Partition | _hyper_1 | 1 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
2 | public | 1dim | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
3 | public | Hypertable_1 | _timescaledb_internal | _hyper_3 | 2 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
4 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_4 | 1 | _timescaledb_internal | calculate_chunk_interval | 0 | 0 | |
1 | public | one_Partition | one_Partition | _hyper_1 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | |
2 | public | 1dim | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | |
3 | public | Hypertable_1 | _timescaledb_internal | _hyper_3 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | |
4 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_4 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | |
(4 rows)

CREATE INDEX ON PUBLIC."Hypertable_1" (time, "temp_c");
Expand Down
Loading

0 comments on commit 0da18a9

Please sign in to comment.