-- Valid chunk sizing function for testing CREATE OR REPLACE FUNCTION calculate_chunk_interval( dimension_id INTEGER, dimension_coord BIGINT, chunk_target_size BIGINT ) RETURNS BIGINT LANGUAGE PLPGSQL AS $BODY$ DECLARE BEGIN RETURN -1; END $BODY$; -- Chunk sizing function with bad signature CREATE OR REPLACE FUNCTION bad_calculate_chunk_interval( dimension_id INTEGER ) RETURNS BIGINT LANGUAGE PLPGSQL AS $BODY$ DECLARE BEGIN RETURN -1; END $BODY$; -- Set a fixed effective memory cache size to make tests determinstic -- (independent of available machine memory) SELECT * FROM test.set_effective_memory_cache_size('2GB'); CREATE TABLE test_adaptive(time timestamptz, temp float, location int); \set ON_ERROR_STOP 0 -- Bad signature of sizing func should fail SELECT create_hypertable('test_adaptive', 'time', chunk_target_size => '1MB', chunk_sizing_func => 'bad_calculate_chunk_interval'); \set ON_ERROR_STOP 1 -- Setting sizing func with correct signature should work SELECT create_hypertable('test_adaptive', 'time', chunk_target_size => '1MB', chunk_sizing_func => 'calculate_chunk_interval'); DROP TABLE test_adaptive; CREATE TABLE test_adaptive(time timestamptz, temp float, location int); -- Size but no explicit func should use default func SELECT create_hypertable('test_adaptive', 'time', chunk_target_size => '1MB', create_default_indexes => true); SELECT table_name, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size FROM _timescaledb_catalog.hypertable; -- Change the target size SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', '2MB'); SELECT table_name, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size FROM _timescaledb_catalog.hypertable; \set ON_ERROR_STOP 0 -- Setting NULL func should fail SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', '1MB', NULL); \set ON_ERROR_STOP 1 -- Setting NULL size disables adaptive chunking SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', NULL); SELECT table_name, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size FROM _timescaledb_catalog.hypertable; SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', '1MB'); -- Setting size to 'off' should also disable SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', 'off'); SELECT table_name, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size FROM _timescaledb_catalog.hypertable; -- Setting 0 size should do an estimate. SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', '0MB'); SELECT table_name, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size FROM _timescaledb_catalog.hypertable; SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', '1MB'); -- Setting size to 'estimate' should also estimate size SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', 'estimate'); SELECT table_name, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size FROM _timescaledb_catalog.hypertable; -- Use a lower memory setting to test that the calculated chunk_target_size is reduced SELECT * FROM test.set_effective_memory_cache_size('512MB'); SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', 'estimate'); SELECT table_name, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size FROM _timescaledb_catalog.hypertable; -- Reset memory settings SELECT * FROM test.set_effective_memory_cache_size('2GB'); -- Set a reasonable test value SELECT * FROM set_adaptive_chunk_sizing('test_adaptive', '1MB'); -- Show the interval length before and after adaptation SELECT id, hypertable_id, interval_length FROM _timescaledb_catalog.dimension; -- Generate data to create chunks. We use the hash of the time value -- to get determinstic location IDs so that we always spread these -- values the same way across space partitions INSERT INTO test_adaptive SELECT time, random() * 35, _timescaledb_internal.get_partition_hash(time) FROM generate_series('2017-03-07T18:18:03+00'::timestamptz - interval '175 days', '2017-03-07T18:18:03+00'::timestamptz, '2 minutes') as time; SELECT * FROM chunk_relation_size('test_adaptive'); -- Do same thing without an index on the time column. This affects -- both the calculation of fill-factor of the chunk and its size CREATE TABLE test_adaptive_no_index(time timestamptz, temp float, location int); -- Size but no explicit func should use default func SELECT create_hypertable('test_adaptive_no_index', 'time', chunk_target_size => '1MB', create_default_indexes => false); SELECT id, hypertable_id, interval_length FROM _timescaledb_catalog.dimension; INSERT INTO test_adaptive_no_index SELECT time, random() * 35, _timescaledb_internal.get_partition_hash(time) FROM generate_series('2017-03-07T18:18:03+00'::timestamptz - interval '175 days', '2017-03-07T18:18:03+00'::timestamptz, '2 minutes') as time; SELECT * FROM chunk_relation_size('test_adaptive_no_index'); -- Test with space partitioning. This might affect the estimation -- since there are more chunks in the same time interval and space -- chunks might be unevenly filled. CREATE TABLE test_adaptive_space(time timestamptz, temp float, location int); SELECT create_hypertable('test_adaptive_space', 'time', 'location', 2, chunk_target_size => '1MB', create_default_indexes => true); SELECT id, hypertable_id, interval_length FROM _timescaledb_catalog.dimension; INSERT INTO test_adaptive_space SELECT time, random() * 35, _timescaledb_internal.get_partition_hash(time) FROM generate_series('2017-03-07T18:18:03+00'::timestamptz - interval '175 days', '2017-03-07T18:18:03+00'::timestamptz, '2 minutes') as time; SELECT * FROM chunk_relation_size('test_adaptive_space'); SELECT id, hypertable_id, interval_length FROM _timescaledb_catalog.dimension;