From ba8fdd58ffd7b1254da01e1e44e90518865903dc Mon Sep 17 00:00:00 2001 From: Konstantina Skovola Date: Thu, 31 Aug 2023 11:25:47 +0300 Subject: [PATCH] Add API function for updating OSM chunk ranges This commit introduces a function `dimension_slice_update_range_for_osm` in the _timescaledb_functions schema. This function is meant to serve as an API call for the OSM extension to update the time range of a hypertable's OSM chunk with the min and max values present in the contiguous time range its tiered chunks span. If the range is not contiguous, then it must be set to the invalid range an OSM chunk is assigned upon creation. A new status field is also introduced in the hypertable catalog table to keep track of whether the ranges covered by tiered and non-tiered chunks overlap. When there is no overlap detected then it is possible to apply the Ordered Append optimization in the presence of OSM chunks. --- cmake/ScriptFiles.cmake | 3 +- sql/osm_api.sql | 14 ++ sql/pre_install/tables.sql | 1 + sql/updates/latest-dev.sql | 158 ++++++++++++ sql/updates/reverse-dev.sql | 164 +++++++++++++ src/chunk.c | 14 ++ src/chunk.h | 2 + src/dimension_slice.c | 192 +++++++++++++++ src/hypertable.c | 6 + src/planner/planner.c | 10 +- src/ts_catalog/catalog.h | 6 + test/expected/alter.out | 6 +- test/expected/alternate_users.out | 12 +- test/expected/create_hypertable.out | 18 +- test/expected/ddl-13.out | 8 +- test/expected/ddl-14.out | 8 +- test/expected/ddl-15.out | 8 +- test/expected/drop_extension.out | 12 +- test/expected/drop_hypertable.out | 16 +- test/expected/drop_owned.out | 18 +- test/expected/drop_rename_hypertable.out | 16 +- test/expected/drop_schema.out | 20 +- test/expected/dump_meta.out | 6 +- test/expected/pg_dump.out | 12 +- test/expected/relocate_extension.out | 10 +- test/expected/truncate.out | 12 +- tsl/test/expected/chunk_utils_internal.out | 272 +++++++++++++++++++++ tsl/test/shared/expected/extension.out | 1 + tsl/test/sql/chunk_utils_internal.sql | 103 ++++++++ 29 files changed, 1033 insertions(+), 95 deletions(-) create mode 100644 sql/osm_api.sql diff --git a/cmake/ScriptFiles.cmake b/cmake/ScriptFiles.cmake index 5a07a7adc12..657d19cf8fd 100644 --- a/cmake/ScriptFiles.cmake +++ b/cmake/ScriptFiles.cmake @@ -59,7 +59,8 @@ set(SOURCE_FILES policy_internal.sql cagg_utils.sql cagg_migrate.sql - job_error_log_retention.sql) + job_error_log_retention.sql + osm_api.sql) if(ENABLE_DEBUG_UTILS AND CMAKE_BUILD_TYPE MATCHES Debug) list(APPEND SOURCE_FILES debug_utils.sql) diff --git a/sql/osm_api.sql b/sql/osm_api.sql new file mode 100644 index 00000000000..33020c3f66f --- /dev/null +++ b/sql/osm_api.sql @@ -0,0 +1,14 @@ +-- This file and its contents are licensed under the Apache License 2.0. +-- Please see the included NOTICE for copyright information and +-- LICENSE-APACHE for a copy of the license. + +-- This function updates the dimension slice range stored in the catalog with the min and max +-- values that the OSM chunk contains. Since there is only one OSM chunk per hypertable with +-- only a time dimension, the hypertable is used to determine the corresponding slice +CREATE OR REPLACE FUNCTION _timescaledb_functions.hypertable_update_range_for_osm( + hypertable REGCLASS, + range_start ANYELEMENT, + range_end ANYELEMENT, + empty BOOL = false +) RETURNS BOOL AS '@MODULE_PATHNAME@', +'ts_hypertable_update_range_for_osm' LANGUAGE C VOLATILE; \ No newline at end of file diff --git a/sql/pre_install/tables.sql b/sql/pre_install/tables.sql index 6826dc5a531..0f4fb67299f 100644 --- a/sql/pre_install/tables.sql +++ b/sql/pre_install/tables.sql @@ -52,6 +52,7 @@ CREATE TABLE _timescaledb_catalog.hypertable ( compression_state smallint NOT NULL DEFAULT 0, compressed_hypertable_id integer, replication_factor smallint NULL, + status int NOT NULL DEFAULT 0, -- table constraints CONSTRAINT hypertable_pkey PRIMARY KEY (id), CONSTRAINT hypertable_associated_schema_name_associated_table_prefix_key UNIQUE (associated_schema_name, associated_table_prefix), diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index 69cbf09dcd0..22b07e2b1f2 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -167,3 +167,161 @@ ALTER FUNCTION _timescaledb_internal.finalize_agg_ffunc(internal,text,name,name, ALTER FUNCTION _timescaledb_internal.finalize_agg_sfunc(internal,text,name,name,name[],bytea,anyelement) SET SCHEMA _timescaledb_functions; ALTER FUNCTION _timescaledb_internal.partialize_agg(anyelement) SET SCHEMA _timescaledb_functions; +-- OSM support - table must re rebuilt to ensure consistent attribute numbers +-- we cannot just ALTER TABLE .. ADD COLUMN +ALTER TABLE _timescaledb_config.bgw_job + DROP CONSTRAINT bgw_job_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.chunk + DROP CONSTRAINT chunk_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.chunk_index + DROP CONSTRAINT chunk_index_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.continuous_agg + DROP CONSTRAINT continuous_agg_mat_hypertable_id_fkey, + DROP CONSTRAINT continuous_agg_raw_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.continuous_aggs_bucket_function + DROP CONSTRAINT continuous_aggs_bucket_function_mat_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold + DROP CONSTRAINT continuous_aggs_invalidation_threshold_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.dimension + DROP CONSTRAINT dimension_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.hypertable + DROP CONSTRAINT hypertable_compressed_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.hypertable_compression + DROP CONSTRAINT hypertable_compression_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.hypertable_data_node + DROP CONSTRAINT hypertable_data_node_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.tablespace + DROP CONSTRAINT tablespace_hypertable_id_fkey; + +DROP VIEW IF EXISTS timescaledb_information.hypertables; +DROP VIEW IF EXISTS timescaledb_information.job_stats; +DROP VIEW IF EXISTS timescaledb_information.jobs; +DROP VIEW IF EXISTS timescaledb_information.continuous_aggregates; +DROP VIEW IF EXISTS timescaledb_information.chunks; +DROP VIEW IF EXISTS timescaledb_information.dimensions; +DROP VIEW IF EXISTS timescaledb_information.compression_settings; +DROP VIEW IF EXISTS _timescaledb_internal.hypertable_chunk_local_size; +DROP VIEW IF EXISTS _timescaledb_internal.compressed_chunk_stats; +DROP VIEW IF EXISTS timescaledb_experimental.chunk_replication_status; +DROP VIEW IF EXISTS timescaledb_experimental.policies; + +-- recreate table +CREATE TABLE _timescaledb_catalog.hypertable_tmp AS SELECT * FROM _timescaledb_catalog.hypertable; +CREATE TABLE _timescaledb_catalog.tmp_hypertable_seq_value AS SELECT last_value, is_called FROM _timescaledb_catalog.hypertable_id_seq; + +ALTER EXTENSION timescaledb DROP TABLE _timescaledb_catalog.hypertable; +ALTER EXTENSION timescaledb DROP SEQUENCE _timescaledb_catalog.hypertable_id_seq; + +SET timescaledb.restoring = on; -- must disable the hooks otherwise we can't do anything without the table _timescaledb_catalog.hypertable + +DROP TABLE _timescaledb_catalog.hypertable; + +CREATE SEQUENCE _timescaledb_catalog.hypertable_id_seq MINVALUE 1; +SELECT setval('_timescaledb_catalog.hypertable_id_seq', last_value, is_called) FROM _timescaledb_catalog.tmp_hypertable_seq_value; +DROP TABLE _timescaledb_catalog.tmp_hypertable_seq_value; + +CREATE TABLE _timescaledb_catalog.hypertable ( + id INTEGER PRIMARY KEY NOT NULL DEFAULT nextval('_timescaledb_catalog.hypertable_id_seq'), + schema_name name NOT NULL, + table_name name NOT NULL, + associated_schema_name name NOT NULL, + associated_table_prefix name NOT NULL, + num_dimensions smallint NOT NULL, + chunk_sizing_func_schema name NOT NULL, + chunk_sizing_func_name name NOT NULL, + chunk_target_size bigint NOT NULL, -- size in bytes + compression_state smallint NOT NULL DEFAULT 0, + compressed_hypertable_id integer, + replication_factor smallint NULL, + status integer NOT NULL DEFAULT 0 +); + +SET timescaledb.restoring = off; + +INSERT INTO _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 +) +SELECT + 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 +FROM + _timescaledb_catalog.hypertable_tmp +ORDER BY id; + +UPDATE _timescaledb_catalog.hypertable +SET status = 3 +WHERE id IN ( + SELECT id + FROM _timescaledb_catalog.hypertable h + WHERE EXISTS ( + SELECT 1 + FROM _timescaledb_catalog.chunk c + WHERE c.osm_chunk = TRUE + AND c.hypertable_id = h.id + ) +); + +ALTER SEQUENCE _timescaledb_catalog.hypertable_id_seq OWNED BY _timescaledb_catalog.hypertable.id; +SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.hypertable', 'WHERE id >= 1'); +SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.hypertable_id_seq', ''); + +GRANT SELECT ON _timescaledb_catalog.hypertable TO PUBLIC; +GRANT SELECT ON _timescaledb_catalog.hypertable_id_seq TO PUBLIC; + +DROP TABLE _timescaledb_catalog.hypertable_tmp; +-- now add any constraints +ALTER TABLE _timescaledb_catalog.hypertable + ADD CONSTRAINT hypertable_associated_schema_name_associated_table_prefix_key UNIQUE (associated_schema_name, associated_table_prefix), + ADD CONSTRAINT hypertable_table_name_schema_name_key UNIQUE (table_name, schema_name), + ADD CONSTRAINT hypertable_schema_name_check CHECK (schema_name != '_timescaledb_catalog'), + ADD CONSTRAINT hypertable_dim_compress_check CHECK (num_dimensions > 0 OR compression_state = 2), + ADD CONSTRAINT hypertable_chunk_target_size_check CHECK (chunk_target_size >= 0), + ADD CONSTRAINT hypertable_compress_check CHECK ( (compression_state = 0 OR compression_state = 1 ) OR (compression_state = 2 AND compressed_hypertable_id IS NULL)), + ADD CONSTRAINT hypertable_replication_factor_check CHECK (replication_factor > 0 OR replication_factor = -1), + ADD CONSTRAINT hypertable_compressed_hypertable_id_fkey FOREIGN KEY (compressed_hypertable_id) REFERENCES _timescaledb_catalog.hypertable (id); + +GRANT SELECT ON TABLE _timescaledb_catalog.hypertable TO PUBLIC; + +-- 3. reestablish constraints on other tables +ALTER TABLE _timescaledb_config.bgw_job + ADD CONSTRAINT bgw_job_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.chunk + ADD CONSTRAINT chunk_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id); +ALTER TABLE _timescaledb_catalog.chunk_index + ADD CONSTRAINT chunk_index_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.continuous_agg + ADD CONSTRAINT continuous_agg_mat_hypertable_id_fkey FOREIGN KEY (mat_hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE, + ADD CONSTRAINT continuous_agg_raw_hypertable_id_fkey FOREIGN KEY (raw_hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.continuous_aggs_bucket_function + ADD CONSTRAINT continuous_aggs_bucket_function_mat_hypertable_id_fkey FOREIGN KEY (mat_hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold + ADD CONSTRAINT continuous_aggs_invalidation_threshold_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.dimension + ADD CONSTRAINT dimension_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.hypertable_compression + ADD CONSTRAINT hypertable_compression_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.hypertable_data_node + ADD CONSTRAINT hypertable_data_node_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id); +ALTER TABLE _timescaledb_catalog.tablespace + ADD CONSTRAINT tablespace_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; diff --git a/sql/updates/reverse-dev.sql b/sql/updates/reverse-dev.sql index 0f17c6c39b5..0222160dd29 100644 --- a/sql/updates/reverse-dev.sql +++ b/sql/updates/reverse-dev.sql @@ -273,3 +273,167 @@ ALTER FUNCTION _timescaledb_functions.finalize_agg_sfunc(internal,text,name,name ALTER FUNCTION _timescaledb_functions.partialize_agg(anyelement) SET SCHEMA _timescaledb_internal; ALTER AGGREGATE _timescaledb_functions.finalize_agg(text,name,name,name[][],bytea,anyelement) SET SCHEMA _timescaledb_internal; +DROP FUNCTION _timescaledb_functions.hypertable_update_range_for_osm(regclass, anyelement, anyelement, boolean); + +-- recreate the _timescaledb_catalog.hypertable table as new field was added +-- 1. drop CONSTRAINTS from other tables referencing the existing one +ALTER TABLE _timescaledb_config.bgw_job + DROP CONSTRAINT bgw_job_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.chunk + DROP CONSTRAINT chunk_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.chunk_index + DROP CONSTRAINT chunk_index_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.continuous_agg + DROP CONSTRAINT continuous_agg_mat_hypertable_id_fkey, + DROP CONSTRAINT continuous_agg_raw_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.continuous_aggs_bucket_function + DROP CONSTRAINT continuous_aggs_bucket_function_mat_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold + DROP CONSTRAINT continuous_aggs_invalidation_threshold_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.dimension + DROP CONSTRAINT dimension_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.hypertable + DROP CONSTRAINT hypertable_compressed_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.hypertable_compression + DROP CONSTRAINT hypertable_compression_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.hypertable_data_node + DROP CONSTRAINT hypertable_data_node_hypertable_id_fkey; +ALTER TABLE _timescaledb_catalog.tablespace + DROP CONSTRAINT tablespace_hypertable_id_fkey; + +-- drop dependent views +ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.hypertables; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.job_stats; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.jobs; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.continuous_aggregates; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.chunks; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.dimensions; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.compression_settings; +ALTER EXTENSION timescaledb DROP VIEW _timescaledb_internal.hypertable_chunk_local_size; +ALTER EXTENSION timescaledb DROP VIEW _timescaledb_internal.compressed_chunk_stats; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_experimental.chunk_replication_status; +ALTER EXTENSION timescaledb DROP VIEW timescaledb_experimental.policies; + +DROP VIEW timescaledb_information.hypertables; +DROP VIEW timescaledb_information.job_stats; +DROP VIEW timescaledb_information.jobs; +DROP VIEW timescaledb_information.continuous_aggregates; +DROP VIEW timescaledb_information.chunks; +DROP VIEW timescaledb_information.dimensions; +DROP VIEW timescaledb_information.compression_settings; +DROP VIEW _timescaledb_internal.hypertable_chunk_local_size; +DROP VIEW _timescaledb_internal.compressed_chunk_stats; +DROP VIEW timescaledb_experimental.chunk_replication_status; +DROP VIEW timescaledb_experimental.policies; + +-- recreate table +CREATE TABLE _timescaledb_catalog.hypertable_tmp AS SELECT * FROM _timescaledb_catalog.hypertable; +CREATE TABLE _timescaledb_catalog.tmp_hypertable_seq_value AS SELECT last_value, is_called FROM _timescaledb_catalog.hypertable_id_seq; + +ALTER EXTENSION timescaledb DROP TABLE _timescaledb_catalog.hypertable; +ALTER EXTENSION timescaledb DROP SEQUENCE _timescaledb_catalog.hypertable_id_seq; + +SET timescaledb.restoring = on; -- must disable the hooks otherwise we can't do anything without the table _timescaledb_catalog.hypertable + +DROP TABLE _timescaledb_catalog.hypertable; + +CREATE SEQUENCE _timescaledb_catalog.hypertable_id_seq MINVALUE 1; +SELECT setval('_timescaledb_catalog.hypertable_id_seq', last_value, is_called) FROM _timescaledb_catalog.tmp_hypertable_seq_value; +DROP TABLE _timescaledb_catalog.tmp_hypertable_seq_value; + +CREATE TABLE _timescaledb_catalog.hypertable ( + id INTEGER PRIMARY KEY NOT NULL DEFAULT nextval('_timescaledb_catalog.hypertable_id_seq'), + schema_name name NOT NULL, + table_name name NOT NULL, + associated_schema_name name NOT NULL, + associated_table_prefix name NOT NULL, + num_dimensions smallint NOT NULL, + chunk_sizing_func_schema name NOT NULL, + chunk_sizing_func_name name NOT NULL, + chunk_target_size bigint NOT NULL, -- size in bytes + compression_state smallint NOT NULL DEFAULT 0, + compressed_hypertable_id integer, + replication_factor smallint NULL +); + +SET timescaledb.restoring = off; + +INSERT INTO _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 +) +SELECT + 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 +FROM + _timescaledb_catalog.hypertable_tmp +ORDER BY id; + +ALTER SEQUENCE _timescaledb_catalog.hypertable_id_seq OWNED BY _timescaledb_catalog.hypertable.id; +SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.hypertable', 'WHERE id >= 1'); +SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.hypertable_id_seq', ''); + +GRANT SELECT ON _timescaledb_catalog.hypertable TO PUBLIC; +GRANT SELECT ON _timescaledb_catalog.hypertable_id_seq TO PUBLIC; + +DROP TABLE _timescaledb_catalog.hypertable_tmp; +-- now add any constraints +ALTER TABLE _timescaledb_catalog.hypertable + -- ADD CONSTRAINT hypertable_pkey PRIMARY KEY (id), + ADD CONSTRAINT hypertable_associated_schema_name_associated_table_prefix_key UNIQUE (associated_schema_name, associated_table_prefix), + ADD CONSTRAINT hypertable_table_name_schema_name_key UNIQUE (table_name, schema_name), + ADD CONSTRAINT hypertable_schema_name_check CHECK (schema_name != '_timescaledb_catalog'), + -- internal compressed hypertables have compression state = 2 + ADD CONSTRAINT hypertable_dim_compress_check CHECK (num_dimensions > 0 OR compression_state = 2), + ADD CONSTRAINT hypertable_chunk_target_size_check CHECK (chunk_target_size >= 0), + ADD CONSTRAINT hypertable_compress_check CHECK ( (compression_state = 0 OR compression_state = 1 ) OR (compression_state = 2 AND compressed_hypertable_id IS NULL)), + -- replication_factor NULL: regular hypertable + -- replication_factor > 0: distributed hypertable on access node + -- replication_factor -1: distributed hypertable on data node, which is part of a larger table + ADD CONSTRAINT hypertable_replication_factor_check CHECK (replication_factor > 0 OR replication_factor = -1), + ADD CONSTRAINT hypertable_compressed_hypertable_id_fkey FOREIGN KEY (compressed_hypertable_id) REFERENCES _timescaledb_catalog.hypertable (id); + +GRANT SELECT ON TABLE _timescaledb_catalog.hypertable TO PUBLIC; + +-- 3. reestablish constraints on other tables +ALTER TABLE _timescaledb_config.bgw_job + ADD CONSTRAINT bgw_job_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.chunk + ADD CONSTRAINT chunk_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id); +ALTER TABLE _timescaledb_catalog.chunk_index + ADD CONSTRAINT chunk_index_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.continuous_agg + ADD CONSTRAINT continuous_agg_mat_hypertable_id_fkey FOREIGN KEY (mat_hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE, + ADD CONSTRAINT continuous_agg_raw_hypertable_id_fkey FOREIGN KEY (raw_hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.continuous_aggs_bucket_function + ADD CONSTRAINT continuous_aggs_bucket_function_mat_hypertable_id_fkey FOREIGN KEY (mat_hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold + ADD CONSTRAINT continuous_aggs_invalidation_threshold_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.dimension + ADD CONSTRAINT dimension_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.hypertable_compression + ADD CONSTRAINT hypertable_compression_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; +ALTER TABLE _timescaledb_catalog.hypertable_data_node + ADD CONSTRAINT hypertable_data_node_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id); +ALTER TABLE _timescaledb_catalog.tablespace + ADD CONSTRAINT tablespace_hypertable_id_fkey FOREIGN KEY (hypertable_id) REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE; diff --git a/src/chunk.c b/src/chunk.c index bdb6ee8f809..2ab7219cc78 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -4609,6 +4609,12 @@ add_foreign_table_as_chunk(Oid relid, Hypertable *parent_ht) ts_chunk_constraints_add_dimension_constraints(chunk->constraints, chunk->fd.id, chunk->cube); ts_chunk_constraints_insert_metadata(chunk->constraints); chunk_add_inheritance(chunk, parent_ht); + /* Update hypertable entry with tiering status information and set overlap flag since the range + * is invalid */ + parent_ht->fd.status = + ts_set_flags_32(parent_ht->fd.status, + HYPERTABLE_STATUS_OSM | HYPERTABLE_STATUS_OSM_CHUNKS_OVERLAP); + ts_hypertable_update(parent_ht); } void @@ -4855,3 +4861,11 @@ ts_chunk_get_osm_chunk_id(int hypertable_id) return chunk_id; } + +/* when a tiered chunk is created, it is assigned a range [INT64_MAX -1, infinity) + XXX could a range start less than INT64_MAX - 1 be a valid range? */ +bool +ts_osm_chunk_range_is_invalid(Oid dimtype, int64 range_start, int64 range_end) +{ + return ((range_end == PG_INT64_MAX) && (range_start == range_end - 1)); +} diff --git a/src/chunk.h b/src/chunk.h index cc3c82fa45f..7e8b0204585 100644 --- a/src/chunk.h +++ b/src/chunk.h @@ -309,5 +309,7 @@ extern TSDLLEXPORT void ts_chunk_merge_on_dimension(const Hypertable *ht, Chunk #define CHUNK_STATUS_COMPRESSED_PARTIAL 8 extern TSDLLEXPORT bool ts_chunk_clear_status(Chunk *chunk, int32 status); +extern TSDLLEXPORT bool ts_osm_chunk_range_is_invalid(Oid dimtype, int64 range_start, + int64 range_end); #endif /* TIMESCALEDB_CHUNK_H */ diff --git a/src/dimension_slice.c b/src/dimension_slice.c index 64fa6cc0e8b..b9741132207 100644 --- a/src/dimension_slice.c +++ b/src/dimension_slice.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ #include "dimension_vector.h" #include "hypertable.h" #include "scanner.h" +#include "hypercube.h" #include "compat/compat.h" @@ -1148,3 +1150,193 @@ ts_dimension_slice_get_chunkids_to_compress(int32 dimension_id, StrategyNumber s return chunk_ids; } + +/* This function checks for overlap between the range we want to update + for the OSM chunk and the chunks currently in timescaledb (not managed by OSM) + */ +static bool +ts_osm_chunk_range_overlaps(int32 osm_dimension_slice_id, int32 dimension_id, int64 range_start, + int64 range_end) +{ + bool res; + DimensionVec *vec = dimension_slice_collision_scan(dimension_id, range_start, range_end); + /* there is only one dimension slice for the OSM chunk. The OSM chunk may not + * necessarily appear in the list of overlapping ranges because when first tiered, + * it is given a range [max, infinity) + */ + if (vec->num_slices >= 2 || + (vec->num_slices == 1 && vec->slices[0]->fd.id != osm_dimension_slice_id)) + res = true; + else + res = false; + pfree(vec); + return res; +} + +static ScanTupleResult +dimension_slice_tuple_update(TupleInfo *ti, void *data) +{ + bool should_free; + HeapTuple tuple = ts_scanner_fetch_heap_tuple(ti, false, &should_free); + FormData_dimension_slice *fd = (FormData_dimension_slice *) data; + + Datum values[Natts_dimension_slice] = { 0 }; + bool isnull[Natts_dimension_slice] = { 0 }; + bool doReplace[Natts_dimension_slice] = { 0 }; + + values[AttrNumberGetAttrOffset(Anum_dimension_slice_range_start)] = + Int64GetDatum(fd->range_start); + doReplace[AttrNumberGetAttrOffset(Anum_dimension_slice_range_start)] = true; + + values[AttrNumberGetAttrOffset(Anum_dimension_slice_range_end)] = Int64GetDatum(fd->range_end); + doReplace[AttrNumberGetAttrOffset(Anum_dimension_slice_range_end)] = true; + + HeapTuple new_tuple = + heap_modify_tuple(tuple, ts_scanner_get_tupledesc(ti), values, isnull, doReplace); + + ts_catalog_update(ti->scanrel, new_tuple); + + heap_freetuple(new_tuple); + if (should_free) + heap_freetuple(tuple); + + return SCAN_DONE; +} + +static int +dimension_slice_update_by_id(int32 dimension_slice_id, FormData_dimension_slice *fd_slice) +{ + ScanKeyData scankey[1]; + + ScanKeyInit(&scankey[0], + Anum_dimension_slice_id_idx_id, + BTEqualStrategyNumber, + F_INT4EQ, + Int32GetDatum(dimension_slice_id)); + + return dimension_slice_scan_limit_internal(DIMENSION_SLICE_ID_IDX, + scankey, + 1, + dimension_slice_tuple_update, + fd_slice, + 1, + RowExclusiveLock, + NULL, + CurrentMemoryContext); +} + +static int32 +ts_chunk_get_osm_slice_id(int32 chunk_id, int32 time_dim_id) +{ + Chunk *chunk = ts_chunk_get_by_id(chunk_id, true); + const DimensionSlice *ds = ts_hypercube_get_slice_by_dimension_id(chunk->cube, time_dim_id); + const int slice_id = ds->fd.id; + return slice_id; +} + +/* + * hypertable_update_range_for_osm + * 0 hypertable REGCLASS, + * 1 range_start, + * 2 range_end, + * 3 empty=false + * If empty is set to true then the range will be set to invalid range + * but the overlap flag will be unset, indicating that no data is managed + * by OSM and therefore timescaledb optimizations can be applied. + */ +TS_FUNCTION_INFO_V1(ts_hypertable_update_range_for_osm); +Datum +ts_hypertable_update_range_for_osm(PG_FUNCTION_ARGS) +{ + Oid relid = PG_ARGISNULL(0) ? InvalidOid : PG_GETARG_OID(0); + Hypertable *ht; + const Dimension *time_dim; + Cache *hcache; + + Oid time_type; /* required for resolving the argument types, should match the hypertable + partitioning column type */ + + hcache = ts_hypertable_cache_pin(); + ht = ts_resolve_hypertable_from_table_or_cagg(hcache, relid, true); + Assert(ht != NULL); + time_dim = hyperspace_get_open_dimension(ht->space, 0); + + Ensure(time_dim != NULL, + "could not find time dimension for hypertable %s.%s", + quote_identifier(NameStr(ht->fd.schema_name)), + quote_identifier(NameStr(ht->fd.table_name))); + + time_type = ts_dimension_get_partition_type(time_dim); + + int32 osm_chunk_id = ts_chunk_get_osm_chunk_id(ht->fd.id); + if (osm_chunk_id == INVALID_CHUNK_ID) + elog(ERROR, + "no OSM chunk found for hypertable %s.%s", + quote_identifier(NameStr(ht->fd.schema_name)), + quote_identifier(NameStr(ht->fd.table_name))); + + int32 dimension_slice_id = ts_chunk_get_osm_slice_id(osm_chunk_id, time_dim->fd.id); + + /* + * range_start, range_end arguments must be converted to internal representation + * a NULL start value is interpreted as INT64_MAX - 1 and a NULL end value is + * interpreted as infinity. + * Passing both start and end NULL values will reset the range to the default range an + * OSM chunk is given upon creation, which is [INT64_MAX - 1, INT64_MAX] + */ + int64 range_start_internal, range_end_internal; + if (PG_ARGISNULL(1)) + range_start_internal = PG_INT64_MAX - 1; + else + range_start_internal = ts_time_value_to_internal(PG_GETARG_DATUM(1), time_type); + if (PG_ARGISNULL(2)) + range_end_internal = PG_INT64_MAX; + else + range_end_internal = ts_time_value_to_internal(PG_GETARG_DATUM(2), time_type); + + if (range_start_internal > range_end_internal) + ereport(ERROR, errmsg("dimension slice range_end cannot be less than range_start")); + + bool osm_chunk_empty = PG_GETARG_BOOL(3); + + bool overlap = false, range_invalid = false; + + ScanTupLock tuplock = { + .lockmode = LockTupleExclusive, + .waitpolicy = LockWaitBlock, + }; + DimensionSlice *slice = + ts_dimension_slice_scan_by_id_and_lock(dimension_slice_id, &tuplock, CurrentMemoryContext); + + if (!slice) + ereport(ERROR, errmsg("could not find slice with id %d", dimension_slice_id)); + overlap = ts_osm_chunk_range_overlaps(dimension_slice_id, + slice->fd.dimension_id, + range_start_internal, + range_end_internal); + range_invalid = + ts_osm_chunk_range_is_invalid(time_type, range_start_internal, range_end_internal); + /* Update the hypertable flags regarding the validity of the OSM range */ + if (overlap || range_invalid) + { + if (!osm_chunk_empty) + ht->fd.status = ts_set_flags_32(ht->fd.status, HYPERTABLE_STATUS_OSM_CHUNKS_OVERLAP); + else + { + /* range is also set to infinity so the OSM chunk is considered last */ + range_start_internal = PG_INT64_MAX - 1; + range_end_internal = PG_INT64_MAX; + ht->fd.status = ts_clear_flags_32(ht->fd.status, HYPERTABLE_STATUS_OSM_CHUNKS_OVERLAP); + } + } + else + ht->fd.status = ts_clear_flags_32(ht->fd.status, HYPERTABLE_STATUS_OSM_CHUNKS_OVERLAP); + ts_hypertable_update(ht); + ts_cache_release(hcache); + + slice->fd.range_start = range_start_internal; + slice->fd.range_end = range_end_internal; + dimension_slice_update_by_id(dimension_slice_id, &slice->fd); + + PG_RETURN_BOOL(overlap); +} diff --git a/src/hypertable.c b/src/hypertable.c index 2c40bef16d1..e80c93e4ee7 100644 --- a/src/hypertable.c +++ b/src/hypertable.c @@ -172,6 +172,7 @@ hypertable_formdata_make_tuple(const FormData_hypertable *fd, TupleDesc desc) else values[AttrNumberGetAttrOffset(Anum_hypertable_replication_factor)] = Int16GetDatum(fd->replication_factor); + values[AttrNumberGetAttrOffset(Anum_hypertable_status)] = Int32GetDatum(fd->status); return heap_form_tuple(desc, values, nulls); } @@ -197,6 +198,7 @@ ts_hypertable_formdata_fill(FormData_hypertable *fd, const TupleInfo *ti) Assert(!nulls[AttrNumberGetAttrOffset(Anum_hypertable_chunk_sizing_func_name)]); Assert(!nulls[AttrNumberGetAttrOffset(Anum_hypertable_chunk_target_size)]); Assert(!nulls[AttrNumberGetAttrOffset(Anum_hypertable_compression_state)]); + Assert(!nulls[AttrNumberGetAttrOffset(Anum_hypertable_status)]); fd->id = DatumGetInt32(values[AttrNumberGetAttrOffset(Anum_hypertable_id)]); memcpy(&fd->schema_name, @@ -237,6 +239,7 @@ ts_hypertable_formdata_fill(FormData_hypertable *fd, const TupleInfo *ti) else fd->replication_factor = DatumGetInt16(values[AttrNumberGetAttrOffset(Anum_hypertable_replication_factor)]); + fd->status = DatumGetInt32(values[AttrNumberGetAttrOffset(Anum_hypertable_status)]); if (should_free) heap_freetuple(tuple); @@ -1003,6 +1006,9 @@ hypertable_insert(int32 hypertable_id, Name schema_name, Name table_name, /* when creating a hypertable, there is never an associated compressed dual */ fd.compressed_hypertable_id = INVALID_HYPERTABLE_ID; + /* new hypertable does not have OSM chunk */ + fd.status = HYPERTABLE_STATUS_DEFAULT; + /* finally, set replication factor */ fd.replication_factor = replication_factor; diff --git a/src/planner/planner.c b/src/planner/planner.c index 65ebeef0af2..fb08d85b06e 100644 --- a/src/planner/planner.c +++ b/src/planner/planner.c @@ -876,11 +876,15 @@ should_chunk_append(Hypertable *ht, PlannerInfo *root, RelOptInfo *rel, Path *pa if (!ordered || path->pathkeys == NIL || list_length(merge->subpaths) == 0) return false; - /* cannot support ordered append with OSM chunks. OSM chunk - * ranges are not recorded with the catalog + /* + * Cannot support ordered append with OSM chunks. + * OSM chunk ranges are not recorded with the catalog */ if (ht && ts_chunk_get_osm_chunk_id(ht->fd.id) != INVALID_CHUNK_ID) - return false; + { + if (ts_flags_are_set_32(ht->fd.status, HYPERTABLE_STATUS_OSM_CHUNKS_OVERLAP)) + return false; + } /* * If we only have 1 child node there is no need for the diff --git a/src/ts_catalog/catalog.h b/src/ts_catalog/catalog.h index a4b4b020bec..4598b68f3d1 100644 --- a/src/ts_catalog/catalog.h +++ b/src/ts_catalog/catalog.h @@ -119,6 +119,7 @@ enum Anum_hypertable Anum_hypertable_compression_state, Anum_hypertable_compressed_hypertable_id, Anum_hypertable_replication_factor, + Anum_hypertable_status, _Anum_hypertable_max, }; @@ -138,6 +139,7 @@ typedef struct FormData_hypertable int16 compression_state; int32 compressed_hypertable_id; int16 replication_factor; + int32 status; } FormData_hypertable; typedef FormData_hypertable *Form_hypertable; @@ -1484,6 +1486,10 @@ typedef struct FormData_job_error typedef FormData_job_error *Form_job_error; +#define HYPERTABLE_STATUS_DEFAULT 0 +#define HYPERTABLE_STATUS_OSM 1 +#define HYPERTABLE_STATUS_OSM_CHUNKS_OVERLAP 2 + extern void ts_catalog_table_info_init(CatalogTableInfo *tables, int max_table, const TableInfoDef *table_ary, const TableIndexDef *index_ary, const char **serial_id_ary); diff --git a/test/expected/alter.out b/test/expected/alter.out index 3c711c6ae2d..532cb07d2ba 100644 --- a/test/expected/alter.out +++ b/test/expected/alter.out @@ -675,9 +675,9 @@ ALTER SCHEMA my_associated_schema RENAME TO new_associated_schema; INSERT INTO my_table (date, quantity) VALUES ('2018-08-10T23:00:00+00:00', 20); -- Make sure the schema name is changed in both catalog tables 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_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 12 | public | my_table | new_associated_schema | _hyper_12 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) SELECT * from _timescaledb_catalog.chunk; diff --git a/test/expected/alternate_users.out b/test/expected/alternate_users.out index 7f76da07bac..cbabf5911a7 100644 --- a/test/expected/alternate_users.out +++ b/test/expected/alternate_users.out @@ -135,12 +135,12 @@ SELECT * FROM create_hypertable('"customSchema"."Hypertable_1"', 'time', NULL, 1 (1 row) 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_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 | | + 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 | status +----+--------------+---------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | one_Partition | one_Partition | _hyper_1 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | public | 1dim | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 3 | public | Hypertable_1 | _timescaledb_internal | _hyper_3 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 4 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_4 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (4 rows) CREATE INDEX ON PUBLIC."Hypertable_1" (time, "temp_c"); diff --git a/test/expected/create_hypertable.out b/test/expected/create_hypertable.out index 2d6d1081aa4..fe463f51e18 100644 --- a/test/expected/create_hypertable.out +++ b/test/expected/create_hypertable.out @@ -86,9 +86,9 @@ select add_dimension('test_schema.test_table', 'location', 4); (1 row) select * from _timescaledb_catalog.hypertable where table_name = 'test_table'; - 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 -----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+-------------------- - 2 | test_schema | test_table | chunk_schema | _hyper_2 | 3 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 2 | test_schema | test_table | chunk_schema | _hyper_2 | 3 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) select * from _timescaledb_catalog.dimension; @@ -149,9 +149,9 @@ NOTICE: adding not-null constraint to column "id" (1 row) select * from _timescaledb_catalog.hypertable where table_name = 'test_table'; - 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 -----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+-------------------- - 2 | test_schema | test_table | chunk_schema | _hyper_2 | 4 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 2 | test_schema | test_table | chunk_schema | _hyper_2 | 4 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) select * from _timescaledb_catalog.dimension; @@ -541,9 +541,9 @@ NOTICE: migrating data to chunks --there should be two new chunks select * from _timescaledb_catalog.hypertable where table_name = 'test_migrate'; - 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 -----+-------------+--------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+-------------------- - 10 | test_schema | test_migrate | _timescaledb_internal | _hyper_10 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+--------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 10 | test_schema | test_migrate | _timescaledb_internal | _hyper_10 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) select * from _timescaledb_catalog.chunk; diff --git a/test/expected/ddl-13.out b/test/expected/ddl-13.out index ba33a2b5bec..bfd3b0bb527 100644 --- a/test/expected/ddl-13.out +++ b/test/expected/ddl-13.out @@ -43,10 +43,10 @@ SELECT * FROM create_hypertable('"customSchema"."Hypertable_1"', 'time', NULL, 1 (1 row) 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 | Hypertable_1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 2 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+--------------+--------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | Hypertable_1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (2 rows) CREATE INDEX ON PUBLIC."Hypertable_1" (time, "temp_c"); diff --git a/test/expected/ddl-14.out b/test/expected/ddl-14.out index 85aa8ab5297..a61e572e08f 100644 --- a/test/expected/ddl-14.out +++ b/test/expected/ddl-14.out @@ -43,10 +43,10 @@ SELECT * FROM create_hypertable('"customSchema"."Hypertable_1"', 'time', NULL, 1 (1 row) 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 | Hypertable_1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 2 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+--------------+--------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | Hypertable_1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (2 rows) CREATE INDEX ON PUBLIC."Hypertable_1" (time, "temp_c"); diff --git a/test/expected/ddl-15.out b/test/expected/ddl-15.out index 85aa8ab5297..a61e572e08f 100644 --- a/test/expected/ddl-15.out +++ b/test/expected/ddl-15.out @@ -43,10 +43,10 @@ SELECT * FROM create_hypertable('"customSchema"."Hypertable_1"', 'time', NULL, 1 (1 row) 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 | Hypertable_1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 2 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+--------------+--------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | Hypertable_1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | customSchema | Hypertable_1 | _timescaledb_internal | _hyper_2 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (2 rows) CREATE INDEX ON PUBLIC."Hypertable_1" (time, "temp_c"); diff --git a/test/expected/drop_extension.out b/test/expected/drop_extension.out index a6738fedd0d..7e9f728fe07 100644 --- a/test/expected/drop_extension.out +++ b/test/expected/drop_extension.out @@ -11,9 +11,9 @@ NOTICE: adding not-null constraint to column "time" (1 row) 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 | drop_test | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | drop_test | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) INSERT INTO drop_test VALUES('Mon Mar 20 09:17:00.936242 2017', 23.4, 'dev1'); @@ -57,9 +57,9 @@ WARNING: column type "timestamp without time zone" used for "time" does not fol (1 row) 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 | drop_test | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | drop_test | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) INSERT INTO drop_test VALUES('Mon Mar 20 09:18:19.100462 2017', 22.1, 'dev1'); diff --git a/test/expected/drop_hypertable.out b/test/expected/drop_hypertable.out index 4833780b975..0ca624f1783 100644 --- a/test/expected/drop_hypertable.out +++ b/test/expected/drop_hypertable.out @@ -2,8 +2,8 @@ -- Please see the included NOTICE for copyright information and -- LICENSE-APACHE for a copy of the license. 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 -----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+-------------------- + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+--------------------+-------- (0 rows) SELECT * from _timescaledb_catalog.dimension; @@ -76,9 +76,9 @@ NOTICE: table "should_drop" is already a hypertable, skipping (1 row) 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 | should_drop | _timescaledb_internal | _hyper_1 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+-------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | should_drop | _timescaledb_internal | _hyper_1 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) SELECT * from _timescaledb_catalog.dimension; @@ -99,9 +99,9 @@ NOTICE: adding not-null constraint to column "time" INSERT INTO should_drop VALUES (now(), 1.0); 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 -----+-------------+-------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+-------------------- - 4 | public | should_drop | _timescaledb_internal | _hyper_4 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+-------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 4 | public | should_drop | _timescaledb_internal | _hyper_4 | 1 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) SELECT * from _timescaledb_catalog.dimension; diff --git a/test/expected/drop_owned.out b/test/expected/drop_owned.out index bfcd4b96e14..238784ee7ae 100644 --- a/test/expected/drop_owned.out +++ b/test/expected/drop_owned.out @@ -25,10 +25,10 @@ NOTICE: adding not-null constraint to column "time" INSERT INTO hypertable_schema.superuser VALUES ('2001-01-01 01:01:01', 23.3, 1); SELECT * FROM _timescaledb_catalog.hypertable ORDER BY id; - 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 | hypertable_schema | default_perm_user | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 2 | hypertable_schema | superuser | _timescaledb_internal | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------------+-------------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | hypertable_schema | default_perm_user | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | hypertable_schema | superuser | _timescaledb_internal | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (2 rows) SELECT * FROM _timescaledb_catalog.chunk; @@ -40,9 +40,9 @@ SELECT * FROM _timescaledb_catalog.chunk; DROP OWNED BY :ROLE_DEFAULT_PERM_USER; SELECT * FROM _timescaledb_catalog.hypertable ORDER BY id; - 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 -----+-------------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+-------------------- - 2 | hypertable_schema | superuser | _timescaledb_internal | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 2 | hypertable_schema | superuser | _timescaledb_internal | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) SELECT * FROM _timescaledb_catalog.chunk; @@ -54,8 +54,8 @@ SELECT * FROM _timescaledb_catalog.chunk; DROP TABLE hypertable_schema.superuser; --everything should be cleaned up SELECT * FROM _timescaledb_catalog.hypertable GROUP BY id; - 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 -----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+-------------------- + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+--------------------+-------- (0 rows) SELECT * FROM _timescaledb_catalog.chunk; diff --git a/test/expected/drop_rename_hypertable.out b/test/expected/drop_rename_hypertable.out index 4a26a2aa4dd..0ba03bd6609 100644 --- a/test/expected/drop_rename_hypertable.out +++ b/test/expected/drop_rename_hypertable.out @@ -146,9 +146,9 @@ SELECT * FROM "newname"; (12 rows) 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 | newname | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | newname | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) \c :TEST_DBNAME :ROLE_SUPERUSER @@ -173,15 +173,15 @@ SELECT * FROM "newschema"."newname"; (12 rows) 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 | newschema | newname | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | newschema | newname | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) DROP TABLE "newschema"."newname"; 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 -----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+-------------------- + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+--------------------+-------- (0 rows) \dt "public".* diff --git a/test/expected/drop_schema.out b/test/expected/drop_schema.out index 046abd4eddb..b12375cd041 100644 --- a/test/expected/drop_schema.out +++ b/test/expected/drop_schema.out @@ -30,10 +30,10 @@ NOTICE: adding not-null constraint to column "time" INSERT INTO hypertable_schema.test1 VALUES ('2001-01-01 01:01:01', 23.3, 1); INSERT INTO hypertable_schema.test2 VALUES ('2001-01-01 01:01:01', 23.3, 1); SELECT * FROM _timescaledb_catalog.hypertable ORDER BY id; - 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 | hypertable_schema | test1 | chunk_schema1 | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 2 | hypertable_schema | test2 | chunk_schema2 | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | hypertable_schema | test1 | chunk_schema1 | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | hypertable_schema | test2 | chunk_schema2 | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (2 rows) SELECT * FROM _timescaledb_catalog.chunk; @@ -53,10 +53,10 @@ SET ROLE :ROLE_DEFAULT_PERM_USER; --show that the metadata for the table using the dropped schema is --changed. The other table is not affected. SELECT * FROM _timescaledb_catalog.hypertable ORDER BY id; - 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 | hypertable_schema | test1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 2 | hypertable_schema | test2 | chunk_schema2 | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | hypertable_schema | test1 | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | hypertable_schema | test2 | chunk_schema2 | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (2 rows) SELECT * FROM _timescaledb_catalog.chunk; @@ -86,8 +86,8 @@ NOTICE: drop cascades to 4 other objects SET ROLE :ROLE_DEFAULT_PERM_USER; --everything should be cleaned up SELECT * FROM _timescaledb_catalog.hypertable GROUP BY id; - 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 -----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+-------------------- + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+------------------------+-------------------+-------------------+--------------------------+--------------------+-------- (0 rows) SELECT * FROM _timescaledb_catalog.chunk; diff --git a/test/expected/dump_meta.out b/test/expected/dump_meta.out index 7086798f41c..e359fa6ac3c 100644 --- a/test/expected/dump_meta.out +++ b/test/expected/dump_meta.out @@ -66,9 +66,9 @@ List of tables \echo 'List of hypertables' List of hypertables 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 | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+----------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) \echo 'List of chunk indexes' diff --git a/test/expected/pg_dump.out b/test/expected/pg_dump.out index a862ab2db83..a4743238458 100644 --- a/test/expected/pg_dump.out +++ b/test/expected/pg_dump.out @@ -77,9 +77,9 @@ WARNING: target chunk size for adaptive chunking is less than 10 MB -- Chunk sizing func set 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 | test_schema | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | public | custom_calculate_chunk_interval | 1048576 | 0 | | + 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 | status +----+-------------+----------------+------------------------+-------------------------+----------------+--------------------------+---------------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | test_schema | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | public | custom_calculate_chunk_interval | 1048576 | 0 | | | 0 (1 row) SELECT proname, pronamespace, pronargs @@ -518,9 +518,9 @@ SELECT * FROM _timescaledb_catalog.chunk_constraint; --Chunk sizing function should have been restored 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 | test_schema | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | public | custom_calculate_chunk_interval | 1048576 | 0 | | + 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 | status +----+-------------+----------------+------------------------+-------------------------+----------------+--------------------------+---------------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | test_schema | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | public | custom_calculate_chunk_interval | 1048576 | 0 | | | 0 (1 row) SELECT proname, pronamespace, pronargs diff --git a/test/expected/relocate_extension.out b/test/expected/relocate_extension.out index c7555db5764..a25d73ed32b 100644 --- a/test/expected/relocate_extension.out +++ b/test/expected/relocate_extension.out @@ -38,11 +38,11 @@ NOTICE: adding not-null constraint to column "time" (1 row) 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 | test_ts | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 2 | public | test_tz | _timescaledb_internal | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | - 3 | public | test_dt | _timescaledb_internal | _hyper_3 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | test_ts | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 2 | public | test_tz | _timescaledb_internal | _hyper_2 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 + 3 | public | test_dt | _timescaledb_internal | _hyper_3 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (3 rows) INSERT INTO test_ts VALUES('Mon Mar 20 09:17:00.936242 2017', 23.4, 'dev1'); diff --git a/test/expected/truncate.out b/test/expected/truncate.out index 6c44ccd2fb6..ac227ef84c7 100644 --- a/test/expected/truncate.out +++ b/test/expected/truncate.out @@ -35,9 +35,9 @@ INSERT INTO "two_Partitions"("timeCustom", device_id, series_0, series_1) VALUES \set QUIET on \o 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 | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+----------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) SELECT * FROM _timescaledb_catalog.chunk; @@ -78,9 +78,9 @@ SELECT * FROM "two_Partitions"; SET client_min_messages = WARNING; TRUNCATE "two_Partitions"; 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 | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | + 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 | status +----+-------------+----------------+------------------------+-------------------------+----------------+--------------------------+--------------------------+-------------------+-------------------+--------------------------+--------------------+-------- + 1 | public | two_Partitions | _timescaledb_internal | _hyper_1 | 2 | _timescaledb_functions | calculate_chunk_interval | 0 | 0 | | | 0 (1 row) SELECT * FROM _timescaledb_catalog.chunk; diff --git a/tsl/test/expected/chunk_utils_internal.out b/tsl/test/expected/chunk_utils_internal.out index a51ab75d681..c7a8ea5aaeb 100644 --- a/tsl/test/expected/chunk_utils_internal.out +++ b/tsl/test/expected/chunk_utils_internal.out @@ -514,6 +514,11 @@ SELECT * FROM child_fdw_table; Wed Jan 01 01:00:00 2020 PST | 100 | 1000 (1 row) +-- error should be thrown as the hypertable does not yet have an associated tiered chunk +\set ON_ERROR_STOP 0 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try','2020-01-01 01:00'::timestamptz, '2020-01-01 03:00'); +ERROR: no OSM chunk found for hypertable public.ht_try +\set ON_ERROR_STOP 1 SELECT _timescaledb_functions.attach_osm_table_chunk('ht_try', 'child_fdw_table'); attach_osm_table_chunk ------------------------ @@ -596,6 +601,94 @@ SELECT * from ht_try WHERE timec > '2020-01-01 01:00' ORDER BY 1; Thu May 05 01:00:00 2022 PDT | 222 | 222 (1 row) +-- test ordered append +BEGIN; +-- before updating the ranges +EXPLAIN SELECT * FROM ht_try ORDER BY 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Merge Append (cost=100.16..235.06 rows=3276 width=24) + Sort Key: _hyper_5_10_chunk.timec + -> Index Scan Backward using _hyper_5_10_chunk_ht_try_timec_idx on _hyper_5_10_chunk (cost=0.15..35.70 rows=1570 width=24) + -> Foreign Scan on child_fdw_table (cost=100.00..166.59 rows=1706 width=24) +(4 rows) + +-- range before update +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.table_name = 'child_fdw_table' AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + chunk_id | table_name | status | osm_chunk | dimension_slice_id | range_start | range_end +----------+-----------------+--------+-----------+--------------------+---------------------+--------------------- + 11 | child_fdw_table | 0 | t | 10 | 9223371244800000000 | 9223372036854775807 +(1 row) + +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try', '2020-01-01 01:00'::timestamptz, '2020-01-02'); + hypertable_update_range_for_osm +--------------------------------- + f +(1 row) + +SELECT id, schema_name, table_name, status FROM _timescaledb_catalog.hypertable WHERE table_name = 'ht_try'; + id | schema_name | table_name | status +----+-------------+------------+-------- + 5 | public | ht_try | 1 +(1 row) + +-- verify range was updated +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.table_name = 'child_fdw_table' AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + chunk_id | table_name | status | osm_chunk | dimension_slice_id | range_start | range_end +----------+-----------------+--------+-----------+--------------------+------------------+------------------ + 11 | child_fdw_table | 0 | t | 10 | 1577869200000000 | 1577952000000000 +(1 row) + +-- should be ordered append now +EXPLAIN SELECT * FROM ht_try ORDER BY 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on ht_try (cost=100.00..202.29 rows=3276 width=24) + Order: ht_try.timec + -> Foreign Scan on child_fdw_table (cost=100.00..166.59 rows=1706 width=24) + -> Index Scan Backward using _hyper_5_10_chunk_ht_try_timec_idx on _hyper_5_10_chunk (cost=0.15..35.70 rows=1570 width=24) +(4 rows) + +SELECT * FROM ht_try ORDER BY 1; + timec | acq_id | value +------------------------------+--------+------- + Wed Jan 01 01:00:00 2020 PST | 100 | 1000 + Thu May 05 01:00:00 2022 PDT | 222 | 222 +(2 rows) + +-- test overlapping range - should not be ordered append +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try', '2022-05-05 01:00'::timestamptz, '2022-05-06'); + hypertable_update_range_for_osm +--------------------------------- + t +(1 row) + +EXPLAIN SELECT * from ht_try ORDER BY 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Merge Append (cost=100.16..235.06 rows=3276 width=24) + Sort Key: _hyper_5_10_chunk.timec + -> Index Scan Backward using _hyper_5_10_chunk_ht_try_timec_idx on _hyper_5_10_chunk (cost=0.15..35.70 rows=1570 width=24) + -> Foreign Scan on child_fdw_table (cost=100.00..166.59 rows=1706 width=24) +(4 rows) + +SELECT * from ht_try ORDER BY 1; + timec | acq_id | value +------------------------------+--------+------- + Wed Jan 01 01:00:00 2020 PST | 100 | 1000 + Thu May 05 01:00:00 2022 PDT | 222 | 222 +(2 rows) + +ROLLBACK; +\set ON_ERROR_STOP 0 +-- test that error is produced +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try', '2020-01-02 01:00'::timestamptz, '2020-01-02 00:00'); +ERROR: dimension slice range_end cannot be less than range_start +\set ON_ERROR_STOP 1 --TEST GUC variable to enable/disable OSM chunk SET timescaledb.enable_tiered_reads=false; EXPLAIN (COSTS OFF) SELECT * from ht_try; @@ -910,6 +1003,185 @@ SELECT indexname, tablename FROM pg_indexes WHERE indexname = 'hyper_constr_mid_ (1 row) DROP INDEX hyper_constr_mid_idx; +-- test that correct slice is found and updated for table with multiple chunk constraints +CREATE TABLE test_multicon(time timestamptz not null unique, a int); +SELECT hypertable_id as htid FROM create_hypertable('test_multicon', 'time', chunk_time_interval => interval '1 day') \gset +insert into test_multicon values ('2020-01-02 01:00'::timestamptz, 1); +SELECT * FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc WHERE c.hypertable_id = :htid +AND c.id = cc.chunk_id; + id | hypertable_id | schema_name | table_name | compressed_chunk_id | dropped | status | osm_chunk | chunk_id | dimension_slice_id | constraint_name | hypertable_constraint_name +----+---------------+-----------------------+-------------------+---------------------+---------+--------+-----------+----------+--------------------+-----------------------------+---------------------------- + 17 | 9 | _timescaledb_internal | _hyper_9_17_chunk | | f | 0 | f | 17 | | 17_3_test_multicon_time_key | test_multicon_time_key + 17 | 9 | _timescaledb_internal | _hyper_9_17_chunk | | f | 0 | f | 17 | 17 | constraint_17 | +(2 rows) + +\c :TEST_DBNAME :ROLE_SUPERUSER ; +UPDATE _timescaledb_catalog.chunk SET osm_chunk = true WHERE hypertable_id = :htid; +\c :TEST_DBNAME :ROLE_4; +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_multicon', '2020-01-02 01:00'::timestamptz, '2020-01-04 01:00'); + hypertable_update_range_for_osm +--------------------------------- + f +(1 row) + +-- view udpated range +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + chunk_id | table_name | status | osm_chunk | dimension_slice_id | range_start | range_end +----------+-------------------+--------+-----------+--------------------+------------------+------------------ + 17 | _hyper_9_17_chunk | 0 | t | 17 | 1577955600000000 | 1578128400000000 +(1 row) + +-- check that range was reset to default - infinity +\set ON_ERROR_STOP 0 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_multicon', NULL, '2020-01-04 01:00'::timestamptz); +ERROR: dimension slice range_end cannot be less than range_start +\set ON_ERROR_STOP 1 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_multicon', NULL::timestamptz, NULL); + hypertable_update_range_for_osm +--------------------------------- + f +(1 row) + +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + chunk_id | table_name | status | osm_chunk | dimension_slice_id | range_start | range_end +----------+-------------------+--------+-----------+--------------------+---------------------+--------------------- + 17 | _hyper_9_17_chunk | 0 | t | 17 | 9223372036854775806 | 9223372036854775807 +(1 row) + +-- test further with ordered append +\c postgres_fdw_db :ROLE_4; +CREATE TABLE test_chunkapp_fdw (time timestamptz NOT NULL, a int); +INSERT INTO test_chunkapp_fdw (time, a) VALUES ('2020-01-03 02:00'::timestamptz, 3); +\c :TEST_DBNAME :ROLE_4 +CREATE TABLE test_chunkapp(time timestamptz NOT NULL, a int); +SELECT hypertable_id as htid FROM create_hypertable('test_chunkapp', 'time', chunk_time_interval => interval '1day') \gset +INSERT INTO test_chunkapp (time, a) VALUES ('2020-01-01 01:00'::timestamptz, 1), ('2020-01-02 01:00'::timestamptz, 2); +CREATE FOREIGN TABLE test_chunkapp_fdw_child(time timestamptz NOT NULL, a int) SERVER s3_server OPTIONS (schema_name 'public', table_name 'test_chunkapp_fdw');; +SELECT _timescaledb_functions.attach_osm_table_chunk('test_chunkapp','test_chunkapp_fdw_child'); + attach_osm_table_chunk +------------------------ + t +(1 row) + +-- view range before update +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + chunk_id | table_name | status | osm_chunk | dimension_slice_id | range_start | range_end +----------+-------------------------+--------+-----------+--------------------+---------------------+--------------------- + 18 | _hyper_10_18_chunk | 0 | f | 18 | 1577836800000000 | 1577923200000000 + 19 | _hyper_10_19_chunk | 0 | f | 19 | 1577923200000000 | 1578009600000000 + 20 | test_chunkapp_fdw_child | 0 | t | 20 | 9223371244800000000 | 9223372036854775807 +(3 rows) + +-- update range +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', '2020-01-02 01:00'::timestamptz, '2020-01-04 01:00'); + hypertable_update_range_for_osm +--------------------------------- + t +(1 row) + +-- view udpated range +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + chunk_id | table_name | status | osm_chunk | dimension_slice_id | range_start | range_end +----------+-------------------------+--------+-----------+--------------------+------------------+------------------ + 18 | _hyper_10_18_chunk | 0 | f | 18 | 1577836800000000 | 1577923200000000 + 19 | _hyper_10_19_chunk | 0 | f | 19 | 1577923200000000 | 1578009600000000 + 20 | test_chunkapp_fdw_child | 0 | t | 20 | 1577955600000000 | 1578128400000000 +(3 rows) + +-- ordered append should not be possible as ranges overlapped +EXPLAIN SELECT * FROM test_chunkapp ORDER BY 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Merge Append (cost=100.33..352.47 rows=6355 width=12) + Sort Key: _hyper_10_18_chunk."time" + -> Index Scan Backward using _hyper_10_18_chunk_test_chunkapp_time_idx on _hyper_10_18_chunk (cost=0.15..42.75 rows=2040 width=12) + -> Index Scan Backward using _hyper_10_19_chunk_test_chunkapp_time_idx on _hyper_10_19_chunk (cost=0.15..42.75 rows=2040 width=12) + -> Foreign Scan on test_chunkapp_fdw_child (cost=100.00..184.80 rows=2275 width=12) +(5 rows) + +SELECT * FROM test_chunkapp ORDER BY 1; + time | a +------------------------------+--- + Wed Jan 01 01:00:00 2020 PST | 1 + Thu Jan 02 01:00:00 2020 PST | 2 + Fri Jan 03 02:00:00 2020 PST | 3 +(3 rows) + +-- check that range is reset to default - infinity +\set ON_ERROR_STOP 0 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', NULL, '2020-01-04 01:00'::timestamptz); +ERROR: dimension slice range_end cannot be less than range_start +\set ON_ERROR_STOP 1 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', NULL::timestamptz, NULL); + hypertable_update_range_for_osm +--------------------------------- + f +(1 row) + +-- ordered append still not possible because range is invalid and overlap flag set +EXPLAIN SELECT * FROM test_chunkapp ORDER BY 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Merge Append (cost=100.33..352.47 rows=6355 width=12) + Sort Key: _hyper_10_18_chunk."time" + -> Index Scan Backward using _hyper_10_18_chunk_test_chunkapp_time_idx on _hyper_10_18_chunk (cost=0.15..42.75 rows=2040 width=12) + -> Index Scan Backward using _hyper_10_19_chunk_test_chunkapp_time_idx on _hyper_10_19_chunk (cost=0.15..42.75 rows=2040 width=12) + -> Foreign Scan on test_chunkapp_fdw_child (cost=100.00..184.80 rows=2275 width=12) +(5 rows) + +SELECT * FROM test_chunkapp ORDER BY 1; + time | a +------------------------------+--- + Wed Jan 01 01:00:00 2020 PST | 1 + Thu Jan 02 01:00:00 2020 PST | 2 + Fri Jan 03 02:00:00 2020 PST | 3 +(3 rows) + +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + chunk_id | table_name | status | osm_chunk | dimension_slice_id | range_start | range_end +----------+-------------------------+--------+-----------+--------------------+---------------------+--------------------- + 18 | _hyper_10_18_chunk | 0 | f | 18 | 1577836800000000 | 1577923200000000 + 19 | _hyper_10_19_chunk | 0 | f | 19 | 1577923200000000 | 1578009600000000 + 20 | test_chunkapp_fdw_child | 0 | t | 20 | 9223372036854775806 | 9223372036854775807 +(3 rows) + +-- now set empty to true, should ordered append +\c postgres_fdw_db :ROLE_4; +DELETE FROM test_chunkapp_fdw; +\c :TEST_DBNAME :ROLE_4; +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', NULL::timestamptz, NULL, empty => true); + hypertable_update_range_for_osm +--------------------------------- + f +(1 row) + +EXPLAIN SELECT * FROM test_chunkapp ORDER BY 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (ChunkAppend) on test_chunkapp (cost=0.15..270.31 rows=6355 width=12) + Order: test_chunkapp."time" + -> Index Scan Backward using _hyper_10_18_chunk_test_chunkapp_time_idx on _hyper_10_18_chunk (cost=0.15..42.75 rows=2040 width=12) + -> Index Scan Backward using _hyper_10_19_chunk_test_chunkapp_time_idx on _hyper_10_19_chunk (cost=0.15..42.75 rows=2040 width=12) + -> Foreign Scan on test_chunkapp_fdw_child (cost=100.00..184.80 rows=2275 width=12) +(5 rows) + +SELECT * FROM test_chunkapp ORDER BY 1; + time | a +------------------------------+--- + Wed Jan 01 01:00:00 2020 PST | 1 + Thu Jan 02 01:00:00 2020 PST | 2 +(2 rows) + -- clean up databases created \c :TEST_DBNAME :ROLE_SUPERUSER DROP DATABASE postgres_fdw_db; diff --git a/tsl/test/shared/expected/extension.out b/tsl/test/shared/expected/extension.out index dff45519ccd..4a0bc5ae67e 100644 --- a/tsl/test/shared/expected/extension.out +++ b/tsl/test/shared/expected/extension.out @@ -92,6 +92,7 @@ ORDER BY pronamespace::regnamespace::text COLLATE "C", p.oid::regprocedure::text _timescaledb_functions.hypertable_invalidation_log_delete(integer) _timescaledb_functions.hypertable_local_size(name,name) _timescaledb_functions.hypertable_remote_size(name,name) + _timescaledb_functions.hypertable_update_range_for_osm(regclass,anyelement,anyelement,boolean) _timescaledb_functions.indexes_local_size(name,name) _timescaledb_functions.indexes_remote_size(name,name,name) _timescaledb_functions.insert_blocker() diff --git a/tsl/test/sql/chunk_utils_internal.sql b/tsl/test/sql/chunk_utils_internal.sql index ef17722a950..eba4e398c7c 100644 --- a/tsl/test/sql/chunk_utils_internal.sql +++ b/tsl/test/sql/chunk_utils_internal.sql @@ -325,6 +325,11 @@ INSERT INTO ht_try VALUES ('2022-05-05 01:00', 222, 222); SELECT * FROM child_fdw_table; +-- error should be thrown as the hypertable does not yet have an associated tiered chunk +\set ON_ERROR_STOP 0 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try','2020-01-01 01:00'::timestamptz, '2020-01-01 03:00'); +\set ON_ERROR_STOP 1 + SELECT _timescaledb_functions.attach_osm_table_chunk('ht_try', 'child_fdw_table'); -- OSM chunk is not visible in chunks view @@ -355,6 +360,35 @@ SELECT * from ht_try WHERE timec > '2000-01-01 01:00' and timec < '2022-01-01 0 SELECT * from ht_try WHERE timec > '2020-01-01 01:00' ORDER BY 1; +-- test ordered append +BEGIN; +-- before updating the ranges +EXPLAIN SELECT * FROM ht_try ORDER BY 1; +-- range before update +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.table_name = 'child_fdw_table' AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try', '2020-01-01 01:00'::timestamptz, '2020-01-02'); +SELECT id, schema_name, table_name, status FROM _timescaledb_catalog.hypertable WHERE table_name = 'ht_try'; +-- verify range was updated +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.table_name = 'child_fdw_table' AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; +-- should be ordered append now +EXPLAIN SELECT * FROM ht_try ORDER BY 1; +SELECT * FROM ht_try ORDER BY 1; +-- test overlapping range - should not be ordered append +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try', '2022-05-05 01:00'::timestamptz, '2022-05-06'); +EXPLAIN SELECT * from ht_try ORDER BY 1; +SELECT * from ht_try ORDER BY 1; +ROLLBACK; + +\set ON_ERROR_STOP 0 +-- test that error is produced +SELECT _timescaledb_functions.hypertable_update_range_for_osm('ht_try', '2020-01-02 01:00'::timestamptz, '2020-01-02 00:00'); +\set ON_ERROR_STOP 1 + --TEST GUC variable to enable/disable OSM chunk SET timescaledb.enable_tiered_reads=false; EXPLAIN (COSTS OFF) SELECT * from ht_try; @@ -555,6 +589,75 @@ CREATE INDEX hyper_constr_mid_idx ON hyper_constr(mid, time) WITH (timescaledb.t SELECT indexname, tablename FROM pg_indexes WHERE indexname = 'hyper_constr_mid_idx'; DROP INDEX hyper_constr_mid_idx; +-- test that correct slice is found and updated for table with multiple chunk constraints +CREATE TABLE test_multicon(time timestamptz not null unique, a int); +SELECT hypertable_id as htid FROM create_hypertable('test_multicon', 'time', chunk_time_interval => interval '1 day') \gset +insert into test_multicon values ('2020-01-02 01:00'::timestamptz, 1); +SELECT * FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc WHERE c.hypertable_id = :htid +AND c.id = cc.chunk_id; +\c :TEST_DBNAME :ROLE_SUPERUSER ; +UPDATE _timescaledb_catalog.chunk SET osm_chunk = true WHERE hypertable_id = :htid; +\c :TEST_DBNAME :ROLE_4; +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_multicon', '2020-01-02 01:00'::timestamptz, '2020-01-04 01:00'); +-- view udpated range +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; +-- check that range was reset to default - infinity +\set ON_ERROR_STOP 0 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_multicon', NULL, '2020-01-04 01:00'::timestamptz); +\set ON_ERROR_STOP 1 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_multicon', NULL::timestamptz, NULL); +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; + +-- test further with ordered append +\c postgres_fdw_db :ROLE_4; +CREATE TABLE test_chunkapp_fdw (time timestamptz NOT NULL, a int); +INSERT INTO test_chunkapp_fdw (time, a) VALUES ('2020-01-03 02:00'::timestamptz, 3); + +\c :TEST_DBNAME :ROLE_4 +CREATE TABLE test_chunkapp(time timestamptz NOT NULL, a int); +SELECT hypertable_id as htid FROM create_hypertable('test_chunkapp', 'time', chunk_time_interval => interval '1day') \gset +INSERT INTO test_chunkapp (time, a) VALUES ('2020-01-01 01:00'::timestamptz, 1), ('2020-01-02 01:00'::timestamptz, 2); + +CREATE FOREIGN TABLE test_chunkapp_fdw_child(time timestamptz NOT NULL, a int) SERVER s3_server OPTIONS (schema_name 'public', table_name 'test_chunkapp_fdw');; +SELECT _timescaledb_functions.attach_osm_table_chunk('test_chunkapp','test_chunkapp_fdw_child'); +-- view range before update +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; +-- update range +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', '2020-01-02 01:00'::timestamptz, '2020-01-04 01:00'); +-- view udpated range +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; +-- ordered append should not be possible as ranges overlapped +EXPLAIN SELECT * FROM test_chunkapp ORDER BY 1; +SELECT * FROM test_chunkapp ORDER BY 1; + +-- check that range is reset to default - infinity +\set ON_ERROR_STOP 0 +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', NULL, '2020-01-04 01:00'::timestamptz); +\set ON_ERROR_STOP 1 + +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', NULL::timestamptz, NULL); +-- ordered append still not possible because range is invalid and overlap flag set +EXPLAIN SELECT * FROM test_chunkapp ORDER BY 1; +SELECT * FROM test_chunkapp ORDER BY 1; +SELECT cc.chunk_id, c.table_name, c.status, c.osm_chunk, cc.dimension_slice_id, ds.range_start, ds.range_end +FROM _timescaledb_catalog.chunk c, _timescaledb_catalog.chunk_constraint cc, _timescaledb_catalog.dimension_slice ds +WHERE c.hypertable_id = :htid AND cc.chunk_id = c.id AND ds.id = cc.dimension_slice_id; +-- now set empty to true, should ordered append +\c postgres_fdw_db :ROLE_4; +DELETE FROM test_chunkapp_fdw; +\c :TEST_DBNAME :ROLE_4; +SELECT _timescaledb_functions.hypertable_update_range_for_osm('test_chunkapp', NULL::timestamptz, NULL, empty => true); +EXPLAIN SELECT * FROM test_chunkapp ORDER BY 1; +SELECT * FROM test_chunkapp ORDER BY 1; + -- clean up databases created \c :TEST_DBNAME :ROLE_SUPERUSER DROP DATABASE postgres_fdw_db;